From cb194df595086fc414e0dfdd09fc7a4b39e78163 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 23 May 2024 04:45:39 -0400 Subject: [PATCH 001/323] Docs: Fixed a typo. --- docs/changelog_v3.3.x.md | 3 +++ docs/prison_changelog_v3.3.0-alpha.18.md | 12 ++++++++++++ .../src/main/resources/lang/mines/de_DE.properties | 2 +- .../src/main/resources/lang/mines/en_US.properties | 2 +- .../src/main/resources/lang/mines/es_ES.properties | 2 +- .../src/main/resources/lang/mines/hu_HU.properties | 2 +- .../src/main/resources/lang/mines/it_IT.properties | 2 +- .../src/main/resources/lang/mines/nl_BE.properties | 2 +- .../src/main/resources/lang/mines/nl_NL.properties | 2 +- .../src/main/resources/lang/mines/ro_RO.properties | 2 +- .../src/main/resources/lang/mines/zh_TW.properties | 2 +- 11 files changed, 24 insertions(+), 9 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 060a66256..96aa83193 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.18a 2024-05-21 +* **Docs: Fixed a typo.** + + **v3.3.0-alpha.18a 2024-05-21** Releasing this alpha.18a because the fix of the of the new player bug was crippling servers. diff --git a/docs/prison_changelog_v3.3.0-alpha.18.md b/docs/prison_changelog_v3.3.0-alpha.18.md index 03c8b4480..b00927a39 100644 --- a/docs/prison_changelog_v3.3.0-alpha.18.md +++ b/docs/prison_changelog_v3.3.0-alpha.18.md @@ -15,6 +15,18 @@ These build logs represent the work that has been going on within prison. # 3.3.0-alpha.18 2024-05-20 + +Prison 3.3.0-alpha.18a 2024-05-21 + +Bug fix: There was a bug that surfaced that was being triggered by new player joins to the prison server. +The symptom was the spamming of new player join messages. +This was actually happening only if there were rank commands that would be ran for the initial rank assignment if it used rank related placeholder. The resolution of the placeholders were triggering another new player cycle. +This was a classic chicken or the egg situation. +It is unknown when this problem was first "setup", but it's only recently that it's been reported. It may have been there in the code for a few years, so not sure how many times this was encountered without being reported. + + + + **Prison-3.3.0-alpha.18.jar** This version of prison works with Spigot v1.20.6 and Paper v1.20.6. 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 502cddbd9..fd9b8aa12 100644 --- a/prison-core/src/main/resources/lang/mines/de_DE.properties +++ b/prison-core/src/main/resources/lang/mines/de_DE.properties @@ -105,4 +105,4 @@ mines_mtp__no_target_mine_found=No target mine found. &3Resubmit teleport reques mines_mtp__player_must_be_in_game=You can only teleport players that are online and in the game. mines_mtp__player_must_be_in_game=&3Specified player is not in the game so they cannot be teleported. mines_mtp__cannot_use_virtual_mines=&cInvalid option. This mine is a virtual mine&7. Use &a/mines set area &7to enable the mine. -mines_mtp__teleport_failed=&3Telport failed. Are you sure you're a Player? +mines_mtp__teleport_failed=&3Teleport failed. Are you sure you're a Player? 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 b21d897fe..325817eea 100644 --- a/prison-core/src/main/resources/lang/mines/en_US.properties +++ b/prison-core/src/main/resources/lang/mines/en_US.properties @@ -106,4 +106,4 @@ mines_mtp__no_target_mine_found=No target mine found. &3Resubmit teleport reques mines_mtp__player_must_be_in_game=You can only teleport players that are online and in the game. mines_mtp__player_must_be_in_game=&3Specified player is not in the game so they cannot be teleported. mines_mtp__cannot_use_virtual_mines=&cInvalid option. This mine is a virtual mine&7. Use &a/mines set area &7to enable the mine. -mines_mtp__teleport_failed=&3Telport failed. Are you sure you're a Player? +mines_mtp__teleport_failed=&3Teleport failed. Are you sure you're a Player? 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 e2baf94f9..cc91e67e4 100644 --- a/prison-core/src/main/resources/lang/mines/es_ES.properties +++ b/prison-core/src/main/resources/lang/mines/es_ES.properties @@ -105,4 +105,4 @@ mines_mtp__no_target_mine_found=No target mine found. &3Resubmit teleport reques mines_mtp__player_must_be_in_game=You can only teleport players that are online and in the game. mines_mtp__player_must_be_in_game=&3Specified player is not in the game so they cannot be teleported. mines_mtp__cannot_use_virtual_mines=&cInvalid option. This mine is a virtual mine&7. Use &a/mines set area &7to enable the mine. -mines_mtp__teleport_failed=&3Telport failed. Are you sure you're a Player? +mines_mtp__teleport_failed=&3Teleport failed. Are you sure you're a Player? 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 cd2424220..83167c089 100644 --- a/prison-core/src/main/resources/lang/mines/hu_HU.properties +++ b/prison-core/src/main/resources/lang/mines/hu_HU.properties @@ -105,4 +105,4 @@ mines_mtp__no_target_mine_found=No target mine found. &3Resubmit teleport reques mines_mtp__player_must_be_in_game=You can only teleport players that are online and in the game. mines_mtp__player_must_be_in_game=&3Specified player is not in the game so they cannot be teleported. mines_mtp__cannot_use_virtual_mines=&cInvalid option. This mine is a virtual mine&7. Use &a/mines set area &7to enable the mine. -mines_mtp__teleport_failed=&3Telport failed. Are you sure you're a Player? +mines_mtp__teleport_failed=&3Teleport failed. Are you sure you're a Player? 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 2c5b126ff..50773dfc3 100644 --- a/prison-core/src/main/resources/lang/mines/it_IT.properties +++ b/prison-core/src/main/resources/lang/mines/it_IT.properties @@ -105,4 +105,4 @@ mines_mtp__no_target_mine_found=No target mine found. &3Resubmit teleport reques mines_mtp__player_must_be_in_game=You can only teleport players that are online and in the game. mines_mtp__player_must_be_in_game=&3Specified player is not in the game so they cannot be teleported. mines_mtp__cannot_use_virtual_mines=&cInvalid option. This mine is a virtual mine&7. Use &a/mines set area &7to enable the mine. -mines_mtp__teleport_failed=&3Telport failed. Are you sure you're a Player? +mines_mtp__teleport_failed=&3Teleport failed. Are you sure you're a Player? 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 41c35aa61..7762b0988 100644 --- a/prison-core/src/main/resources/lang/mines/nl_BE.properties +++ b/prison-core/src/main/resources/lang/mines/nl_BE.properties @@ -103,4 +103,4 @@ mines_mtp__no_target_mine_found=No target mine found. &3Resubmit teleport reques mines_mtp__player_must_be_in_game=You can only teleport players that are online and in the game. mines_mtp__player_must_be_in_game=&3Specified player is not in the game so they cannot be teleported. mines_mtp__cannot_use_virtual_mines=&cInvalid option. This mine is a virtual mine&7. Use &a/mines set area &7to enable the mine. -mines_mtp__teleport_failed=&3Telport failed. Are you sure you're a Player? +mines_mtp__teleport_failed=&3Teleport failed. Are you sure you're a Player? 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 b93443167..6d980bef4 100644 --- a/prison-core/src/main/resources/lang/mines/nl_NL.properties +++ b/prison-core/src/main/resources/lang/mines/nl_NL.properties @@ -103,4 +103,4 @@ mines_mtp__no_target_mine_found=No target mine found. &3Resubmit teleport reques mines_mtp__player_must_be_in_game=You can only teleport players that are online and in the game. mines_mtp__player_must_be_in_game=&3Specified player is not in the game so they cannot be teleported. mines_mtp__cannot_use_virtual_mines=&cInvalid option. This mine is a virtual mine&7. Use &a/mines set area &7to enable the mine. -mines_mtp__teleport_failed=&3Telport failed. Are you sure you're a Player? +mines_mtp__teleport_failed=&3Teleport failed. Are you sure you're a Player? 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 cfb6d17c9..fe42318c2 100644 --- a/prison-core/src/main/resources/lang/mines/ro_RO.properties +++ b/prison-core/src/main/resources/lang/mines/ro_RO.properties @@ -106,4 +106,4 @@ mines_mtp__no_target_mine_found=No target mine found. &3Resubmit teleport reques mines_mtp__player_must_be_in_game=You can only teleport players that are online and in the game. mines_mtp__player_must_be_in_game=&3Specified player is not in the game so they cannot be teleported. mines_mtp__cannot_use_virtual_mines=&cInvalid option. This mine is a virtual mine&7. Use &a/mines set area &7to enable the mine. -mines_mtp__teleport_failed=&3Telport failed. Are you sure you're a Player? +mines_mtp__teleport_failed=&3Teleport failed. Are you sure you're a Player? 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 78a6e3e5d..7de3182b6 100644 --- a/prison-core/src/main/resources/lang/mines/zh_TW.properties +++ b/prison-core/src/main/resources/lang/mines/zh_TW.properties @@ -106,4 +106,4 @@ mines_mtp__no_target_mine_found=No target mine found. &3Resubmit teleport reques mines_mtp__player_must_be_in_game=You can only teleport players that are online and in the game. mines_mtp__player_must_be_in_game=&3Specified player is not in the game so they cannot be teleported. mines_mtp__cannot_use_virtual_mines=&cInvalid option. This mine is a virtual mine&7. Use &a/mines set area &7to enable the mine. -mines_mtp__teleport_failed=&3Telport failed. Are you sure you're a Player? +mines_mtp__teleport_failed=&3Teleport failed. Are you sure you're a Player? From c5d2275bbf61a66ed045507949eaed73105afd35 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 26 May 2024 19:09:13 -0400 Subject: [PATCH 002/323] Player file name update: The file names used for the rank players and the player cache are being updated. These files have the player's name as part of them, but the big change is that the new format now is supporting bedrock players. The bedrock player UUIDs are all zeros at the beginning of the UUID, so it was leading to possible issues when there were more than one bedrock player due to the cache trying to load the wrong file. The transition to the new file format will not be forced yet. The old format will continue to be used until a major release is made in the future. The new format can be enabled through the config.yml file. There is also a new task and command under '/prison support updates playerFilenameUpdate`. The prison system is now able to track and store different events and settings in a new 'pluigins/Prison/backups/prison-system-settings.json' file. This will track the usage of the player name update. --- docs/changelog_v3.3.x.md | 10 +- .../prison/backups/PrisonSystemSettings.java | 111 ++++++ .../mcprison/prison/cache/CoreCacheFiles.java | 321 +++++++++++------- .../mcprison/prison/cache/PlayerCache.java | 55 +-- .../cache/PlayerCacheCheckTimersTask.java | 7 +- .../tech/mcprison/prison/file/JsonFileIO.java | 150 +++++++- .../prison/ranks/data/RankPlayer.java | 80 +++-- .../java/tech/mcprison/prison/TestPlayer.java | 2 +- .../prison/ranks/commands/RanksCommands.java | 63 ++++ .../prison/ranks/data/TopNPlayers.java | 4 +- .../prison/ranks/managers/PlayerManager.java | 21 +- .../PlayerNewFileNameCheckAsyncTask.java | 221 ++++++++++++ .../spigot/game/SpigotOfflinePlayer.java | 2 +- .../prison/spigot/game/SpigotPlayer.java | 2 +- prison-spigot/src/main/resources/config.yml | 27 ++ 15 files changed, 882 insertions(+), 194 deletions(-) create mode 100644 prison-core/src/main/java/tech/mcprison/prison/backups/PrisonSystemSettings.java create mode 100644 prison-ranks/src/main/java/tech/mcprison/prison/ranks/tasks/PlayerNewFileNameCheckAsyncTask.java diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 96aa83193..5d1eacbd6 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,15 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.18a 2024-05-21 +# 3.3.0-alpha.18a 2024-05-26 + + +* **Player file name update: The file names used for the rank players and the player cache are being updated.** +These files have the player's name as part of them, but the big change is that the new format now is supporting bedrock players. +The bedrock player UUIDs are all zeros at the beginning of the UUID, so it was leading to possible issues when there were more than one bedrock player due to the cache trying to load the wrong file. +The transition to the new file format will not be forced yet. The old format will continue to be used until a major release is made in the future. +The new format can be enabled through the config.yml file. There is also a new task and command under '/prison support updates playerFilenameUpdate`. +The prison system is now able to track and store different events and settings in a new 'pluigins/Prison/backups/prison-system-settings.json' file. This will track the usage of the player name update. * **Docs: Fixed a typo.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/backups/PrisonSystemSettings.java b/prison-core/src/main/java/tech/mcprison/prison/backups/PrisonSystemSettings.java new file mode 100644 index 000000000..ace72d8cc --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/backups/PrisonSystemSettings.java @@ -0,0 +1,111 @@ +package tech.mcprison.prison.backups; + +import java.io.File; +import java.util.TreeMap; + +import tech.mcprison.prison.file.FileIOData; +import tech.mcprison.prison.file.JsonFileIO; + +public class PrisonSystemSettings + implements FileIOData { + public static final String PRISON_SYSTEM_FILENAME = "prison-system-settings.json"; + + private static PrisonSystemSettings instance = null; + + private TreeMap> settings; + + public enum SystemSettingKey { + PlayerFileNameUpdate + + ; + } + + private PrisonSystemSettings() { + super(); + + this.settings = new TreeMap<>(); + } + + + public static PrisonSystemSettings getInstance() { + if ( instance == null ) { + synchronized ( PrisonSystemSettings.class ) { + if ( instance == null ) { + + instance = new PrisonSystemSettings(); + } + } + } + + return instance; + } + + /** + *

This function should be used to add new root nodes to ensure + * that they are of type SystemSettingKey values. This functional + * also adds a TreeMap as it's value pair so it's ready to + * take on values. + *

+ * + * @param rootKey + */ + public void addRootSetting( SystemSettingKey rootKey ) { + if ( !getSettings().containsKey( rootKey.name()) ) { + + getSettings().put( rootKey.name(), new TreeMap<>() ); + } + } + + public TreeMap getRootSetting( SystemSettingKey rootkey ) { + TreeMap results = null; + + if ( getSettings() == null ) { + load(); + } + + // Try to add the rootKey just in case it does not exist: + addRootSetting(rootkey); + + results = getSettings().get(rootkey.name()); + + return results; + } + + private TreeMap> getSettings() { + return settings; + } + private void setSettings(TreeMap> settings) { + this.settings = settings; + } + + + public void save() { + File file = getPrisonSystemSettingsFile(); + + JsonFileIO jfIo = new JsonFileIO(); + + jfIo.saveJsonFile(file, this); + } + + public void load() { + File file = getPrisonSystemSettingsFile(); + + JsonFileIO jfIo = new JsonFileIO(); + + PrisonSystemSettings settings = (PrisonSystemSettings) jfIo.readJsonFile(file, this); + + setSettings( settings.getSettings() ); + } + + public void unload() { + setSettings( null ); + } + + public File getPrisonSystemSettingsFile() { + PrisonBackups pb = new PrisonBackups(); + File path = pb.getBackupDirectory(); + + return new File( path, PRISON_SYSTEM_FILENAME ); + } + + } diff --git a/prison-core/src/main/java/tech/mcprison/prison/cache/CoreCacheFiles.java b/prison-core/src/main/java/tech/mcprison/prison/cache/CoreCacheFiles.java index c8fd65cb1..b5d586b23 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/cache/CoreCacheFiles.java +++ b/prison-core/src/main/java/tech/mcprison/prison/cache/CoreCacheFiles.java @@ -1,13 +1,11 @@ package tech.mcprison.prison.cache; import java.io.File; -import java.io.FileFilter; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; -import java.util.TreeMap; import com.google.gson.Gson; import com.google.gson.GsonBuilder; @@ -15,6 +13,7 @@ import com.google.gson.JsonSyntaxException; import tech.mcprison.prison.Prison; +import tech.mcprison.prison.file.JsonFileIO; import tech.mcprison.prison.internal.Player; import tech.mcprison.prison.output.Output; @@ -24,13 +23,14 @@ public abstract class CoreCacheFiles { public static final String FILE_PREFIX_BACKUP = ".backup_"; public static final String FILE_SUFFIX_BACKUP = ".bu"; public static final String FILE_SUFFIX_TEMP = ".temp"; + public static final String FILE_SUFFIX_TXT = ".txt"; public static final String FILE_TIMESTAMP_FORMAT = "_yyyy-MM-dd_HH-mm-ss"; private final String cachePath; private File cacheDirectory = null; private Gson gson = null; - private TreeMap playerFiles; +// private TreeMap playerFiles; public CoreCacheFiles( String cachePath ) { @@ -84,7 +84,7 @@ protected File createTempFile(File file) { *

* */ - protected CoreCacheData fromJsonFile(File inputFile, Class classOfT ) { + protected CoreCacheData fromJsonFile(File inputFile, Class classOfT ) { CoreCacheData results = null; if ( inputFile.exists() ) { @@ -151,24 +151,31 @@ protected CoreCacheData fromJsonFile(File inputFile, Class classOfT ) { CoreCacheData results = null; + String cacheFilename = JsonFileIO.filenameCache(player); +// String playerId = player.getUUID().toString(); + + File playerCacheFile = getPlayerFile( cacheFilename ); + // // This is the "target" file name for the player, based upon their // // current name. The saved cache file may not be named exactly the same, // // and if it's not, then their existing cache file will be renamed // // within the function getCachedFileMatch() - String playerFileName = getPlayerFileName( player ); +// String playerFileName = getPlayerFileName( player ); + +// String uuidPrefix = JsonFileIO.getFileNameUUIDFragment(playerFileName) - File playerFile = getCachedFileMatch( playerFileName ); +// File playerFile = getCachedFileMatch( playerId, cacheFilename ); - if ( playerFile.exists() ) { + if ( playerCacheFile.exists() ) { - results = fromJsonFile( playerFile, classOfT ); + results = fromJsonFile( playerCacheFile, classOfT ); } // New player and file does not exist so create it. if ( results == null ) { - results = new PlayerCachePlayerData( player, playerFile ); + results = new PlayerCachePlayerData( player, playerCacheFile ); // Then save it: toJsonFile( results ); @@ -215,9 +222,9 @@ public void toJsonFile(CoreCacheData cacheData) { File playerFile = cacheData.getPlayerFile(); File outTemp = createTempFile( playerFile ); - if ( !getPlayerFiles().containsKey( playerFile.getName() )) { - getPlayerFiles().put( playerFile.getName(), playerFile ); - } +// if ( !getPlayerFiles().containsKey( playerFile.getName() )) { +// getPlayerFiles().put( playerFile.getName(), playerFile ); +// } boolean success = false; @@ -276,35 +283,40 @@ protected File getPlayerFile(String playerFileName) { return new File( getPlayerFilePath(), playerFileName ); } - protected TreeMap getPlayerFiles() { - // load the player's files: - if ( playerFiles == null ) { - - playerFiles = new TreeMap<>(); - - FileFilter fileFilter = (file) -> { - - String fname = file.getName(); - boolean isTemp = fname.startsWith( FILE_PREFIX_BACKUP ) || - fname.endsWith( FILE_SUFFIX_BACKUP ) || - fname.endsWith( FILE_SUFFIX_TEMP ); - - return !file.isDirectory() && !isTemp && - fname.endsWith( FILE_SUFFIX_JSON ); - }; - - - File[] files = getPlayerFilePath().listFiles( fileFilter ); - for ( File f : files ) - { - String fileNamePrefix = getFileNamePrefix( f.getName() ); - getPlayerFiles().put( fileNamePrefix, f ); - } - - } - - return playerFiles; - } +// protected TreeMap getPlayerFiles() { +// // load the player's files: +// +// TreeMap playerFiles = new TreeMap<>(); +// +// FileFilter fileFilter = (file) -> { +// +// String fname = file.getName(); +// boolean isTemp = fname.startsWith( FILE_PREFIX_BACKUP ) || +// fname.endsWith( FILE_SUFFIX_BACKUP ) || +// fname.endsWith( FILE_SUFFIX_TEMP ) || +// fname.endsWith( FILE_SUFFIX_TXT ); +// +// return !file.isDirectory() && !isTemp && +// fname.endsWith( FILE_SUFFIX_JSON ); +// }; +// +// +// File[] files = getPlayerFilePath().listFiles( fileFilter ); +// for ( File f : files ) +// { +// String fName = f.getName(); +// +// String fileNamePrefix = JsonFileIO.getFileNameUUIDFragment( fName ); +// +// if ( fileNamePrefix != null && fileNamePrefix.length() > 0 ) { +// +// playerFiles.put( fileNamePrefix, f ); +// } +// } +// +// +// return playerFiles; +// } @@ -325,100 +337,145 @@ public File getPlayerFilePath() { return cacheDirectory; } - /** - *

This function returns the file name which is constructed by - * using the player's UUID and their name. The player's name is not - * used in the selection of a player's file, only the UUID prefix. - *

- * - *

The UUID prefix is based upon the HEX representation of the - * the UUID, and includes the first 13 characters which includes one - * hyphen. Since the minecraft UUID is based upon random numbers - * (type 4 UUID), then odds are great that file name prefixes will - * be unique, but they don't have to be. - *

- * - *

Its a high importance that file names can be found based upon - * Player information, hence the UUID prefix. Plus it's very important - * to be able to have the files human readable so admins can find - * specific player files if they need to; hence the player name suffix. - *

- * - * @param player - * @return - */ - private String getPlayerFileName( Player player ) { - String UUIDString = player.getUUID().toString(); - String uuidFragment = getFileNamePrefix( UUIDString ); - - return uuidFragment + "_" + player.getName() + FILE_SUFFIX_JSON; - } +// /** +// *

This function returns the file name which is constructed by +// * using the player's UUID and their name. The player's name is not +// * used in the selection of a player's file, only the UUID prefix. +// *

+// * +// *

The UUID prefix is based upon the HEX representation of the +// * the UUID, and includes the first 13 characters which includes one +// * hyphen. Since the minecraft UUID is based upon random numbers +// * (type 4 UUID), then odds are great that file name prefixes will +// * be unique, but they don't have to be. +// *

+// * +// *

Its a high importance that file names can be found based upon +// * Player information, hence the UUID prefix. Plus it's very important +// * to be able to have the files human readable so admins can find +// * specific player files if they need to; hence the player name suffix. +// *

+// * +// * @param player +// * @return +// */ +// private String getPlayerFileName( Player player ) { +// +// return JsonFileIO.filenameCache( player ); +// +//// String UUIDString = player.getUUID().toString(); +//// String uuidFragment = getFileNamePrefix( UUIDString ); +//// +//// return uuidFragment + "_" + player.getName() + FILE_SUFFIX_JSON; +// } - /** - *

This function returns the first 13 characters of the supplied - * file name, or UUID String. The hyphen is around the 12 or 13th position, - * so it may or may not include it. - *

- * - * @param playerFileName - * @return - */ - String getFileNamePrefix( String UUIDString ) { - return UUIDString.substring( 0, 14 ); - } +// /** +// *

This function returns the first 13 characters of the supplied +// * file name, or UUID String. The hyphen is around the 12 or 13th position, +// * so it may or may not include it. +// *

+// * +// * @param playerFileName +// * @return +// */ +// String getFileNamePrefix( String UUIDString ) { +// return UUIDString.substring( 0, 14 ); +// } - /** - *

Potentially there could be more than one result, but considering if a player - * changes their name, then it should only return only one entry. The reason for - * this, is that the file name should be based upon the player's UUID, which is the - * first 13 characters of the file, and the name itself, which follows, should - * never be part of the "key". - *

- * - * @param playerFile - * @param playerFileName - * @return - */ - private File getCachedFileMatch( String playerFileName ) - { - File results = null; - - String fileNamePrefix = getFileNamePrefix( playerFileName ); - - results = getPlayerFiles().get( fileNamePrefix ); +// /** +// *

This takes a playerId (their UUID) and tries to get their file name from the +// * playerFile collection. If it does not exist, a new file is created for their +// * user. If the saved file name does not match the playerFilename, then it indicates +// * there could have been a player name change, so update the saved file on the file +// * system and update what's stored in the playerFiles. +// *

+// * +// * +// * @param playerFile +// * @param playerFileName +// * @return +// */ +// private File getCachedFileMatch( String playerId, String playerFileName ) +// { +// File results = null; +// +// if ( getPlayerFiles().containsKey( playerId ) ) { +// +// results = getPlayerFiles().get( playerId ); +// } +// else { +// // This is the "target" file name for the player, based upon their +// // current name. The saved cache file may not be named exactly the same, +// // and if it's not, then their existing cache file needs to be +// // renamed. +// results = getPlayerFile( playerFileName ); +// +// // NOTE: because the file was NOT found in the directory, then we can assume +// // this is a new player therefore we won't have an issue with the player's +// // name changing. +// getPlayerFiles().put( playerId, results ); +// } +// +// +// if ( results != null && !results.getName().equalsIgnoreCase(playerFileName) ) { +// // They player's name changed. Update the name of the file and save it: +// +// // File name changed!!! Need to rename the file in the file system, and +// // update what is in the playerFiles map!! +// +// File newFile = getPlayerFile( playerFileName ); +// +// if ( results.exists() ) { +// // rename what's on the file system: +// results.renameTo( newFile ); +// } +// +// // Replace what's in the map: +// getPlayerFiles().put( playerId, newFile ); +// +// results = newFile; +// } +// - if ( results == null ) { - - // This is the "target" file name for the player, based upon their - // current name. The saved cache file may not be named exactly the same, - // and if it's not, then their existing cache file needs to be - // renamed. - results = getPlayerFile( playerFileName ); - - // NOTE: because the file was NOT found in the directory, then we can assume - // this is a new player therefore we won't have an issue with the player's - // name changing. - getPlayerFiles().put( fileNamePrefix, results ); - } - else if ( !playerFileName.equalsIgnoreCase( results.getName() )) { - - // File name changed!!! Need to rename the file in the file system, and - // update what is in the playerFiles map!! - - File newFile = getPlayerFile( playerFileName ); - - if ( results.exists() ) { - // rename what's on the file system: - results.renameTo( newFile ); - } - - // Replace what's in the map: - getPlayerFiles().put( fileNamePrefix, newFile ); - - results = newFile; - } +// String fileNamePrefix = JsonFileIO.getFileNameUUIDFragment( playerFileName ); +//// String fileNamePrefix = getFileNamePrefix( playerFileName ); +// +// if ( fileNamePrefix != null && fileNamePrefix.length() > 0 ) { +// results = getPlayerFiles().get( fileNamePrefix ); +// } +// +// if ( results == null ) { +// +// // This is the "target" file name for the player, based upon their +// // current name. The saved cache file may not be named exactly the same, +// // and if it's not, then their existing cache file needs to be +// // renamed. +// results = getPlayerFile( playerFileName ); +// +// // NOTE: because the file was NOT found in the directory, then we can assume +// // this is a new player therefore we won't have an issue with the player's +// // name changing. +// getPlayerFiles().put( fileNamePrefix, results ); +// } +// else if ( !playerFileName.equalsIgnoreCase( results.getName() )) { +// +// // File name changed!!! Need to rename the file in the file system, and +// // update what is in the playerFiles map!! +// +// File newFile = getPlayerFile( playerFileName ); +// +// if ( results.exists() ) { +// // rename what's on the file system: +// results.renameTo( newFile ); +// } +// +// // Replace what's in the map: +// getPlayerFiles().put( fileNamePrefix, newFile ); +// +// results = newFile; +// } // NavigableMap files = getPlayerFiles().tailMap( fileNamePrefix, true ); // Set keys = files.keySet(); @@ -430,6 +487,6 @@ else if ( !playerFileName.equalsIgnoreCase( results.getName() )) { // results.add( files.get( key ) ); // } - return results; - } +// return results; +// } } 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 0875b92ad..8b0ddad2c 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 @@ -6,6 +6,7 @@ import java.util.Set; import java.util.SortedMap; import java.util.TreeMap; +import java.util.TreeSet; import tech.mcprison.prison.Prison; import tech.mcprison.prison.internal.Player; @@ -132,36 +133,42 @@ private void onDisableInternal() { if ( getPlayers().size() > 0 ) { - Set keys = getPlayers().keySet(); - + Set keys = null; + synchronized ( getPlayers() ) { + keys = new TreeSet<>( getPlayers().keySet() ); + } + + + for ( String key : keys ) { + // Remove the player from the cache and get the playerData: + PlayerCachePlayerData playerData = null; + + synchronized ( getPlayers() ) { + playerData = getPlayers().remove( key ); + } - for ( String key : keys ) { - // Remove the player from the cache and get the playerData: - PlayerCachePlayerData playerData = getPlayers().remove( key ); + if ( playerData != null ) { - if ( playerData != null ) { - - // Note: Since we are logging online time, then all players that are - // in the cache are considered constantly dirty and needs to be - // saved. - - // Since the disable function has been called, we can only assume the - // server is shutting down. We need to save dirty player caches, but - // they must be done in-line so the shutdown process will wait for all - // players to be saved. - - getCacheFiles().toJsonFile( playerData ); + // Note: Since we are logging online time, then all players that are + // in the cache are considered constantly dirty and needs to be + // saved. + + // Since the disable function has been called, we can only assume the + // server is shutting down. We need to save dirty player caches, but + // they must be done in-line so the shutdown process will wait for all + // players to be saved. + + getCacheFiles().toJsonFile( playerData ); + + if ( playerData.getTask() != null ) { - if ( playerData.getTask() != null ) { - - synchronized( getTasks() ) { - - getTasks().remove( playerData.getTask() ); - } + synchronized( getTasks() ) { - PrisonTaskSubmitter.cancelTask( playerData.getTask().getTaskId() ); + getTasks().remove( playerData.getTask() ); } + + PrisonTaskSubmitter.cancelTask( playerData.getTask().getTaskId() ); } } } diff --git a/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheCheckTimersTask.java b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheCheckTimersTask.java index d9dac7c3f..81f418688 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheCheckTimersTask.java +++ b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheCheckTimersTask.java @@ -3,6 +3,7 @@ import java.util.ConcurrentModificationException; import java.util.HashSet; import java.util.Set; +import java.util.TreeSet; /** *

This periodically ran task will go through all cached players and update @@ -65,7 +66,11 @@ private void processCache() { try { - Set keys = pCache.getPlayers().keySet(); + Set keys = null; + + synchronized ( pCache.getPlayers() ) { + keys = new TreeSet<>( pCache.getPlayers().keySet() ); + } for ( String key : keys ) { 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 b2deb33dc..18aa9de47 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 @@ -5,6 +5,7 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; +import tech.mcprison.prison.Prison; import tech.mcprison.prison.error.ErrorManager; import tech.mcprison.prison.internal.Player; import tech.mcprison.prison.modules.ModuleStatus; @@ -51,9 +52,146 @@ public Gson getGsonExposed() .create(); } + /** + *

This function generate a partial user file name. This is based upon + * the UUID-fragment (first and last parts of the player UUID), + * plus the player's name, and the file suffix, which is '.json'. + * This function does not add any prefix such as 'player_' or + * 'cache_'. + *

+ * + * @param player + * @return + */ + private static String getPlayerFileNameNewVersion( Player player ) { + + String uuidFragment = getFileNamePrefixNew( player ); + + return uuidFragment + "_" + player.getName() + FILE_SUFFIX_JSON; + } + /** + *

This generates the fragment UUID that is used within file names. + * This is based upon the first 8 UUID digits, plus the hyphen. Followed + * by the last segment of the UUID, which starts at character 25. + *

+ * + *

This uses the start and end of the UUID because bedrock players + * only have zeros for the first part of the UUID, so the ending must + * be included too. + *

+ * + *

Examples: + *

+ * '22cacd8c-d0ff-4dd7-a8ba-2a6a8b46be92' + * '' + * + * @param player + * @return + */ + private static String getFileNamePrefixNew( Player player ) { + String uuid = player.getUUID().toString(); + return uuid.substring( 0, 9 ) + + uuid.substring( 25 ); + } + /** + *

This function extracts the UUID fragment from player file names. + *

+ * + * @param filename + * @return + */ + public static String getFileNameUUIDFragment( String filename ) { + String uuid = null; + + if ( filename != null && filename.trim().length() > 0 ) { + + String uuidTmp = filename.replace("cache_", "").replace("player_", ""); + + uuid = uuidTmp.indexOf("_") > 0 ? + uuidTmp.substring(0, uuidTmp.indexOf("_")) + : uuidTmp; + } + return uuid; + +// String uuid = player.getUUID().toString(); +// return uuid.substring( 0, 9 ) + +// uuid.substring( 25 ); + } + + /** + *

This is a helper function to ensure that the given file name is + * always generated correctly and consistently. + *

+ * + * @return "player_" plus the least significant bits of the UID + */ + public static String filenamePlayer( Player player ) + { + boolean useNewFormat = Prison.get().getPlatform() + .getConfigBooleanFalse( "prison-ranks.use-friendly-user-file-name" ); + + return useNewFormat ? filenamePlayerNew( player ) : filenamePlayerOld( player ); + } + + public static String filenameCache( Player player ) + { + boolean useNewFormat = Prison.get().getPlatform() + .getConfigBooleanFalse( "prison-ranks.use-friendly-user-file-name" ); + + return useNewFormat ? + filenameCacheNew( player ) : filenameCacheOld( player ); + } + + /** + * Do not use. Use 'filenameCache( player )'. + * + * @param player + * @return + */ + public static String filenameCacheNew( Player player ) { + + return "cache_" + getPlayerFileNameNewVersion( player ); + } + /** + * Do not use. Use 'filenameCache( player )'. + * + * @param player + * @return + */ + public static String filenameCacheOld( Player player ) { + + return getPlayerFileNameShortVersion( player ); + } + /** + * Do not use. Use 'filenamePlayer( player )'. + * + * @param player + * @return + */ + public static String filenamePlayerNew( Player player ) + { + return "player_" + getPlayerFileNameNewVersion( player ); + } + /** + * Do not use. Use 'filenamePlayer( player )'. + * + * @param player + * @return + */ + public static String filenamePlayerOld( Player player ) + { + return "player_" + player.getUUID().getLeastSignificantBits() + FILE_SUFFIX_JSON; + } + + + /** + *

Do not use. This version is not compatible with bedrock players + * because all bedrock UUIDs are just zeros when using this formmat. + * The newer format also includes the trailing + * *

This constructs a player file named based upon the UUID followed * by the player's name. This format is used so it's easier to identify * the correct player. @@ -68,15 +206,20 @@ public Gson getGsonExposed() * * @return */ - public static String getPlayerFileName( Player player ) { + @Deprecated + public static String getPlayerFileNameShortVersion( Player player ) { String UUIDString = player.getUUID().toString(); - String uuidFragment = getFileNamePrefix( UUIDString ); + String uuidFragment = getFileNamePrefixObsolete( UUIDString ); return uuidFragment + "_" + player.getName() + FILE_SUFFIX_JSON; } /** + *

Do not use. This does not support bedrock players because + * the prefix of bedrock UUIDs is all zeros. + *

+ * *

This function returns the first 13 characters of the supplied * file name, or UUID String. The hyphen is around the 12 or 13th position, * so it may or may not include it. @@ -85,7 +228,8 @@ public static String getPlayerFileName( Player player ) { * @param playerFileName * @return */ - private static String getFileNamePrefix( String UUIDString ) { + @Deprecated + private static String getFileNamePrefixObsolete( String UUIDString ) { return UUIDString.substring( 0, 14 ); } 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 230e24cee..dce6835ab 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 @@ -227,26 +227,7 @@ public String toString() { return getName() + " " + getRanks(); } - - /** - *

This constructs a player file named based upon the UUID followed - * by the player's name. This format is used so it's easier to identify - * the correct player. - *

- * - *

The format should be UUID-PlayerName.json. The UUID is a shortened - * format, which should still produce a unique id. The name, when read, - * is based upon the UUID and not the player's name, which may change. - * This format includes the player's name to make it easier to identify - * who's record is whom's. - *

- * - * @return - */ - public String getPlayerFileName() { - - return JsonFileIO.getPlayerFileName( this ); - } + public String getRanks() { @@ -357,6 +338,27 @@ public void setNames( List names ) { // this.blocksMined = blocksMined; // } + + /** + *

This constructs a player file named based upon the UUID followed + * by the player's name. This format is used so it's easier to identify + * the correct player. + *

+ * + *

The format should be UUID-PlayerName.json. The UUID is a shortened + * format, which should still produce a unique id. The name, when read, + * is based upon the UUID and not the player's name, which may change. + * This format includes the player's name to make it easier to identify + * who's record is whom's. + *

+ * + * @return + */ + public String getPlayerFileName() { + + return filenamePlayer(); + } + /** *

This is a helper function to ensure that the given file name is * always generated correctly and consistently. @@ -364,11 +366,45 @@ public void setNames( List names ) { * * @return "player_" plus the least significant bits of the UID */ - public String filename() + public String filenamePlayer() { - return "player_" + uid.getLeastSignificantBits(); + return JsonFileIO.filenamePlayer( this ); + +// boolean useNewFormat = Prison.get().getPlatform() +// .getConfigBooleanFalse( "prison-ranks.use-friendly-user-file-name" ); +// +// return useNewFormat ? filenamePlayerNew() : filenamePlayerOld(); } + public String filenameCache() + { + return JsonFileIO.filenameCache( this ); + +// boolean useNewFormat = Prison.get().getPlatform() +// .getConfigBooleanFalse( "prison-ranks.use-friendly-user-file-name" ); +// +// return useNewFormat ? +// filenameCacheNew() : filenamePlayerOld(); + } + +// public String filenameCacheNew() { +// +// return "cache_" + JsonFileIO.getPlayerFileNameNewVersion( this ); +// } +// public String filenameCacheOld() { +// return JsonFileIO.getPlayerFileNameShortVersion( this ); +// } +// +// public String filenamePlayerNew() +// { +// return "player_" + JsonFileIO.getPlayerFileNameNewVersion( this ); +// } +// +// public String filenamePlayerOld() +// { +// return "player_" + uid.getLeastSignificantBits(); +// } + // /** // *

This function will check to see if the player is on the default rank on diff --git a/prison-core/src/test/java/tech/mcprison/prison/TestPlayer.java b/prison-core/src/test/java/tech/mcprison/prison/TestPlayer.java index 6cf0b48c4..db97bc0d8 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/TestPlayer.java +++ b/prison-core/src/test/java/tech/mcprison/prison/TestPlayer.java @@ -72,7 +72,7 @@ public List getInput() { */ public String getPlayerFileName() { - return JsonFileIO.getPlayerFileName( this ); + return JsonFileIO.filenamePlayer( this ); } @Override public void updateInventory() { 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 7503bccc8..0de2ab81b 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 @@ -50,6 +50,7 @@ import tech.mcprison.prison.ranks.managers.PlayerManager; import tech.mcprison.prison.ranks.managers.RankManager; import tech.mcprison.prison.ranks.managers.RankManager.RanksByLadderOptions; +import tech.mcprison.prison.ranks.tasks.PlayerNewFileNameCheckAsyncTask; import tech.mcprison.prison.util.JumboTextFont; import tech.mcprison.prison.util.Text; @@ -2370,6 +2371,68 @@ public void rankTopN(CommandSender sender, } + + + @Command(identifier = "prison support updates playerFileNameUpdate", + description = "&3This command will run a task that will check both the " + + "Player Rank files and the Player Cache files to see if " + + "they are using an old naming format. If they are, then the " + + "files are renamed to the new format. This command can be " + + "ran multiple times, since nothing will be changed if the " + + "file names have already been converted." + + "{br}" + + "&3Inorder to use the new naming formats, the 'config.yml' must " + + "contain the boolean property " + + "'prison-ranks.use-friendly-user-file-name' with a value of " + + "true. Failure to both set that to a value of true, and " + + "to run this updater may lead to possible player data corruption." + + "" + + "" + + "{br}" + + "&3The new format for player-based file names includes the " + + "player's name, and uses a UUID fragment that is actually " + + "bedrock friendly. The UUID parts that are used, are the " + + "first eight digits of the UUID, plus the last 12. Bedrock " + + "UUIDs can have first 16 to 20 digits being all zeros, which " + + "could result in ambiguous file names where all bedrock players " + + "would have the same prefix. The whole point of only using the " + + "first eight hex digits was that they would have still be all " + + "unique.{br}", + onlyPlayers = false, permissions = "prison.debug" ) + public void supportPlayerFileNameUpdateCmd(CommandSender sender, + @Arg(name = "action", def = "status", + description = "Only shows the PrisonSystemStatus for the " + + "'PlayerFileNameUpdate' and will not try to run the " + + "update. Default: 'status'. [status, run]") String action + ) { + + // Get the PrisonSystemSettings for the PlayerFileNameUpdate and format the results: + List msg = new PlayerNewFileNameCheckAsyncTask().getStatusDetails(); + + boolean useNewFormat = Prison.get().getPlatform() + .getConfigBooleanFalse( "prison-ranks.use-friendly-user-file-name" ); + +// msg.add( "" ); + + sender.sendMessage(msg); + + if ( action != null && action.trim().equalsIgnoreCase("run")) { + + if ( !useNewFormat ) { + Output.get().logInfo( "&cCommand failure: &aBefore the player file names can be " + + "checked, the setting '&cprison-ranks.use-friendly-user-file-name&a' " + + "must be set to '&ctrue&a'. Once enabled, this can not be " + + "reverted because the player files (Player Ranks and Player Caches) " + + "could be corrupted."); + } + else { + long delayTicks = 0; + PlayerNewFileNameCheckAsyncTask.submitTaskSync( delayTicks ); + } + } + + } + private boolean contains( String search, String... values ) { boolean results = false; 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 4c79e3cf6..7543af291 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 @@ -440,7 +440,7 @@ public void refreshAndSort() { TopNPlayersData topN = null; - String key = player.getPlayerFileName(); + String key = player.getUUID().toString(); if ( getTopNMap().containsKey(key) ) { topN = getTopNMap().get(key); @@ -580,7 +580,7 @@ private TopNPlayersData getTopNPlayer(RankPlayer rPlayer) { TopNPlayersData topN = null; - String key = rPlayer.getPlayerFileName(); + String key = rPlayer.getUUID().toString(); if ( getTopNMap().containsKey( key ) ) { diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java index ae6c2301d..f0a42242a 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java @@ -78,7 +78,7 @@ public class PlayerManager private transient Set playerErrors; public PlayerManager(Collection collection) { - super("PlayerMangager"); + super("PlayerManager"); this.collection = collection; @@ -165,30 +165,39 @@ public void loadPlayers() throws IOException { * @throws IOException If the file could not be created or written to. * @see #savePlayer(RankPlayer) To save with the default conventional filename. */ - private void savePlayer(RankPlayer player, String playerFile) throws IOException { + private boolean savePlayer(RankPlayer player, String playerFile) throws IOException { + boolean success = false; if ( !player.isEnableDirty() || player.isEnableDirty() && player.isDirty() ) { collection.save(playerFile, RankPlayerFactory.toDocument( player ) ); player.setDirty( false ); + + success = true; } // RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); // collection.save(playerFile, RankPlayerFactory.toDocument( player ) ); -// collection.insert(playerFile, player.toDocument()); +// collection.insert(playerFile, player.toDocument());y + + return success; } - public void savePlayer(RankPlayer player) { + public boolean savePlayer(RankPlayer player) { + boolean success = false; + try { - this.savePlayer(player, player.filename()); + success = this.savePlayer(player, player.filenamePlayer()); } catch (IOException e) { - String errorMessage = cannotSaveNewPlayerFile( player.getName(), player.filename() ); + String errorMessage = cannotSaveNewPlayerFile( player.getName(), player.filenamePlayer() ); Output.get().logError( errorMessage, e); } + + return success; } /** diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/tasks/PlayerNewFileNameCheckAsyncTask.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/tasks/PlayerNewFileNameCheckAsyncTask.java new file mode 100644 index 000000000..d81235889 --- /dev/null +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/tasks/PlayerNewFileNameCheckAsyncTask.java @@ -0,0 +1,221 @@ +package tech.mcprison.prison.ranks.tasks; + +import java.io.File; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.TreeMap; + +import tech.mcprison.prison.Prison; +import tech.mcprison.prison.backups.PrisonSystemSettings; +import tech.mcprison.prison.backups.PrisonSystemSettings.SystemSettingKey; +import tech.mcprison.prison.file.JsonFileIO; +import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.ranks.PrisonRanks; +import tech.mcprison.prison.ranks.data.RankPlayer; +import tech.mcprison.prison.ranks.managers.PlayerManager; +import tech.mcprison.prison.tasks.PrisonRunnable; +import tech.mcprison.prison.tasks.PrisonTaskSubmitter; + +/** + * This task will run after the server starts up. + * If the 'prison-ranks.use-friendly-user-file-name' + */ +public class PlayerNewFileNameCheckAsyncTask + implements PrisonRunnable { + + public PlayerNewFileNameCheckAsyncTask() { + super(); + } + + public static void submitTaskSync( long delayTicks ) { + + boolean useNewFormat = Prison.get().getPlatform() + .getConfigBooleanFalse( "prison-ranks.use-friendly-user-file-name" ); + + if ( useNewFormat ) { + + Output.get().logInfo( + "&PlayerFileNameCheck Task: &aUsing Friendly User filenames: " + + "&dConversion file check async task submitted." ); + + Output.get().logInfo( + "&PlayerFileNameCheck Task: &aChecking: " + + "&dPlayer Rank files &aand &dPlayer Cache files&a." ); + + PlayerNewFileNameCheckAsyncTask task = new PlayerNewFileNameCheckAsyncTask(); + + PrisonTaskSubmitter.runTaskLaterAsync( task, delayTicks ); + } + else { + // Fail silently... + } + } + + @Override + public void run() { + + int changedPlayRankFiles = 0; + int changedCacheFiles = 0; + + PlayerManager pm = PrisonRanks.getInstance().getPlayerManager(); + List players = pm.getPlayers(); + + File playerRankpath = new File( new File( Prison.get().getDataFolder(), "ranksDb" ), "players"); + File playerCachePath = new File( Prison.get().getDataFolder(), "playerCache" ); + + for (RankPlayer player : players) { + + // Rank player file: + if ( playerRankpath.exists() ) + { + + String oldFilename = JsonFileIO.filenamePlayerOld( player ); + File oldPlayerFile = new File( playerRankpath, oldFilename ); + + if ( oldPlayerFile.exists() ) { + + String newFilename = JsonFileIO.filenamePlayerNew( player ); + File newPlayerFile = new File( playerRankpath, newFilename ); + + oldPlayerFile.renameTo(newPlayerFile); + +// Files.move( oldPlayerFile, newPlayerFile ); + changedPlayRankFiles++; + } + } + + + // Player cache file: + if ( playerCachePath.exists() ) + { + + String oldFilename = JsonFileIO.filenameCacheOld( player ); + File oldCacheFile = new File( playerCachePath, oldFilename ); + + if ( oldCacheFile.exists() ) { + + String newFilename = JsonFileIO.filenameCacheNew( player ); + File newCacheFile = new File( playerCachePath, newFilename ); + + oldCacheFile.renameTo(newCacheFile); +// Files.move( oldCacheFile, newCacheFile ); + changedCacheFiles++; + } + } + } + + Output.get().logInfo( + "&3PlayerFileNameCheck Task: Files updated for %d players: &aPlayer Rank files: " + + "&d%d " + + "&aPlayer Cache files: &d%d", + players.size(), + changedPlayRankFiles, + changedCacheFiles ); + + if ( changedCacheFiles > 0 || changedCacheFiles > 0 ) { + saveStatusDetailLog( changedPlayRankFiles, changedCacheFiles ); + } + else if ( players.size() > 0 ) { + Output.get().logInfo( + "&3PlayerFileNameCheck Task: It appears as if all player files have " + + "already been converted." ); + } + + List msgs = getStatusDetails(); + + for (String msg : msgs) { + + Output.get().logInfo( msg ); + } + + } + + public void saveStatusDetailLog( int changedPlayRankFiles, int changedCacheFiles ) { + // Need to log it: + TreeMap settings = PrisonSystemSettings.getInstance() + .getRootSetting( SystemSettingKey.PlayerFileNameUpdate ); + + if ( !settings.containsKey( "converted") ) { + settings.put("converted", Boolean.TRUE ); + } + + if ( !settings.containsKey( "logs") ) { + settings.put("logs", new ArrayList() ); + } + + @SuppressWarnings("unchecked") + ArrayList logs = (ArrayList) settings.get("logs"); + + TreeMap log = new TreeMap<>(); + + SimpleDateFormat sdFmt = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss"); + log.put("run-date", sdFmt.format(new Date()) ); + log.put("player-cache-files-changed", Integer.valueOf(changedPlayRankFiles) ); + log.put("player-rank-files-changed", Integer.valueOf(changedCacheFiles) ); + + logs.add( log ); + + // Save the update: + PrisonSystemSettings.getInstance().save(); + + // Unload the data: + PrisonSystemSettings.getInstance().unload(); + + + } + + public List getStatusDetails() { + List msg = new ArrayList<>(); + + String msgFmt = " %-13s %7s %7s"; + + boolean useNewFormat = Prison.get().getPlatform() + .getConfigBooleanFalse( "prison-ranks.use-friendly-user-file-name" ); + + TreeMap pfnUpdate = + PrisonSystemSettings.getInstance().getRootSetting( SystemSettingKey.PlayerFileNameUpdate ); + + // Unload the data: + PrisonSystemSettings.getInstance().unload(); + + boolean converted = !pfnUpdate.containsKey("converted") ? + false : (Boolean) pfnUpdate.get("converted"); + + msg.add( "PlayerFileNameUpdate: status: " ); + msg.add( " 'prison-ranks.use-friendly-user-file-name': " + Boolean.toString(useNewFormat) ); + msg.add( " converted: " + Boolean.toString(converted) ); + + if ( converted ) { + + @SuppressWarnings("unchecked") + ArrayList logs = (ArrayList) pfnUpdate.get("logs"); + + msg.add( String.format(msgFmt, "", "Changed", "Changed")); + msg.add( String.format(msgFmt, "Date", "P-Ranks", "P-Cache")); + msg.add( String.format(msgFmt, "-----------", "-------", "-------")); + + for (Object logObj : logs) { + @SuppressWarnings("unchecked") + TreeMap log = (TreeMap) logObj; + + String runDate = (String) log.get("run-date"); + int changedPlayRankFiles = (Integer) log.get("player-cache-files-changed"); + int changedCacheFiles = (Integer) log.get("player-rank-files-changed"); + + msg.add( String.format(msgFmt, + runDate, + Integer.toString(changedCacheFiles), + Integer.toString(changedPlayRankFiles))); + } + + } + + // msg.add( "" ); + + + return msg; + } + +} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java index 77bbd4638..b6ffb5112 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java @@ -59,7 +59,7 @@ public String getName() { */ public String getPlayerFileName() { - return JsonFileIO.getPlayerFileName( this ); + return JsonFileIO.filenamePlayer( this ); } @Override 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 7b2e70f85..ff628e0f2 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 @@ -93,7 +93,7 @@ public SpigotPlayer(org.bukkit.entity.Player bukkitPlayer) { */ public String getPlayerFileName() { - return JsonFileIO.getPlayerFileName( this ); + return JsonFileIO.filenamePlayer( this ); } @Override diff --git a/prison-spigot/src/main/resources/config.yml b/prison-spigot/src/main/resources/config.yml index db8394e8d..efa966b30 100644 --- a/prison-spigot/src/main/resources/config.yml +++ b/prison-spigot/src/main/resources/config.yml @@ -145,7 +145,34 @@ ranks: +# +# The setting `add-new-players-on-startup` will allow prison to scan for new players that +# have not been setup in prison, and add them at server startup. +# This can be disabled. If it is, then when new players are "accessed" then they should be +# added to prison upon demand. It's been reported that adding new players can take a few +# seconds (2 to 5 seconds) per player, which has not been confirmed. But if true, then +# existing servers switching over to Prison could take a long time to setup all players +# at startup. So this setting may make sense in those conditions. +# NOTE: Its not possible to test all situations where new players are bypassed when starting +# Prison. Therefore disabling this setting is at your own risk. But if any issues are +# encountered, then PLEASE contact support on our discord server ASAP and we will +# fix the issues for you. We want Prison to be bug free, but are not able to ensure +# 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. +# +# Older player files, under 'plugins/Prison/data_storage/ranksDB/players', were based upon +# the player's UUID, which is difficult to figure out which file is for each player.' +# The setting 'use-friendly-user-file-names: true' will enable a new file name format, which +# is similar to the file names used under the playerCache directory. +# This setting is disabled by default. The idea is that this new feature will be rolled out, +# but will not be enabled yet. When this is enabled for everyone, this setting will go away. +# When this feature is enabled, the old file formats will be replaced with the new format +# automatically. Once converted, the files cannot be reverted back to the old names. prison-ranks: + startup: + add-new-players-on-startup: true + use-friendly-user-file-names: false + # WARNING: Never use the following setting to disable the vault-economy From b85a8b5497cfe94210fc4ac77c323122b872d91a Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 27 May 2024 03:25:31 -0400 Subject: [PATCH 003/323] RankPlayer files and PlayerCache files: Update to how prison is managing these files, and how it's tracking more of the data that is added to the RankPlayer so that way the TopN process will not have to access the player cache. RankPlayer file changes will increase the frequency of updates on this file. Used to be primarily when there would be a rank change but now it's tracking more information which will be updated when the player cache is saved or unloaded. --- docs/changelog_v3.3.x.md | 6 +- .../mcprison/prison/cache/PlayerCache.java | 18 +++ .../cache/PlayerCacheCheckTimersTask.java | 14 ++ .../cache/PlayerCacheSaveAllPlayersTask.java | 6 +- .../cache/PlayerCacheUnloadPlayerTask.java | 13 ++ .../mcprison/prison/file/FileCollection.java | 20 ++- .../tech/mcprison/prison/file/JsonFileIO.java | 20 +++ .../prison/internal/platform/Platform.java | 6 + .../prison/ranks/data/RankPlayer.java | 152 ++++++++++++++---- .../tech/mcprison/prison/TestPlatform.java | 10 ++ .../prison/ranks/data/RankPlayerFactory.java | 52 ++++++ .../prison/ranks/data/TopNPlayersData.java | 62 ++++++- .../PlayerNewFileNameCheckAsyncTask.java | 13 ++ .../prison/spigot/SpigotPlatform.java | 31 +++- 14 files changed, 381 insertions(+), 42 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 5d1eacbd6..0de6fb062 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.18a 2024-05-26 +# 3.3.0-alpha.18a 2024-05-27 + + +* **RankPlayer files and PlayerCache files:** Update to how prison is managing these files, and how it's tracking more of the data that is added to the RankPlayer so that way the TopN process will not have to access the player cache. +RankPlayer file changes will increase the frequency of updates on this file. Used to be primarily when there would be a rank change but now it's tracking more information which will be updated when the player cache is saved or unloaded. * **Player file name update: The file names used for the rank players and the player cache are being updated.** 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 8b0ddad2c..410a354bc 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 @@ -266,6 +266,24 @@ public PlayerCachePlayerData getOnlinePlayer( Player player ) { return playerData; } + /** + *

This function will only return a player cache object if it's + * already in the player cache. If the player is not in the cache, + * then this will return a null, and the player will not be loaded. + *

+ * + *

Any player that is not in the cache will not be loaded because of + * the usage of this function. + *

+ * + * @param player + * @return + */ + public PlayerCachePlayerData getOnlinePlayerCached( Player player ) { + PlayerCachePlayerData playerData = getPlayer( player, false ); + + return playerData; + } private PlayerCachePlayerData getPlayer( Player player ) { return getPlayer( player, true ); diff --git a/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheCheckTimersTask.java b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheCheckTimersTask.java index 81f418688..431f7aede 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheCheckTimersTask.java +++ b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheCheckTimersTask.java @@ -4,6 +4,10 @@ import java.util.HashSet; import java.util.Set; import java.util.TreeSet; +import java.util.UUID; + +import tech.mcprison.prison.Prison; +import tech.mcprison.prison.ranks.data.RankPlayer; /** *

This periodically ran task will go through all cached players and update @@ -96,6 +100,16 @@ private void processCache() { playerData.addEarnings( 0, null ); } + UUID uuid = UUID.fromString( key ); + + RankPlayer rPlayer = Prison.get().getPlatform() + .getRankPlayer( uuid, + playerData != null ? playerData.getPlayerName() : "" ); + + if ( rPlayer != null ) { + rPlayer.updateTotalLastValues(playerData); + } + } } catch ( ConcurrentModificationException e ) 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 917540f79..cae993369 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 @@ -66,7 +66,11 @@ public void run() Map syncMap = pCache.getPlayers(); - Set keys = new TreeSet<>( syncMap.keySet() ); + Set keys = null; + + synchronized ( syncMap ) { + keys = new TreeSet<>( syncMap.keySet() ); + } for ( String key : keys ) { diff --git a/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheUnloadPlayerTask.java b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheUnloadPlayerTask.java index 79b948bb6..5d18df8c7 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheUnloadPlayerTask.java +++ b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheUnloadPlayerTask.java @@ -1,5 +1,10 @@ package tech.mcprison.prison.cache; +import java.util.UUID; + +import tech.mcprison.prison.Prison; +import tech.mcprison.prison.ranks.data.RankPlayer; + public class PlayerCacheUnloadPlayerTask extends PlayerCacheTask { @@ -15,6 +20,7 @@ public void run() { // Remove from the player cache: PlayerCachePlayerData removed = null; + synchronized ( pCache.getPlayers() ) { @@ -23,6 +29,13 @@ public void run() { if ( removed != null ) { + UUID uuid = UUID.fromString( removed.getPlayerUuid() ); + + RankPlayer rPlayer = Prison.get().getPlatform() + .getRankPlayer( uuid, + removed != null ? removed.getPlayerName() : "" ); + rPlayer.updateTotalLastValues( removed ); + pCache.getCacheFiles().toJsonFile( removed ); } diff --git a/prison-core/src/main/java/tech/mcprison/prison/file/FileCollection.java b/prison-core/src/main/java/tech/mcprison/prison/file/FileCollection.java index e1323e123..fb4ee4766 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/file/FileCollection.java +++ b/prison-core/src/main/java/tech/mcprison/prison/file/FileCollection.java @@ -1,6 +1,7 @@ package tech.mcprison.prison.file; import java.io.File; +import java.io.FileFilter; import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -55,9 +56,13 @@ public File getCollDir() { public List getAll() { List allDocs = new ArrayList<>(); + FileFilter fFilter = JsonFileIO.getPrisonFileFilter(); + + // Each folder in the root directory is its own database. // We'll initialize each of them here. - File[] collectionFiles = this.collDir.listFiles((dir, name) -> name.endsWith(".json")); + File[] collectionFiles = this.collDir.listFiles( fFilter ); +// File[] collectionFiles = this.collDir.listFiles((dir, name) -> name.endsWith(".json")); if (collectionFiles != null) { for (File dbFile : collectionFiles) { if ( isDeleted( dbFile ) ) { @@ -80,7 +85,9 @@ public List getAll() { @Override public Optional get(String key) { - File dbFile = new File(collDir, key + ".json"); + + String suffix = key.endsWith(FILE_SUFFIX_JSON) ? "" : FILE_SUFFIX_JSON; + File dbFile = new File(collDir, key + suffix); Document doc = (Document) readJsonFile(dbFile, new Document()); return Optional.ofNullable(doc); @@ -95,21 +102,24 @@ public void save(Document document) @Override public void save(String filename, Document document) { - File dbFile = new File(collDir, filename + ".json"); + String suffix = filename.endsWith(FILE_SUFFIX_JSON) ? "" : FILE_SUFFIX_JSON; + File dbFile = new File(collDir, filename + suffix); saveJsonFile( dbFile, document ); } @Override public boolean delete(String name) { - File dbFile = new File(collDir, name + ".json"); + String suffix = name.endsWith(FILE_SUFFIX_JSON) ? "" : FILE_SUFFIX_JSON; + File dbFile = new File(collDir, name + suffix); return virtualDelete( dbFile ); } @Override public File backup( String name ) { - File dbFile = new File(collDir, name + ".json"); + String suffix = name.endsWith(FILE_SUFFIX_JSON) ? "" : FILE_SUFFIX_JSON; + File dbFile = new File(collDir, name + suffix); File backupFile = virtualBackup( dbFile ); return backupFile; 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 18aa9de47..c8544bdc4 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 @@ -1,6 +1,7 @@ package tech.mcprison.prison.file; import java.io.File; +import java.io.FileFilter; import com.google.gson.Gson; import com.google.gson.GsonBuilder; @@ -18,6 +19,7 @@ public class JsonFileIO public static final String FILE_PREFIX_BACKUP = ".backup_"; public static final String FILE_SUFFIX_BACKUP = ".bu"; public static final String FILE_SUFFIX_TEMP = ".temp"; + public static final String FILE_SUFFIX_TXT = ".txt"; public static final String FILE_TIMESTAMP_FORMAT = "_yyyy-MM-dd_HH-mm-ss"; private final Gson gson; @@ -240,6 +242,24 @@ public String toString( Object obj ) { return json; } + + public static FileFilter getPrisonFileFilter() { + + FileFilter fileFilter = (file) -> { + + String fname = file.getName(); + boolean isTemp = fname.startsWith( FILE_PREFIX_BACKUP ) || + fname.endsWith( FILE_SUFFIX_BACKUP ) || + fname.endsWith( FILE_SUFFIX_TEMP ) || + fname.endsWith( FILE_SUFFIX_TXT ); + + return !file.isDirectory() && !isTemp && + fname.endsWith( FILE_SUFFIX_JSON ); + }; + + return fileFilter; + } + /** * 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 94c3d8f51..d1f88dce2 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 @@ -73,6 +73,12 @@ public interface Platform { public void getWorldLoadErrors( ChatDisplay display ); + public RankPlayer getRankPlayer(UUID uuid, String name); + + + public boolean saveRankPlayer(RankPlayer rPlayer); + + /** * Returns the player with the specified name. */ 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 dce6835ab..81e560e59 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 @@ -68,6 +68,16 @@ public class RankPlayer private UUID uid; + + private long totalBlocks; + + private long totalTokens; + private double currentBalance; + + private long lastSeenDate; + + + // This is used to track if a RankPlayer was saved, or needs to be saved. private transient boolean enableDirty = false; private transient boolean dirty = false; @@ -246,7 +256,106 @@ public UUID getUUID() { return uid; } - public boolean isEnableDirty() { + /** + *

Note that this is a passive field that is actually maintained in the + * player cache. Use that instead of this field. This field is intended to + * be used within TopN stats when the player is offline so the player cache + * does not need to be loaded. + *

+ * + * @return + */ + public long getTotalBlocksTemp() { + return totalBlocks; + } + public void setTotalBlocksTemp(long totalBlocks) { + this.totalBlocks = totalBlocks; + } + + /** + *

Note that this is a passive field that is actually maintained in the + * player cache. Use that instead of this field. This field is intended to + * be used within TopN stats when the player is offline so the player cache + * does not need to be loaded. + *

+ * + * @return + */ + public long getTotalTokensTemp() { + return totalTokens; + } + public void setTotalTokensTemp(long currentTokens) { + this.totalTokens = currentTokens; + } + + /** + *

Note that this is a passive field that is actually maintained in the + * player cache. Use that instead of this field. This field is intended to + * be used within TopN stats when the player is offline so the player cache + * does not need to be loaded. + *

+ * + * @return + */ + public double getCurrentBalanceTemp() { + return currentBalance; + } + public void setCurrentBalanceTemp(double currentBalance) { + this.currentBalance = currentBalance; + } + + /** + *

Note that this is a passive field that is actually maintained in the + * player cache. Use that instead of this field. This field is intended to + * be used within TopN stats when the player is offline so the player cache + * does not need to be loaded. + *

+ * + * @return + */ + public long getLastSeenDateTemp() { + return lastSeenDate; + } + public void setLastSeenDateTemp(long lastSeenDate) { + this.lastSeenDate = lastSeenDate; + } + + public void updateTotalLastValues( PlayerCachePlayerData cacheData ) { + updateTotalLastValues( cacheData, true ); + } + + public void updateTotalLastValues( PlayerCachePlayerData cacheData, boolean update ) { + + if ( cacheData != null ) { + + if ( cacheData.getBlocksTotal() != getTotalBlocksTemp() ) { + + setTotalBlocksTemp( cacheData.getBlocksTotal() ); + setDirty( true ); + } + + if ( cacheData.getLastSeenDate() != getLastSeenDateTemp() ) { + + setLastSeenDateTemp( cacheData.getLastSeenDate() ); + setDirty( true ); + } + + if ( cacheData.getTokensTotal() != getTotalTokensTemp() ) { + + setTotalTokensTemp( cacheData.getTokensTotal() ); + setDirty( true ); + } + + if ( update ) { + + // Save if dirty: + Prison.get().getPlatform().saveRankPlayer( this ); + } + } + } + + + public boolean isEnableDirty() { return enableDirty; } public void setEnableDirty(boolean enableDirty) { @@ -369,42 +478,13 @@ public String getPlayerFileName() { public String filenamePlayer() { return JsonFileIO.filenamePlayer( this ); - -// boolean useNewFormat = Prison.get().getPlatform() -// .getConfigBooleanFalse( "prison-ranks.use-friendly-user-file-name" ); -// -// return useNewFormat ? filenamePlayerNew() : filenamePlayerOld(); } public String filenameCache() { return JsonFileIO.filenameCache( this ); - -// boolean useNewFormat = Prison.get().getPlatform() -// .getConfigBooleanFalse( "prison-ranks.use-friendly-user-file-name" ); -// -// return useNewFormat ? -// filenameCacheNew() : filenamePlayerOld(); } -// public String filenameCacheNew() { -// -// return "cache_" + JsonFileIO.getPlayerFileNameNewVersion( this ); -// } -// public String filenameCacheOld() { -// return JsonFileIO.getPlayerFileNameShortVersion( this ); -// } -// -// public String filenamePlayerNew() -// { -// return "player_" + JsonFileIO.getPlayerFileNameNewVersion( this ); -// } -// -// public String filenamePlayerOld() -// { -// return "player_" + uid.getLeastSignificantBits(); -// } - // /** // *

This function will check to see if the player is on the default rank on @@ -1230,6 +1310,9 @@ public double getBalance() { } setCachedRankPlayerBalance( null, results ); + + // Store player's balance for stats such as TopN: + setCurrentBalanceTemp(results); } return results; @@ -1287,6 +1370,8 @@ private boolean addBalanceEconomy( double amount ) { if ( economy != null ) { results = economy.addBalance( this, amount ); addCachedRankPlayerBalance( null, amount ); + + setCurrentBalanceTemp( economy.getBalance( this ) ); } return results; } @@ -1510,7 +1595,12 @@ public PlayerCache getPlayerCache() { @Override public PlayerCachePlayerData getPlayerCachePlayerData() { - return PlayerCache.getInstance().getOnlinePlayer( this ); + PlayerCachePlayerData cacheData = PlayerCache.getInstance().getOnlinePlayer( this ); + + // Do not update here... it gets called too many times: + //updateTotalLastValues( cacheData ); + + return cacheData; } @Override 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 74eb4933e..1ef8451db 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/TestPlatform.java +++ b/prison-core/src/test/java/tech/mcprison/prison/TestPlatform.java @@ -79,6 +79,16 @@ public void getWorldLoadErrors( ChatDisplay display ) { } + @Override + public RankPlayer getRankPlayer(UUID uuid, String name) { + return null; + } + + @Override + public boolean saveRankPlayer(RankPlayer rPlayer) { + return false; + } + @Override public Optional getPlayer(String name) { return null; diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactory.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactory.java index 542c3e799..cb0fecf66 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactory.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactory.java @@ -9,6 +9,7 @@ import com.google.gson.internal.LinkedTreeMap; import tech.mcprison.prison.Prison; +import tech.mcprison.prison.cache.PlayerCachePlayerData; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.ranks.FirstJoinHandlerMessages; import tech.mcprison.prison.ranks.PrisonRanks; @@ -83,16 +84,67 @@ public RankPlayer createRankPlayer(Document document) { } } + + + if ( document.get("balance") != null ) { + + rankPlayer.setCurrentBalanceTemp( (Double) document.get("balance") ); + } + + if ( document.get("totalBlocks") != null ) { + + rankPlayer.setTotalBlocksTemp( getLong( rankPlayer.getName(), "totalBlocks", document ) ); + } + + if ( document.get("totalTokens") != null ) { + + rankPlayer.setTotalTokensTemp( getLong( rankPlayer.getName(), "totalTokens", document ) ); + } + + if ( document.get("lastSeenDate") != null ) { + + rankPlayer.setTotalBlocksTemp( getLong( rankPlayer.getName(), "lastSeenDate", document ) ); + } + + return rankPlayer; } + private long getLong( String playerName, String field, Document document ) { + long value = 0L; + + Object obj = document.get(field); + if ( obj == null ) { + } + if ( obj instanceof Long ) { + value = (Long) obj; + } + else if ( obj instanceof Double ) { + Double duble = (Double) obj; + value = duble.longValue(); + } + + return value; + } public static Document toDocument( RankPlayer rankPlayer ) { + + // Update some stats from the playerCache: + PlayerCachePlayerData cacheData = rankPlayer.getPlayerCache().getOnlinePlayerCached(rankPlayer); + rankPlayer.updateTotalLastValues( cacheData , false); + Document ret = new Document(); ret.put("uid", rankPlayer.getUUID()); ret.put("ranks", rankPlayer.getRanksRefs() ); // ret.put("prestige", this.prestige); ret.put("names", rankPlayer.getNames()); + + + ret.put("balance", Double.valueOf( rankPlayer.getCurrentBalanceTemp() )); + ret.put("totalBlocks", Long.valueOf( rankPlayer.getTotalBlocksTemp() )); + ret.put("totalTokens", Long.valueOf( rankPlayer.getTotalTokensTemp() )); + ret.put("lastSeenDate", Long.valueOf( rankPlayer.getLastSeenDateTemp() )); + // ret.put("blocksMined", rankPlayer.getBlocksMined() ); return ret; diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/TopNPlayersData.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/TopNPlayersData.java index 10aa7d42e..7319192e0 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/TopNPlayersData.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/TopNPlayersData.java @@ -34,6 +34,8 @@ public class TopNPlayersData { private String name; + private String uuid; + private String playerFileName; private PlayerState playerState; @@ -53,12 +55,21 @@ public class TopNPlayersData private int rankPositionDefault; private int rankPositionPrestiges; + private long blocks; + private long timeMining; + private long timeOnline; + private long tokens; + + private static transient SimpleDateFormat sdFmt = new SimpleDateFormat( "yyyy-MM-dd kk:mm:ss" ); public TopNPlayersData() { super(); this.playerState = PlayerState.offline; + + this.rankPositionDefault = -1; + this.rankPositionPrestiges = -1; } public TopNPlayersData( RankPlayer rPlayer) { @@ -67,7 +78,8 @@ public TopNPlayersData( RankPlayer rPlayer) { this.rPlayer = rPlayer; this.name = rPlayer.getName(); - this.playerFileName = rPlayer.getPlayerFileName(); + this.uuid = rPlayer.getUUID().toString(); +// this.playerFileName = rPlayer.getPlayerFileName(); // // Note: the nextPlayer rank could be in either the default ladder, // // or the next prestige rank if at end of default ladder. @@ -75,7 +87,8 @@ public TopNPlayersData( RankPlayer rPlayer) { // This may be expensive getting lastSeen from the player's cache data: - setLastSeen( rPlayer.getPlayerCachePlayerData().getLastSeenDate() ); + setLastSeen( rPlayer.getLastSeenDateTemp() ); +// setLastSeen( rPlayer.getPlayerCachePlayerData().getLastSeenDate() ); // this.lastSeenFormatted = sdFmt.format( new Date( this.lastSeen ) ); @@ -93,6 +106,14 @@ public void updateRankPlayer( RankPlayer rPlayer ) { setRankPositionDefault( rPlayer.getRankPositonDefault() ); setRankPositionPrestiges( rPlayer.getRankPositonPrestiges() ); + + + setBlocks( rPlayer.getTotalBlocksTemp() ); + setTokens( rPlayer.getTotalTokensTemp() ); + +// setTimeMining( rPlayer.getPlayerCachePlayerData().getOnlineMiningTimeTotal() ); +// setTimeOnline( rPlayer.getPlayerCachePlayerData().getOnlineTimeTotal() ); + } @Override @@ -140,7 +161,8 @@ public int compare(TopNPlayersData o1, TopNPlayersData o2) { } public String getKey() { - return getPlayerFileName(); + + return getUuid() != null ? getUuid() : getPlayerFileName(); } public String getName() { @@ -150,6 +172,13 @@ public void setName(String name) { this.name = name; } + public String getUuid() { + return uuid; + } + public void setUuid(String uuid) { + this.uuid = uuid; + } + public String getPlayerFileName() { return playerFileName; } @@ -230,5 +259,32 @@ public void setRankPositionPrestiges(int rankPositionPrestiges) { this.rankPositionPrestiges = rankPositionPrestiges; } + public long getBlocks() { + return blocks; + } + public void setBlocks(long blocks) { + this.blocks = blocks; + } + + public long getTimeMining() { + return timeMining; + } + public void setTimeMining(long timeMining) { + this.timeMining = timeMining; + } + + public long getTimeOnline() { + return timeOnline; + } + public void setTimeOnline(long timeOnline) { + this.timeOnline = timeOnline; + } + + public long getTokens() { + return tokens; + } + public void setTokens(long tokens) { + this.tokens = tokens; + } } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/tasks/PlayerNewFileNameCheckAsyncTask.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/tasks/PlayerNewFileNameCheckAsyncTask.java index d81235889..f5bef4f7c 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/tasks/PlayerNewFileNameCheckAsyncTask.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/tasks/PlayerNewFileNameCheckAsyncTask.java @@ -10,6 +10,7 @@ import tech.mcprison.prison.Prison; import tech.mcprison.prison.backups.PrisonSystemSettings; import tech.mcprison.prison.backups.PrisonSystemSettings.SystemSettingKey; +import tech.mcprison.prison.cache.PlayerCachePlayerData; import tech.mcprison.prison.file.JsonFileIO; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.ranks.PrisonRanks; @@ -102,6 +103,18 @@ public void run() { oldCacheFile.renameTo(newCacheFile); // Files.move( oldCacheFile, newCacheFile ); changedCacheFiles++; + + // The player's cache data object contains a File object pointing to + // the old cache file, which needs to be replaced with the new + // cache File object, otherwise the player cache will keep trying to + // write to the old file name. + // If the player cache does not contain this player, then it will not + // be loaded. If the player is loaded later on, then it will load + // from the newly renamed files. + PlayerCachePlayerData pCache = player.getPlayerCache().getOnlinePlayerCached( player ); + if ( pCache != null ) { + pCache.setPlayerFile( newCacheFile ); + } } } } 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 9b4f5bf6b..f3c071f31 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 @@ -271,7 +271,36 @@ public void getWorldLoadErrors( ChatDisplay display ) { } - @Override public Optional getPlayer(String name) { + @Override + public RankPlayer getRankPlayer( UUID uuid, String name ) { + RankPlayer rPlayer = null; + + if ( PrisonRanks.getInstance() != null && PrisonRanks.getInstance().isEnabled() ) { + PlayerManager pm = PrisonRanks.getInstance().getPlayerManager(); + + rPlayer = pm.getPlayer( uuid, name ); + + } + + return rPlayer; + } + + @Override + public boolean saveRankPlayer( RankPlayer rPlayer ) { + boolean results = false; + + if ( PrisonRanks.getInstance() != null && PrisonRanks.getInstance().isEnabled() ) { + PlayerManager pm = PrisonRanks.getInstance().getPlayerManager(); + + results = pm.savePlayer(rPlayer); + + } + + return results; + } + + @Override + public Optional getPlayer(String name) { org.bukkit.entity.Player playerBukkit = Bukkit.getPlayer(name); From c08fb0522ec7e0e6870766c3a16bc6feb05f5c6f Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 27 May 2024 12:35:22 -0400 Subject: [PATCH 004/323] New feature: Reloadable players. Players can now be reloaded with the command: `/ranks reload players` or the alias '/prison reload players' If a player's RankPlayer file, as found in `plugins/Prison/data_storage/ranksDB/players/players_*.json', is modified manually, or replaced with a backup copy, then this command will reload all players for the server. When this command is issued, prison will attempt to save all changed player files and remove them from the rank's PlayerManager. Once all players have been removed, the process of reloading them will begin. There is a chance there could be a currently running process that is using the older copy of the player's RankPlayer obect/file. This will not terminate any process, or swap usage of an object in mid-stream. All risks of using this new feature are placed on the individual using this command since it is unknown how some operations and tasks may respond. That said, this really should have minimal to no impact. This feature should not be used frequently; it should only be used on the rare occasion. If this is used frequently, then perhaps there is a larger over arching issue that needs to be addressed. --- docs/changelog_v3.3.x.md | 9 ++++ .../mcprison/prison/ranks/PrisonRanks.java | 11 +---- .../prison/ranks/commands/RanksCommands.java | 30 ++++++++++++ .../prison/ranks/managers/PlayerManager.java | 47 +++++++++++++++++++ 4 files changed, 88 insertions(+), 9 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 0de6fb062..aeec00465 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.18a 2024-05-27 +* **New feature: Reloadable players.** +Players can now be reloaded with the command: `/ranks reload players` or the alias '/prison reload players' +If a player's RankPlayer file, as found in `plugins/Prison/data_storage/ranksDB/players/players_*.json', is modified manually, or replaced with a backup copy, then this command will reload all players for the server. +When this command is issued, prison will attempt to save all changed player files and remove them from the rank's PlayerManager. Once all players have been removed, the process of reloading them will begin. +There is a chance there could be a currently running process that is using the older copy of the player's RankPlayer obect/file. This will not terminate any process, or swap usage of an object in mid-stream. +All risks of using this new feature are placed on the individual using this command since it is unknown how some operations and tasks may respond. That said, this really should have minimal to no impact. +This feature should not be used frequently; it should only be used on the rare occasion. If this is used frequently, then perhaps there is a larger over arching issue that needs to be addressed. + + * **RankPlayer files and PlayerCache files:** Update to how prison is managing these files, and how it's tracking more of the data that is added to the RankPlayer so that way the TopN process will not have to access the player cache. RankPlayer file changes will increase the frequency of updates on this file. Used to be primarily when there would be a rank change but now it's tracking more information which will be updated when the player cache is saved or unloaded. 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 80527e11c..d87b8ff72 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 @@ -187,8 +187,9 @@ public void enable() { playerManager = new PlayerManager(initCollection("players")); + try { - playerManager.loadPlayers(); + playerManager.loadAllPlayers(); } catch (IOException e) { getStatus().setStatus(ModuleStatus.Status.FAILED); @@ -200,14 +201,6 @@ public void enable() { getStatus().addMessage( prisonRanksFailedLoadingPlayersMsg( e.getMessage() )); logStartupMessageError( prisonRanksFailedToLoadPlayFileMsg( e.getMessage() )); } - - - // Hook up all players to the ranks: - // - parameter checkPlayerBalances is set to false - playerManager.connectPlayersToRanks( false ); - - Output.get().logInfo( "Ranks: Finished Connecting Players to Ranks." ); - // Load up the commands 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 0de2ab81b..eafb1ea13 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 @@ -1,5 +1,6 @@ package tech.mcprison.prison.ranks.commands; +import java.io.IOException; import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -2433,6 +2434,35 @@ public void supportPlayerFileNameUpdateCmd(CommandSender sender, } + + + @Command(identifier = "ranks reload players", + description = "Reloads all players.", + aliases = "prison reload players", + onlyPlayers = false, permissions = "ranks.set") + public void reloadPlayersCmd(CommandSender sender ){ + + + try { + PrisonRanks.getInstance().getPlayerManager().reloadAllPlayers(); + + String msg = String.format( + "&3Reload Players: Successful. Maybe..." ); + + sender.sendMessage(msg); + + } + catch (IOException e) { + String msg = String.format( + "&cReload Players: Failed. [%s]", + e.getMessage() ); + + sender.sendMessage(msg); + } + + + } + private boolean contains( String search, String... values ) { boolean results = false; diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java index f0a42242a..1b3566308 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java @@ -36,6 +36,7 @@ import tech.mcprison.prison.internal.Player; import tech.mcprison.prison.internal.PlayerUtil; import tech.mcprison.prison.internal.events.player.PlayerJoinEvent; +import tech.mcprison.prison.modules.ModuleStatus; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.placeholders.ManagerPlaceholders; import tech.mcprison.prison.placeholders.PlaceHolderKey; @@ -2203,5 +2204,51 @@ public void reloadPlaceholders() { getTranslatedPlaceHolderKeys(); } + public void unloadAllPlayers() { + + for (RankPlayer player : getPlayers() ) { + + if ( player.isDirty() ) { + savePlayer(player); + } + } + + getPlayers().clear(); + getPlayersByName().clear(); + + getPlayerErrors().clear(); + } + + + public void loadAllPlayers() + throws IOException { + Output.get().logInfo( "Ranks: Loading Players..." ); + + loadPlayers(); + + + + // Hook up all players to the ranks: + // - parameter checkPlayerBalances is set to false + connectPlayersToRanks( false ); + + Output.get().logInfo( "Ranks: Finished Connecting Players to Ranks." ); + } + + + public void reloadAllPlayers() + throws IOException { + + synchronized ( getPlayers() ) { + + unloadAllPlayers(); + + + loadAllPlayers(); + + reloadPlaceholders(); + } + } + } From 8e3a1f4595f54fd3d0487815c5850d3f71bc8227 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 27 May 2024 14:44:10 -0400 Subject: [PATCH 005/323] Friendly player files: changes to get everything working. The command is able to convert player files, and to update the active player cache. The players do not need to be reloaded, since the system will automatically use the newer file format once the conversion is ran. The checks for which file format should be used is based upon the config.yml setting and if the conversion was ran. Update some notes on the `/ranks reload players`. --- docs/changelog_v3.3.x.md | 7 ++ .../prison/backups/PrisonSystemSettings.java | 105 +++++++++++++++--- .../tech/mcprison/prison/file/JsonFileIO.java | 26 +++-- .../prison/ranks/commands/RanksCommands.java | 16 ++- .../PlayerNewFileNameCheckAsyncTask.java | 40 ++++--- 5 files changed, 153 insertions(+), 41 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index aeec00465..75312a923 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.18a 2024-05-27 +* **Friendly player files: changes to get everything working.** +The command is able to convert player files, and to update the active player cache. +The players do not need to be reloaded, since the system will automatically use the newer file format once the conversion is ran. +The checks for which file format should be used is based upon the config.yml setting and if the conversion was ran. +Update some notes on the `/ranks reload players`. + + * **New feature: Reloadable players.** Players can now be reloaded with the command: `/ranks reload players` or the alias '/prison reload players' If a player's RankPlayer file, as found in `plugins/Prison/data_storage/ranksDB/players/players_*.json', is modified manually, or replaced with a backup copy, then this command will reload all players for the server. diff --git a/prison-core/src/main/java/tech/mcprison/prison/backups/PrisonSystemSettings.java b/prison-core/src/main/java/tech/mcprison/prison/backups/PrisonSystemSettings.java index ace72d8cc..59df26e99 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/backups/PrisonSystemSettings.java +++ b/prison-core/src/main/java/tech/mcprison/prison/backups/PrisonSystemSettings.java @@ -3,18 +3,34 @@ import java.io.File; import java.util.TreeMap; +import tech.mcprison.prison.Prison; import tech.mcprison.prison.file.FileIOData; import tech.mcprison.prison.file.JsonFileIO; +/** + *

This class serves as a way for prison to track major events and + * configuration settings. Such as changes in settings that cannot be + * determined by looking at other files. This is also an internal + * prison settings file that the users should never touch. + *

+ * + *

For the friendly file names, the primary logic is located within + * the Ranks module since it has everything to do with ranks. + * The source code can be found in this class: + * '/prison-ranks/src/main/java/tech/mcprison/prison/ranks/tasks/PlayerNewFileNameCheckAsyncTask.java' + *

+ */ public class PrisonSystemSettings implements FileIOData { public static final String PRISON_SYSTEM_FILENAME = "prison-system-settings.json"; + public static final String PRISON_SYSTEM_SETTING_FRIENDLY_PLAYER_FILE_NAMES = "prison-ranks.use-friendly-user-file-names"; + private static PrisonSystemSettings instance = null; private TreeMap> settings; - public enum SystemSettingKey { + public enum SystemSettingsKey { PlayerFileNameUpdate ; @@ -49,14 +65,14 @@ public static PrisonSystemSettings getInstance() { * * @param rootKey */ - public void addRootSetting( SystemSettingKey rootKey ) { + public void addRootSetting( SystemSettingsKey rootKey ) { if ( !getSettings().containsKey( rootKey.name()) ) { getSettings().put( rootKey.name(), new TreeMap<>() ); } } - public TreeMap getRootSetting( SystemSettingKey rootkey ) { + public TreeMap getRootSetting( SystemSettingsKey rootkey ) { TreeMap results = null; if ( getSettings() == null ) { @@ -72,6 +88,9 @@ public TreeMap getRootSetting( SystemSettingKey rootkey ) { } private TreeMap> getSettings() { + if ( settings == null ) { + this.settings = new TreeMap<>(); + } return settings; } private void setSettings(TreeMap> settings) { @@ -90,22 +109,80 @@ public void save() { public void load() { File file = getPrisonSystemSettingsFile(); - JsonFileIO jfIo = new JsonFileIO(); - - PrisonSystemSettings settings = (PrisonSystemSettings) jfIo.readJsonFile(file, this); - - setSettings( settings.getSettings() ); + if ( file.exists() ) { + JsonFileIO jfIo = new JsonFileIO(); + + PrisonSystemSettings settings = (PrisonSystemSettings) jfIo.readJsonFile(file, this); + + setSettings( settings.getSettings() ); + + } } - public void unload() { - setSettings( null ); - } +// public void unload() { +// setSettings( null ); +// } public File getPrisonSystemSettingsFile() { - PrisonBackups pb = new PrisonBackups(); - File path = pb.getBackupDirectory(); - return new File( path, PRISON_SYSTEM_FILENAME ); + File dataStoragePath = new File( Prison.get().getDataFolder(), "data_storage" ); + + File systemPath = new File( dataStoragePath, "system" ); + + systemPath.mkdirs(); + + return new File( systemPath, PRISON_SYSTEM_FILENAME ); } + + /** + *

This function will check two things. First will be the config settings within + * 'config.yml' to see if the new format is enabled. Secondly, it checks to see if + * the PrisonSystemSettings has recorded if the conversion has taken place. + * Both have to be true in order for this function to return a value of true., + *

+ * + * @return + */ + public static boolean useFriendlyUserFileNames() { + + boolean useNewFormat = Prison.get().getPlatform() + .getConfigBooleanFalse( PRISON_SYSTEM_SETTING_FRIENDLY_PLAYER_FILE_NAMES ); + + if ( useNewFormat ) { + + boolean converted = checkSystemFriendlyUserFileNamesConverted(); + + useNewFormat = converted; + } + + return useNewFormat; + } + + /** + *

This function specifically returns the value of the 'converted' setting for the + * 'playerFileNameUpdate' prison system key. + *

+ * + *

This does not perform any checks on the settings within 'config.yml'. For a full + * check of both this 'converted' value, and the config settings use the + * 'useFriendlyUserFileNames()' function instead of this function. + *

+ * + * @return + */ + public static boolean checkSystemFriendlyUserFileNamesConverted() { + + TreeMap pfnUpdate = + PrisonSystemSettings.getInstance().getRootSetting( SystemSettingsKey.PlayerFileNameUpdate ); + + // Unload the data: +// PrisonSystemSettings.getInstance().unload(); + + boolean converted = !pfnUpdate.containsKey("converted") ? + false : (Boolean) pfnUpdate.get("converted"); + + return converted; + } + } 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 c8544bdc4..729aedb65 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 @@ -6,7 +6,7 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; -import tech.mcprison.prison.Prison; +import tech.mcprison.prison.backups.PrisonSystemSettings; import tech.mcprison.prison.error.ErrorManager; import tech.mcprison.prison.internal.Player; import tech.mcprison.prison.modules.ModuleStatus; @@ -131,19 +131,31 @@ public static String getFileNameUUIDFragment( String filename ) { */ public static String filenamePlayer( Player player ) { - boolean useNewFormat = Prison.get().getPlatform() - .getConfigBooleanFalse( "prison-ranks.use-friendly-user-file-name" ); + boolean useNewFormat = useFriendlyUserFileNames(); return useNewFormat ? filenamePlayerNew( player ) : filenamePlayerOld( player ); } public static String filenameCache( Player player ) { - boolean useNewFormat = Prison.get().getPlatform() - .getConfigBooleanFalse( "prison-ranks.use-friendly-user-file-name" ); + boolean useNewFormat = useFriendlyUserFileNames(); - return useNewFormat ? - filenameCacheNew( player ) : filenameCacheOld( player ); + return useNewFormat ? filenameCacheNew( player ) : filenameCacheOld( player ); + } + + + /** + *

This function will check two things. First will be the config settings within + * 'config.yml' to see if the new format is enabled. Secondly, it checks to see if + * the PrisonSystemSettings has recorded if the conversion has taken place. + * Both have to be true in order for this function to return a value of true., + *

+ * + * @return + */ + public static boolean useFriendlyUserFileNames() { + + return PrisonSystemSettings.useFriendlyUserFileNames(); } /** 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 eafb1ea13..eaaaf343a 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 @@ -15,6 +15,7 @@ import tech.mcprison.prison.Prison; import tech.mcprison.prison.PrisonAPI; import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; +import tech.mcprison.prison.backups.PrisonSystemSettings; import tech.mcprison.prison.autofeatures.AutoFeaturesWrapper; import tech.mcprison.prison.cache.PlayerCache; import tech.mcprison.prison.cache.PlayerCachePlayerData; @@ -2411,7 +2412,7 @@ public void supportPlayerFileNameUpdateCmd(CommandSender sender, List msg = new PlayerNewFileNameCheckAsyncTask().getStatusDetails(); boolean useNewFormat = Prison.get().getPlatform() - .getConfigBooleanFalse( "prison-ranks.use-friendly-user-file-name" ); + .getConfigBooleanFalse( PrisonSystemSettings.PRISON_SYSTEM_SETTING_FRIENDLY_PLAYER_FILE_NAMES ); // msg.add( "" ); @@ -2421,10 +2422,12 @@ public void supportPlayerFileNameUpdateCmd(CommandSender sender, if ( !useNewFormat ) { Output.get().logInfo( "&cCommand failure: &aBefore the player file names can be " + - "checked, the setting '&cprison-ranks.use-friendly-user-file-name&a' " + + "checked, the setting '&c%s&a' " + "must be set to '&ctrue&a'. Once enabled, this can not be " + "reverted because the player files (Player Ranks and Player Caches) " + - "could be corrupted."); + "could be corrupted.", + PrisonSystemSettings.PRISON_SYSTEM_SETTING_FRIENDLY_PLAYER_FILE_NAMES + ); } else { long delayTicks = 0; @@ -2437,7 +2440,12 @@ public void supportPlayerFileNameUpdateCmd(CommandSender sender, @Command(identifier = "ranks reload players", - description = "Reloads all players.", + description = "Reloads all players. Use at your own risk. Prison is not responsible " + + "if player save files are manually changed, replaced, modified in anyway. " + + "Actual impact of reloading players is not 100% predictable, but " + + "should be safe under most conditions. Before making any manual changes to " + + "any prison file, please run `/prison support backup save help` and make a backup " + + "copy of prison's settings.", aliases = "prison reload players", onlyPlayers = false, permissions = "ranks.set") public void reloadPlayersCmd(CommandSender sender ){ diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/tasks/PlayerNewFileNameCheckAsyncTask.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/tasks/PlayerNewFileNameCheckAsyncTask.java index f5bef4f7c..c6bca2b45 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/tasks/PlayerNewFileNameCheckAsyncTask.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/tasks/PlayerNewFileNameCheckAsyncTask.java @@ -9,7 +9,7 @@ import tech.mcprison.prison.Prison; import tech.mcprison.prison.backups.PrisonSystemSettings; -import tech.mcprison.prison.backups.PrisonSystemSettings.SystemSettingKey; +import tech.mcprison.prison.backups.PrisonSystemSettings.SystemSettingsKey; import tech.mcprison.prison.cache.PlayerCachePlayerData; import tech.mcprison.prison.file.JsonFileIO; import tech.mcprison.prison.output.Output; @@ -33,12 +33,13 @@ public PlayerNewFileNameCheckAsyncTask() { public static void submitTaskSync( long delayTicks ) { boolean useNewFormat = Prison.get().getPlatform() - .getConfigBooleanFalse( "prison-ranks.use-friendly-user-file-name" ); + .getConfigBooleanFalse( + PrisonSystemSettings.PRISON_SYSTEM_SETTING_FRIENDLY_PLAYER_FILE_NAMES ); if ( useNewFormat ) { Output.get().logInfo( - "&PlayerFileNameCheck Task: &aUsing Friendly User filenames: " + "&3PlayerFileNameCheck Task: &aUsing Friendly User filenames: " + "&dConversion file check async task submitted." ); Output.get().logInfo( @@ -50,7 +51,11 @@ public static void submitTaskSync( long delayTicks ) { PrisonTaskSubmitter.runTaskLaterAsync( task, delayTicks ); } else { - // Fail silently... + Output.get().logInfo( + "&3layerFileNameCheck Task: &aFailed. The 'config.yml' setting '%s' " + + "is not enabled so this task cannot run.", + PrisonSystemSettings.PRISON_SYSTEM_SETTING_FRIENDLY_PLAYER_FILE_NAMES ); + } } @@ -63,12 +68,14 @@ public void run() { PlayerManager pm = PrisonRanks.getInstance().getPlayerManager(); List players = pm.getPlayers(); - File playerRankpath = new File( new File( Prison.get().getDataFolder(), "ranksDb" ), "players"); - File playerCachePath = new File( Prison.get().getDataFolder(), "playerCache" ); + File dataStoragePath = new File( Prison.get().getDataFolder(), "data_storage" ); + + File playerRankpath = new File( new File( dataStoragePath, "ranksDb" ), "players"); + File playerCachePath = new File( dataStoragePath, "playerCache" ); for (RankPlayer player : players) { - // Rank player file: + // Rank player file directory: if ( playerRankpath.exists() ) { @@ -88,7 +95,7 @@ public void run() { } - // Player cache file: + // Player cache file directory: if ( playerCachePath.exists() ) { @@ -148,7 +155,7 @@ else if ( players.size() > 0 ) { public void saveStatusDetailLog( int changedPlayRankFiles, int changedCacheFiles ) { // Need to log it: TreeMap settings = PrisonSystemSettings.getInstance() - .getRootSetting( SystemSettingKey.PlayerFileNameUpdate ); + .getRootSetting( SystemSettingsKey.PlayerFileNameUpdate ); if ( !settings.containsKey( "converted") ) { settings.put("converted", Boolean.TRUE ); @@ -174,7 +181,7 @@ public void saveStatusDetailLog( int changedPlayRankFiles, int changedCacheFiles PrisonSystemSettings.getInstance().save(); // Unload the data: - PrisonSystemSettings.getInstance().unload(); +// PrisonSystemSettings.getInstance().unload(); } @@ -182,22 +189,23 @@ public void saveStatusDetailLog( int changedPlayRankFiles, int changedCacheFiles public List getStatusDetails() { List msg = new ArrayList<>(); - String msgFmt = " %-13s %7s %7s"; + String msgFmt = " %-22s %7s %7s"; boolean useNewFormat = Prison.get().getPlatform() - .getConfigBooleanFalse( "prison-ranks.use-friendly-user-file-name" ); + .getConfigBooleanFalse( PrisonSystemSettings.PRISON_SYSTEM_SETTING_FRIENDLY_PLAYER_FILE_NAMES ); TreeMap pfnUpdate = - PrisonSystemSettings.getInstance().getRootSetting( SystemSettingKey.PlayerFileNameUpdate ); + PrisonSystemSettings.getInstance().getRootSetting( SystemSettingsKey.PlayerFileNameUpdate ); // Unload the data: - PrisonSystemSettings.getInstance().unload(); +// PrisonSystemSettings.getInstance().unload(); boolean converted = !pfnUpdate.containsKey("converted") ? false : (Boolean) pfnUpdate.get("converted"); msg.add( "PlayerFileNameUpdate: status: " ); - msg.add( " 'prison-ranks.use-friendly-user-file-name': " + Boolean.toString(useNewFormat) ); + msg.add( " '" + PrisonSystemSettings.PRISON_SYSTEM_SETTING_FRIENDLY_PLAYER_FILE_NAMES + "': " + + Boolean.toString(useNewFormat) ); msg.add( " converted: " + Boolean.toString(converted) ); if ( converted ) { @@ -207,7 +215,7 @@ public List getStatusDetails() { msg.add( String.format(msgFmt, "", "Changed", "Changed")); msg.add( String.format(msgFmt, "Date", "P-Ranks", "P-Cache")); - msg.add( String.format(msgFmt, "-----------", "-------", "-------")); + msg.add( String.format(msgFmt, "-----------------", "-------", "-------")); for (Object logObj : logs) { @SuppressWarnings("unchecked") From b53046f5fb3b9a21f0f6ad3f7647c044b716a4f0 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 27 May 2024 23:59:44 -0400 Subject: [PATCH 006/323] Block utils: Unbreakable blocks breaking. There was an issue with the unbreakable blocks not identifying a collection with a Location for a key. Changed the key to a String using the world-coordinates and it fixed the issue. --- docs/changelog_v3.3.x.md | 5 ++- .../prison/spigot/utils/BlockUtils.java | 35 ++++++++++++++----- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 75312a923..5688a8966 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.18a 2024-05-27 +# 3.3.0-alpha.18a 2024-05-28 + + +* **Block utils: Unbreakable blocks breaking.** There was an issue with the unbreakable blocks not identifying a collection with a Location for a key. Changed the key to a String using the world-coordinates and it fixed the issue. * **Friendly player files: changes to get everything working.** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/BlockUtils.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/BlockUtils.java index 34969030e..9a85e63b3 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/BlockUtils.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/BlockUtils.java @@ -5,6 +5,7 @@ import tech.mcprison.prison.internal.block.PrisonBlock; import tech.mcprison.prison.mines.data.Mine; +import tech.mcprison.prison.output.Output; import tech.mcprison.prison.spigot.block.SpigotBlock; import tech.mcprison.prison.tasks.PrisonTaskSubmitter; import tech.mcprison.prison.util.Location; @@ -13,7 +14,7 @@ public class BlockUtils { private static BlockUtils instance; - private HashMap unbreakableBlocks; + private HashMap unbreakableBlocks; private HashMap> unbreakableBlocksByMine; @@ -42,14 +43,32 @@ public boolean isUnbreakable( SpigotBlock block ) { if ( block != null ) { PrisonBlock pBlock = block.getPrisonBlock(); results = isUnbreakable( pBlock ); + +// dumpUnbreakables( block, results ); } return results; } +// private void dumpUnbreakables(SpigotBlock block, boolean unbreakable) { +// StringBuilder sb = new StringBuilder(); +// +// sb.append( String.format( +// "Unbreakable dump: unbreakable: %s targetBlockLocation: %s {br} unbreakables: ", +// Boolean.toString(unbreakable), +// block.getLocation().toWorldCoordinates() )); +// +// for (String loc : unbreakableBlocks.keySet() ) { +// sb.append( String.format( "%s ", loc)); +// +// } +// +// Output.get().logInfo( sb.toString() ); +// } + public boolean isUnbreakable( PrisonBlock block ) { return block == null || block.getLocation() == null ? false : - getUnbreakableBlocks().containsKey( block.getLocation() ); + getUnbreakableBlocks().containsKey( block.getLocation().toWorldCoordinates() ); } @@ -69,7 +88,7 @@ public UnbreakableBlockData addUnbreakable( Location location, PrisonBlock block if ( location != null ) { data = new UnbreakableBlockData( location, block, mine ); - getUnbreakableBlocks().put( data.getKey(), data ); + getUnbreakableBlocks().put( data.getKey().toWorldCoordinates(), data ); if ( mine != null ) { if ( !getUnbreakableBlocksByMine().containsKey( mine ) ) { @@ -97,7 +116,7 @@ public void removeUnbreakable( Mine mine ) { HashSet blocks = getUnbreakableBlocksByMine().get( mine ); for ( UnbreakableBlockData data : blocks ) { - getUnbreakableBlocks().remove( data.getKey() ); + getUnbreakableBlocks().remove( data.getKey().toWorldCoordinates() ); if ( data.getTaskId() > 0 ) { // If task is still queued to run, cancel it: @@ -111,13 +130,13 @@ public void removeUnbreakable( Mine mine ) { } public void removeUnbreakable( Location location ) { - if ( location != null && getUnbreakableBlocks().containsKey( location ) ) { + if ( location != null && getUnbreakableBlocks().containsKey( location.toWorldCoordinates() ) ) { synchronized ( BlockUtils.class ) { - if ( getUnbreakableBlocks().containsKey( location ) ) { + if ( getUnbreakableBlocks().containsKey( location.toWorldCoordinates() ) ) { - UnbreakableBlockData data = getUnbreakableBlocks().remove( location ); + UnbreakableBlockData data = getUnbreakableBlocks().remove( location.toWorldCoordinates() ); if ( data != null && data.getMine() != null && getUnbreakableBlocksByMine().containsKey( data.getMine() )) { @@ -140,7 +159,7 @@ public void removeUnbreakable( PrisonBlock block ) { } } - public HashMap getUnbreakableBlocks() { + public HashMap getUnbreakableBlocks() { return unbreakableBlocks; } From 7b4855bf3262531810d95de3a59efe777a9f0d66 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 29 May 2024 04:17:33 -0400 Subject: [PATCH 007/323] New feature: Reloadable ranks and ladders. --- docs/changelog_v3.3.x.md | 7 +- .../mcprison/prison/ranks/PrisonRanks.java | 142 ++++++++++++------ .../prison/ranks/PrisonRanksMessages.java | 8 +- .../prison/ranks/data/RankLadderFactory.java | 4 +- .../prison/ranks/managers/LadderManager.java | 85 ++++++++++- .../prison/ranks/managers/PlayerManager.java | 2 +- .../prison/ranks/managers/RankManager.java | 36 ++++- 7 files changed, 218 insertions(+), 66 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 5688a8966..59c764c0b 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -1,4 +1,4 @@ -[Prison Documents - Table of Contents](prison_docs_000_toc.md) +[Prison Documents - Table of Co9ntents](prison_docs_000_toc.md) ## Prison Build Logs for v3.3.x @@ -14,7 +14,10 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.18a 2024-05-28 +# 3.3.0-alpha.18a 2024-05-29 + + +* **New feature: Reloadable ranks and ladders.** * **Block utils: Unbreakable blocks breaking.** There was an issue with the unbreakable blocks not identifying a collection with a Location for a key. Changed the key to a String using the world-coordinates and it fixed the issue. 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 d87b8ff72..f8100ba48 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 @@ -149,7 +149,7 @@ public void enable() { ladderManager = new LadderManager(initCollection("ladders"), this); try { - ladderManager.loadLadders(); + ladderManager.loadLadders( getRankManager() ); } catch (IOException e) { getStatus().setStatus(ModuleStatus.Status.FAILED); @@ -158,7 +158,7 @@ public void enable() { logStartupMessageError( prisonRanksFailureLoadingLadderMsg( e.getMessage() ) ); } - createDefaultLadder(); + ladderManager.createDefaultLadder(); // // Set the rank relationships: @@ -270,6 +270,48 @@ public void enable() { } + + public boolean reloadRanksAndLadders() { + boolean success = false; + + try { + + // New temp RankManager to reload ranks: + RankManager rManager = new RankManager(initCollection("ranks")); + + rManager.reloadAllRanks(); + + // Load up the ladders + + // New temp LadderManager to reload ladders: + LadderManager lManager = new LadderManager(initCollection("ladders"), this); + + // NOTE: This instance of the LadderManager requires the new temp instance of the rank manager: + lManager.reloadAllLadders( rManager ); + + + // Now replace all rank data and ladder data with the newly loaded data: + getRankManager().setLoadedRanks( rManager.getRanks() ); + getRankManager().setRanksByName( rManager.getRanksByName() ); + getRankManager().setRanksById( rManager.getRanksById() ); + + getLadderManager().setLoadedLadders( lManager.getLoadedLadders() ); + + + // Must reload all players now, so they are properly aligned with the ranks and ladders: + getPlayerManager().reloadAllPlayers(); + + + } catch (IOException e) { + String msg = String.format( + "PrisonRanks: reloadRanksAndLadders: Failed. [%s]", + e.getMessage()); + + Output.get().logInfo( msg ); + } + + return success; + } public void checkAllPlayersForJoin() { @@ -404,54 +446,54 @@ private Collection initCollection(String collName) { return collectionOptional.orElseThrow(RuntimeException::new); } - /** - * A default ladder is absolutely necessary on the server, so let's create it if it doesn't exist, this also create the prestiges ladder. - */ - private void createDefaultLadder() { - if ( ladderManager.getLadder(LadderManager.LADDER_DEFAULT) == null ) { - RankLadder rankLadder = ladderManager.createLadder(LadderManager.LADDER_DEFAULT); - - if ( rankLadder == null ) { - - String failureMsg = prisonRanksFailureCreateDefaultLadderMsg(); - - Output.get().logError( failureMsg ); - super.getStatus().toFailed( failureMsg ); - return; - } - - if ( !ladderManager.save( rankLadder ) ) { - - String failureMsg = prisonRanksFailureSavingDefaultLadderMsg(); - - Output.get().logError( failureMsg ); - super.getStatus().toFailed( failureMsg ); - } - } - - if ( ladderManager.getLadder(LadderManager.LADDER_PRESTIGES) == null ) { - RankLadder rankLadder = ladderManager.createLadder(LadderManager.LADDER_PRESTIGES); - - if ( rankLadder == null ) { - - String failureMsg = prisonRanksFailureCreatePrestigeLadderMsg(); - - Output.get().logError( failureMsg ); - super.getStatus().toFailed( failureMsg ); - return; - } - - if ( !ladderManager.save( rankLadder ) ) { - - String failureMsg = prisonRanksFailureSavingPrestigeLadderMsg(); - - Output.get().logError( failureMsg ); - super.getStatus().toFailed( failureMsg ); - } - } - - } - +// /** +// * A default ladder is absolutely necessary on the server, so let's create it if it doesn't exist, this also create the prestiges ladder. +// */ +// private void createDefaultLadder() { +// if ( ladderManager.getLadder(LadderManager.LADDER_DEFAULT) == null ) { +// RankLadder rankLadder = ladderManager.createLadder(LadderManager.LADDER_DEFAULT); +// +// if ( rankLadder == null ) { +// +// String failureMsg = prisonRanksFailureCreateDefaultLadderMsg(); +// +// Output.get().logError( failureMsg ); +// super.getStatus().toFailed( failureMsg ); +// return; +// } +// +// if ( !ladderManager.save( rankLadder ) ) { +// +// String failureMsg = prisonRanksFailureSavingDefaultLadderMsg(); +// +// Output.get().logError( failureMsg ); +// super.getStatus().toFailed( failureMsg ); +// } +// } +// +// if ( ladderManager.getLadder(LadderManager.LADDER_PRESTIGES) == null ) { +// RankLadder rankLadder = ladderManager.createLadder(LadderManager.LADDER_PRESTIGES); +// +// if ( rankLadder == null ) { +// +// String failureMsg = prisonRanksFailureCreatePrestigeLadderMsg(); +// +// Output.get().logError( failureMsg ); +// super.getStatus().toFailed( failureMsg ); +// return; +// } +// +// if ( !ladderManager.save( rankLadder ) ) { +// +// String failureMsg = prisonRanksFailureSavingPrestigeLadderMsg(); +// +// Output.get().logError( failureMsg ); +// super.getStatus().toFailed( failureMsg ); +// } +// } +// +// } +// private void logStartupMessageError( String message ) { diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/PrisonRanksMessages.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/PrisonRanksMessages.java index 579db0592..d62a5dc8d 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/PrisonRanksMessages.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/PrisonRanksMessages.java @@ -132,7 +132,7 @@ public String prisonRanksStatusLoadedPlayersMsg( int playerCount ) { } - protected String prisonRanksFailureCreateDefaultLadderMsg() { + public String prisonRanksFailureCreateDefaultLadderMsg() { String msgCreate = PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_prisonRanks__failure_with_ladder_create" ) @@ -151,7 +151,7 @@ protected String prisonRanksFailureCreateDefaultLadderMsg() { } - protected String prisonRanksFailureSavingDefaultLadderMsg() { + public String prisonRanksFailureSavingDefaultLadderMsg() { String msgSave = PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_prisonRanks__failure_with_ladder_save" ) @@ -171,7 +171,7 @@ protected String prisonRanksFailureSavingDefaultLadderMsg() { - protected String prisonRanksFailureCreatePrestigeLadderMsg() { + public String prisonRanksFailureCreatePrestigeLadderMsg() { String msgCreate = PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_prisonRanks__failure_with_ladder_create" ) @@ -189,7 +189,7 @@ protected String prisonRanksFailureCreatePrestigeLadderMsg() { } - protected String prisonRanksFailureSavingPrestigeLadderMsg() { + public String prisonRanksFailureSavingPrestigeLadderMsg() { String msgSave = PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_prisonRanks__failure_with_ladder_save" ) diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankLadderFactory.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankLadderFactory.java index e3964f7cf..adbe19228 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankLadderFactory.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankLadderFactory.java @@ -13,7 +13,7 @@ public class RankLadderFactory { @SuppressWarnings( "unchecked" ) - public RankLadder createRankLadder(Document document, PrisonRanks prisonRanks) { + public RankLadder createRankLadder(Document document, RankManager rankManager) { RankLadder rankLadder = null; boolean isDirty = false; @@ -23,7 +23,7 @@ public RankLadder createRankLadder(Document document, PrisonRanks prisonRanks) { rankLadder = new RankLadder( id, name ); - RankManager rankManager = prisonRanks.getRankManager(); +// RankManager rankManager = prisonRanks.getRankManager(); if ( rankManager == null ) { 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 f9bd31eac..5b4db10ea 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 @@ -80,13 +80,13 @@ public LadderManager(Collection collection, PrisonRanks prisonRanks) { * @param fileKey The key that this ladder is stored as. This is case-sensitive. * @throws IOException If the file could not be read or does not exist. */ - public void loadLadder(String fileKey) throws IOException { + public void loadLadder(String fileKey, RankManager rankManager) throws IOException { Document doc = collection.get(fileKey).orElseThrow(IOException::new); RankLadderFactory rlFactory = new RankLadderFactory(); - RankLadder ladder = rlFactory.createRankLadder(doc, prisonRanks); + RankLadder ladder = rlFactory.createRankLadder(doc, rankManager); loadedLadders.add(ladder); // Will be dirty if load a ladder and the rank name does not exist and it adds them: @@ -100,13 +100,14 @@ public void loadLadder(String fileKey) throws IOException { * * @throws IOException If the folder could not be found, or if a file could not be read or does not exist. */ - public void loadLadders() throws IOException { + public void loadLadders( RankManager rankManager ) + throws IOException { List documents = collection.getAll(); final RankLadderFactory rlFactory = new RankLadderFactory(); documents.forEach(document -> loadedLadders.add( - rlFactory.createRankLadder(document, prisonRanks)) ); + rlFactory.createRankLadder(document, rankManager)) ); for ( RankLadder ladder : loadedLadders ) { // Will be dirty if load a ladder and the rank name does not exist and it adds them: @@ -386,4 +387,80 @@ public String getLadderByFileName(String fileName) { return results; } + /** + * A default ladder is absolutely necessary on the server, so let's create it if it doesn't exist, this also create the prestiges ladder. + */ + public void createDefaultLadder() { + if ( getLadder(LadderManager.LADDER_DEFAULT) == null ) { + RankLadder rankLadder = createLadder(LadderManager.LADDER_DEFAULT); + + if ( rankLadder == null ) { + + String failureMsg = prisonRanks.prisonRanksFailureCreateDefaultLadderMsg(); + + Output.get().logError( failureMsg ); + prisonRanks.getStatus().toFailed( failureMsg ); + return; + } + + if ( !save( rankLadder ) ) { + + String failureMsg = prisonRanks.prisonRanksFailureSavingDefaultLadderMsg(); + + Output.get().logError( failureMsg ); + prisonRanks.getStatus().toFailed( failureMsg ); + } + } + + if ( getLadder(LadderManager.LADDER_PRESTIGES) == null ) { + RankLadder rankLadder = createLadder(LadderManager.LADDER_PRESTIGES); + + if ( rankLadder == null ) { + + String failureMsg = prisonRanks.prisonRanksFailureCreatePrestigeLadderMsg(); + + Output.get().logError( failureMsg ); + prisonRanks.getStatus().toFailed( failureMsg ); + return; + } + + if ( !save( rankLadder ) ) { + + String failureMsg = prisonRanks.prisonRanksFailureSavingPrestigeLadderMsg(); + + Output.get().logError( failureMsg ); + prisonRanks.getStatus().toFailed( failureMsg ); + } + } + + } + + + + public List getLoadedLadders() { + return loadedLadders; + } + public void setLoadedLadders(List loadedLadders) { + this.loadedLadders = loadedLadders; + } + + + private void resetAllLadders() { + + this.loadedLadders = new ArrayList<>(); + } + + public void reloadAllLadders( RankManager rankManager ) + throws IOException { + Output.get().logInfo( "Ranks: Loading Ladders..." ); + + resetAllLadders(); + + loadLadders( rankManager ); + + + Output.get().logInfo( "Ranks: Finished Loading Ladders." ); + + } + } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java index 1b3566308..794a897de 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java @@ -36,7 +36,6 @@ import tech.mcprison.prison.internal.Player; import tech.mcprison.prison.internal.PlayerUtil; import tech.mcprison.prison.internal.events.player.PlayerJoinEvent; -import tech.mcprison.prison.modules.ModuleStatus; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.placeholders.ManagerPlaceholders; import tech.mcprison.prison.placeholders.PlaceHolderKey; @@ -2063,6 +2062,7 @@ public String getTranslatePlayerPlaceHolder( PlaceholderIdentifier identifier ) * @param results * @return */ + @SuppressWarnings("unused") private String applySecondaryPlaceholders(RankPlayer rankPlayer, String results) { results = applySecondaryPlaceholdersCheck( "{player}", rankPlayer.getName(), 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 561bb8c87..272b289df 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 @@ -719,7 +719,8 @@ public String getTranslateRanksPlaceHolder( PlaceholderIdentifier identifier ) { PlaceholderAttributeBar attributeBar = identifier.getAttributeBar(); PlaceholderAttributeNumberFormat attributeNFormat = identifier.getAttributeNFormat(); PlaceholderAttributeText attributeText = identifier.getAttributeText(); - PlaceholderAttributeTime attributeTime = identifier.getAttributeTime(); + @SuppressWarnings("unused") + PlaceholderAttributeTime attributeTime = identifier.getAttributeTime(); int sequence = identifier.getSequence(); @@ -1590,11 +1591,11 @@ private List getLoadedRanks() { return loadedRanks; } - private TreeMap getRanksByName() { + public TreeMap getRanksByName() { return ranksByName; } - private TreeMap getRanksById() { + public TreeMap getRanksById() { return ranksById; } @@ -1627,4 +1628,33 @@ public void setLadderCommands( LadderCommands ladderCommands ) { this.ladderCommands = ladderCommands; } + public void setLoadedRanks(List loadedRanks) { + this.loadedRanks = loadedRanks; + } + public void setRanksByName(TreeMap ranksByName) { + this.ranksByName = ranksByName; + } + public void setRanksById(TreeMap ranksById) { + this.ranksById = ranksById; + } + + private void resetAllRanks() { + + this.loadedRanks = new ArrayList<>(); + this.ranksByName = new TreeMap<>(); + this.ranksById = new TreeMap<>(); + } + + public void reloadAllRanks() + throws IOException { + Output.get().logInfo( "Ranks: Loading Ranks..." ); + + resetAllRanks(); + + loadRanks(); + + + Output.get().logInfo( "Ranks: Finished Loading Ranks." ); + + } } From 279d6555dc2748d2adce5065d6057f5f3f4bcabf Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 29 May 2024 04:19:29 -0400 Subject: [PATCH 008/323] Friendly player files: Slight adjustments. Added two report features so list both old and new file names for all players, for either player or cache files. --- docs/changelog_v3.3.x.md | 3 + .../prison/ranks/commands/RanksCommands.java | 44 ++++++- .../PlayerNewFileNameCheckAsyncTask.java | 121 ++++++++++++++++++ 3 files changed, 163 insertions(+), 5 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 59c764c0b..abb0498b0 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.18a 2024-05-29 +* **Friendly player files: Slight adjustments. Added two report features so list both old and new file names for all players, for either player or cache files.** + + * **New feature: Reloadable ranks and ladders.** 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 eaaaf343a..759b92083 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 @@ -53,6 +53,7 @@ import tech.mcprison.prison.ranks.managers.RankManager; import tech.mcprison.prison.ranks.managers.RankManager.RanksByLadderOptions; import tech.mcprison.prison.ranks.tasks.PlayerNewFileNameCheckAsyncTask; +import tech.mcprison.prison.ranks.tasks.PlayerNewFileNameCheckAsyncTask.ReportMode; import tech.mcprison.prison.util.JumboTextFont; import tech.mcprison.prison.util.Text; @@ -2405,11 +2406,19 @@ public void supportPlayerFileNameUpdateCmd(CommandSender sender, @Arg(name = "action", def = "status", description = "Only shows the PrisonSystemStatus for the " + "'PlayerFileNameUpdate' and will not try to run the " - + "update. Default: 'status'. [status, run]") String action + + "update. Default: 'status'. [status, run, cache, player]") + String action, + @Arg(name = "page", def = "1", + description = "If a report of 'cache' or 'player', then page is used if there " + + "are more than 25 players. Default = 1. Valid values 1 and higher. [ >= 1]" ) + int page ) { + ReportMode reportMode = ReportMode.fromString( action ); + // Get the PrisonSystemSettings for the PlayerFileNameUpdate and format the results: - List msg = new PlayerNewFileNameCheckAsyncTask().getStatusDetails(); + PlayerNewFileNameCheckAsyncTask task = new PlayerNewFileNameCheckAsyncTask(); + List msg = task.getStatusDetails(); boolean useNewFormat = Prison.get().getPlatform() .getConfigBooleanFalse( PrisonSystemSettings.PRISON_SYSTEM_SETTING_FRIENDLY_PLAYER_FILE_NAMES ); @@ -2418,7 +2427,11 @@ public void supportPlayerFileNameUpdateCmd(CommandSender sender, sender.sendMessage(msg); - if ( action != null && action.trim().equalsIgnoreCase("run")) { + if ( reportMode == ReportMode.cache || reportMode == ReportMode.players ) { + + task.playerConverterReport( reportMode, page ); + } + else if ( reportMode == ReportMode.run ) { if ( !useNewFormat ) { Output.get().logInfo( "&cCommand failure: &aBefore the player file names can be " + @@ -2467,8 +2480,29 @@ public void reloadPlayersCmd(CommandSender sender ){ sender.sendMessage(msg); } - - + } + + + @Command(identifier = "ranks reload ranksLaddersAndPlayers", + description = "Reloads all Ranks and then Ladders. Also reloads players too so they are " + + "properly hooked in to the newly loaded ranks and ladders. " + + "Use at your own risk. Prison is not responsible " + + "if rank and ladder save files are manually changed, replaced, modified in anyway. " + + "Actual impact of reloading ladders and ranks are not 100% predictable, but " + + "should be safe under most conditions. Before making any manual changes to " + + "any prison file, please run `/prison support backup save help` and make a backup " + + "copy of prison's settings.", + aliases = "prison reload ranksLaddersAndPlayers", + onlyPlayers = false, permissions = "ranks.set") + public void reloadLaddersAndRanksCmd(CommandSender sender ){ + + + PrisonRanks.getInstance().reloadRanksAndLadders(); + + String msg = String.format( + "&3Reload ranks, ladders and players: Successful. Maybe..." ); + + sender.sendMessage(msg); } private boolean contains( String search, String... values ) { diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/tasks/PlayerNewFileNameCheckAsyncTask.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/tasks/PlayerNewFileNameCheckAsyncTask.java index c6bca2b45..739603e41 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/tasks/PlayerNewFileNameCheckAsyncTask.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/tasks/PlayerNewFileNameCheckAsyncTask.java @@ -26,6 +26,26 @@ public class PlayerNewFileNameCheckAsyncTask implements PrisonRunnable { + public enum ReportMode { + status, + run, + players, + cache; + + public static ReportMode fromString( String reportMode ) { + ReportMode results = players; + + for (ReportMode mode : values()) { + if ( reportMode != null && mode.name().equalsIgnoreCase(reportMode) ) { + results = mode; + break; + } + } + + return results; + } + } + public PlayerNewFileNameCheckAsyncTask() { super(); } @@ -239,4 +259,105 @@ public List getStatusDetails() { return msg; } + + /** + *

This generates a report in the console that will list all players in prison + * and their old and new file names for a given mode. + *

+ * + * @param page + */ + public void playerConverterReport( ReportMode mode, int page ) { + + PlayerManager pm = PrisonRanks.getInstance().getPlayerManager(); + List players = pm.getPlayers(); + + + int pageSize = 25; + + if ( page <= 1 ) { + page = 1; + } + + + int pageStart = (page - 1) * pageSize; + int pageEnd = pageStart + pageSize; + + + if ( pageEnd >= players.size() ) { + pageEnd = players.size() - 1; + + pageStart = pageEnd - pageSize; + + if ( pageStart < 0 ) { + pageStart = 0; + } + } + + String pattern = "%4s %-6s %-5s %-5s %-60s %-60s \n"; + + StringBuilder sb = new StringBuilder(); + + // Headers: + sb.append( String.format( pattern, "Plyr", "Report", "Using", "Using", "", "" ) ); + sb.append( String.format( pattern, "Nmbr", "Mode", "Old", "new", "Old Filename", "New Filename" ) ); + sb.append( String.format( pattern, "----", "------", "-----", "-----", + "--------- --------- --------- --------- --------- ---------", + "--------- --------- --------- --------- --------- ---------" ) ); + + File dataStoragePath = new File( Prison.get().getDataFolder(), "data_storage" ); + + File playerRankpath = new File( new File( dataStoragePath, "ranksDb" ), "players"); + File playerCachePath = new File( dataStoragePath, "playerCache" ); + + + for ( int i = pageStart; i <= pageEnd; i++ ) { + + RankPlayer player = players.get(i); + + // Rank player file directory: + if ( mode == ReportMode.players ) { + + String oldFilename = JsonFileIO.filenamePlayerOld( player ); + String newFilename = JsonFileIO.filenamePlayerNew( player ); + + File oldPlayerFile = new File( playerRankpath, oldFilename ); + File newPlayerFile = new File( playerRankpath, newFilename ); + + sb.append( String.format( pattern, + Integer.toString(i), + mode.name(), + oldPlayerFile.exists(), + newPlayerFile.exists(), + oldFilename, newFilename ) ); + } + + + // Player cache file directory: + if ( mode == ReportMode.cache ) { + + String oldFilename = JsonFileIO.filenameCacheOld( player ); + String newFilename = JsonFileIO.filenameCacheNew( player ); + + File oldCacheFile = new File( playerCachePath, oldFilename ); + File newCacheFile = new File( playerCachePath, newFilename ); + + sb.append( String.format( pattern, + Integer.toString(i), + mode.name(), + oldCacheFile.exists(), + newCacheFile.exists(), + oldFilename, newFilename ) ); + } + + + } + + Output.get().logInfo( + "&3Prison Player's new file name format report: \n" + + "%s", + sb.toString() ); + + } + } From 42ba6e7d16188d5358ab1b9e215e0d1836b89a89 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 29 May 2024 04:49:02 -0400 Subject: [PATCH 009/323] Mine notifications: Added support for world and server modes. --- docs/changelog_v3.3.x.md | 4 +++ .../prison/mines/commands/MinesCommands.java | 4 +-- .../mcprison/prison/mines/data/MineData.java | 2 ++ .../mcprison/prison/mines/data/MineTasks.java | 30 +++++++++++++++++-- 4 files changed, 35 insertions(+), 5 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index abb0498b0..de58ebff0 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.18a 2024-05-29 +* **Mine notifications: Added support for world and server modes.** + + + * **Friendly player files: Slight adjustments. Added two report features so list both old and new file names for all players, for either player or cache files.** 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 8e7ced08c..5fe5cb89a 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 @@ -2299,7 +2299,7 @@ public void setNotificationCommand(CommandSender sender, @Arg(name = "mineName", description = "The name of the mine to edit, or '*all*' to " + "apply to all mines. [*all*]") String mineName, @Arg(name = "mode", def="displayOptions", description = "The notification mode " - + "to use: [disabled within radius]") + + "to use: [disabled within radius world server]") String mode, @Arg(name = "radius", def="0", description = "The distance from the center of the mine to notify players of a reset." ) String radius @@ -2311,7 +2311,7 @@ public void setNotificationCommand(CommandSender sender, if ( noteMode == MineNotificationMode.displayOptions ) { sender.sendMessage( "&7Select a Mode: &bdisabled&7, &bwithin &7the mine, &bradius " + - "&7from center of mine." ); + "&7from center of mine&7, &bworld&7, &bserver&7." ); return; } diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineData.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineData.java index e8f3f9f2f..f8da89f18 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineData.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineData.java @@ -167,6 +167,8 @@ public enum MineNotificationMode { disable, within, radius, + world, + server, displayOptions ; diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineTasks.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineTasks.java index 7e64551c7..f6b276740 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineTasks.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineTasks.java @@ -271,8 +271,16 @@ protected void broadcastResetMessageToAllPlayersWithRadius() { for (Player player : players) { // Check for either mode: Within the mine, or by radius from mines center: - if ( getNotificationMode() == MineNotificationMode.within && + if ( + getNotificationMode() == MineNotificationMode.server || + + getNotificationMode() == MineNotificationMode.world && + getBounds().getMin().getWorld().getName().equalsIgnoreCase( + player.getLocation().getWorld().getName() ) || + + getNotificationMode() == MineNotificationMode.within && getBounds().withinIncludeTopBottomOfMine(player.getLocation() ) || + getNotificationMode() == MineNotificationMode.radius && getBounds().within(player.getLocation(), getNotificationRadius()) ) { @@ -322,8 +330,16 @@ else if ( PrisonMines.getInstance().getMinesMessages() for (Player player : players) { // Check for either mode: Within the mine, or by radius from mines center: - if ( getNotificationMode() == MineNotificationMode.within && + if ( + getNotificationMode() == MineNotificationMode.server || + + getNotificationMode() == MineNotificationMode.world && + getBounds().getMin().getWorld().getName().equalsIgnoreCase( + player.getLocation().getWorld().getName() ) || + + getNotificationMode() == MineNotificationMode.within && getBounds().withinIncludeTopBottomOfMine(player.getLocation() ) || + getNotificationMode() == MineNotificationMode.radius && getBounds().within(player.getLocation(), getNotificationRadius()) ) { @@ -365,8 +381,16 @@ protected void broadcastPendingResetMessageToAllPlayersWithRadius(MineJob mineJo Prison.get().getPlatform().getOnlinePlayers()); for (Player player : players) { // Check for either mode: Within the mine, or by radius from mines center: - if ( getNotificationMode() == MineNotificationMode.within && + if ( + getNotificationMode() == MineNotificationMode.server || + + getNotificationMode() == MineNotificationMode.world && + getBounds().getMin().getWorld().getName().equalsIgnoreCase( + player.getLocation().getWorld().getName() ) || + + getNotificationMode() == MineNotificationMode.within && getBounds().withinIncludeTopBottomOfMine(player.getLocation() ) || + getNotificationMode() == MineNotificationMode.radius && getBounds().within(player.getLocation(), getNotificationRadius()) ) { From dea241f80b728111eeca3d11839e2c236440d32e Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 29 May 2024 23:15:01 -0400 Subject: [PATCH 010/323] Mine reset notifications: Forgot to add support for 'server' notification mode. --- docs/changelog_v3.3.x.md | 3 ++ .../mcprison/prison/mines/data/MineTasks.java | 33 +++++++++++++++---- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index de58ebff0..1362005d6 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.18a 2024-05-29 +* **Mine reset notifications: Forgot to add support for 'server' notification mode.** + + * **Mine notifications: Added support for world and server modes.** diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineTasks.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineTasks.java index f6b276740..ab4af8375 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineTasks.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineTasks.java @@ -266,8 +266,15 @@ protected void broadcastResetMessageToAllPlayersWithRadius() { World world = getBounds().getCenter().getWorld(); if ( world != null ) { - List players = (world.getPlayers() != null ? world.getPlayers() : - Prison.get().getPlatform().getOnlinePlayers()); + + boolean useWorld = getNotificationMode() != MineNotificationMode.server && + world != null && world.getPlayers() != null; + + List players = + useWorld ? + world.getPlayers() : + Prison.get().getPlatform().getOnlinePlayers(); + for (Player player : players) { // Check for either mode: Within the mine, or by radius from mines center: @@ -325,8 +332,15 @@ else if ( PrisonMines.getInstance().getMinesMessages() World world = getBounds().getCenter().getWorld(); if ( world != null ) { - List players = (world.getPlayers() != null ? world.getPlayers() : - Prison.get().getPlatform().getOnlinePlayers()); + + boolean useWorld = getNotificationMode() != MineNotificationMode.server && + world != null && world.getPlayers() != null; + + List players = + useWorld ? + world.getPlayers() : + Prison.get().getPlatform().getOnlinePlayers(); + for (Player player : players) { // Check for either mode: Within the mine, or by radius from mines center: @@ -377,8 +391,15 @@ protected void broadcastPendingResetMessageToAllPlayersWithRadius(MineJob mineJo World world = getBounds().getCenter().getWorld(); if ( world != null ) { - List players = (world.getPlayers() != null ? world.getPlayers() : - Prison.get().getPlatform().getOnlinePlayers()); + + boolean useWorld = getNotificationMode() != MineNotificationMode.server && + world != null && world.getPlayers() != null; + + List players = + useWorld ? + world.getPlayers() : + Prison.get().getPlatform().getOnlinePlayers(); + for (Player player : players) { // Check for either mode: Within the mine, or by radius from mines center: if ( From 48fb165b83a2974cba24a58c83b17410d07b4c2a Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 30 May 2024 23:27:52 -0400 Subject: [PATCH 011/323] Spigot utils: saw a rare situation where a NPE happened when prison had custom blocks setup, but the plugin was removed. This prevents a NPE if the backing 3rd plugin goes away. --- docs/changelog_v3.3.x.md | 7 ++++++- .../tech/mcprison/prison/spigot/SpigotUtil.java | 13 ++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 1362005d6..cf5e21fde 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.18a 2024-05-29 +# 3.3.0-alpha.18a 2024-05-30 + + +* **Spigot utils: saw a rare situation where a NPE happened when prison had custom blocks setup, but the plugin was removed.** +This prevents a NPE if the backing 3rd plugin goes away. + * **Mine reset notifications: Forgot to add support for 'server' notification mode.** 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 e9bb0fcd6..395e78406 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 @@ -178,11 +178,14 @@ public static ItemStack getItemStack( XMaterial xMaterial, int amount ) { public static SpigotItemStack getSpigotItemStackXMat( XMaterial xMaterial, int amount ) { SpigotItemStack itemStack = null; - try { - itemStack = new SpigotItemStack( getItemStack( xMaterial, amount ) ); - } - catch (PrisonItemStackNotSupportedRuntimeException e) { - // ignore + if ( xMaterial != null ) { + + try { + itemStack = new SpigotItemStack( getItemStack( xMaterial, amount ) ); + } + catch (PrisonItemStackNotSupportedRuntimeException e) { + // ignore + } } return itemStack; From a64b80547c8db57efa1122a76ed25125e0d307e4 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 2 Jun 2024 20:39:26 -0400 Subject: [PATCH 012/323] Rankups: Change how rankups are working by default. They no longer require perms, but within the 'plugis/Prison/config.yml' they can be enabled. The reason for this change is due to the fact that a lot of people have been saying that perms are suddenly forcing a perm check, which has been failing. So although this is a change that may break a few servers which do not want players to be able to control their own rankup or prestige, this is a fix that will make it easier for many others. If these new settings are not added to the config.yml file, then they will default to true. ranks: rankup-bypass-perm-check: true prestige: prestige-bypass-perm-check: true --- .../prison/ranks/commands/RankUpCommand.java | 130 ++++++++++++++---- 1 file changed, 100 insertions(+), 30 deletions(-) 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 2a53095dd..f6b2034d1 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 @@ -156,8 +156,9 @@ public void rankUpMax(CommandSender sender, "command with other ladders, the users must have the correct perms as listed with this " + "command's help information. " , - permissions = "ranks.user", - altPermissions = {"ranks.rankup.default", "ranks.rankup.prestiges", "ranks.rankup.[ladderName]"}, +// permissions = "ranks.user", + altPermissions = {"ranks.user", "ranks.rankup.default", "ranks.rankup.prestiges", + "ranks.rankup.[ladderName]"}, onlyPlayers = false) public void rankUp(CommandSender sender, @Arg(name = "ladder", description = "The ladder to rank up on. Defaults to 'default'.", def = "default") String ladder, @@ -180,6 +181,8 @@ public void rankUp(CommandSender sender, playerName = ""; } + + // NOTE: If this is being ran from the console, the a 'playerName' parameter must be supplied: if ( !isPlayer && playerName.length() == 0 ) { Output.get().logInfo( rankupCannotRunFromConsoleMsg() ); return; @@ -222,26 +225,62 @@ public void rankUp(CommandSender sender, // return; // } + boolean isLadderDefault = ladder.equalsIgnoreCase(LadderManager.LADDER_DEFAULT); + boolean isLadderPrestiges = ladder.equalsIgnoreCase(LadderManager.LADDER_PRESTIGES); + + boolean isPrestigesEnabled = Prison.get().getPlatform().getConfigBooleanFalse( "prestiges" ) || + Prison.get().getPlatform().getConfigBooleanFalse( "prestige.enabled" ); + + + boolean isDefaultBypassPermCheck = isLadderDefault && + Prison.get().getPlatform().getConfigBooleanTrue( + "ranks.rankup-bypass-perm-check" ); + + boolean hasDefaultPerm = sender.hasPermission( "ranks.user" ) || + sender.hasPermission( "ranks.rankup.default"); + + boolean isPrestigeBypassPermCheck = isLadderPrestiges && + isPrestigesEnabled && + Prison.get().getPlatform().getConfigBooleanTrue( + "prestige.prestige-bypass-perm-check" ); + + String perms = "ranks.rankup."; String permsLadder = perms + ladder; + + boolean hasLadderPerm = sender.hasPermission(permsLadder); - boolean isPrestigesEnabled = Prison.get().getPlatform().getConfigBooleanFalse( "prestiges" ) || - Prison.get().getPlatform().getConfigBooleanFalse( "prestige.enabled" ); - - boolean isLadderPrestiges = ladder.equalsIgnoreCase(LadderManager.LADDER_PRESTIGES); - boolean isLadderDefault = ladder.equalsIgnoreCase(LadderManager.LADDER_DEFAULT); + String permsCheck = String.format( + "isDefaultBypassPermCheck: %s, isPrestigeBypassPermCheck: %s, 'ranks.user': %s, '%s': %s ", + Boolean.toString(isDefaultBypassPermCheck), + Boolean.toString(isPrestigeBypassPermCheck), + Boolean.toString( sender.hasPermission( "ranks.user" ) ), + + permsLadder, + Boolean.toString(hasLadderPerm) + ); + - if ( isLadderDefault || + if ( isDefaultBypassPermCheck || + isPrestigeBypassPermCheck || + + isLadderDefault && hasDefaultPerm || + + isPrestigesEnabled && isLadderPrestiges && + hasLadderPerm || + + + !isLadderDefault && !isLadderPrestiges && + hasLadderPerm - (isPrestigesEnabled && isLadderPrestiges || - !isLadderPrestiges ) && - sender.hasPermission( permsLadder) ) { + Output.get().logDebug( DebugTarget.rankup, - "Rankup: cmd '/rankup %s%s' Passed perm check: %s", + "Rankup: cmd '/rankup %s%s' Passed perm check: %s [%s]]", ladder, ( playerName.length() == 0 ? "" : " " + playerName ), - permsLadder ); + permsLadder, + permsCheck ); // Output.get().logDebug( DebugTarget.rankup, @@ -262,8 +301,8 @@ public void rankUp(CommandSender sender, else { Player player = getPlayer( sender, playerName ); Output.get().logDebug( DebugTarget.rankup, - "Rankup: Failed: cmd '/rankup %s' Does not have the permission %s", - ladder, permsLadder ); + "Rankup: Failed: cmd '/rankup %s' Does not have the permission %s. [%s]", + ladder, permsLadder, permsCheck ); rankupMaxNoPermissionMsg( sender, permsLadder, player.getRankPlayer() ); } @@ -279,8 +318,8 @@ public void rankUp(CommandSender sender, + "if the config.yml setting 'prestige.enable__ranks_rankup_prestiges__permission` is set to a " + "value of 'true' (defaults to 'false'). " + "Examples: '/prestige', '/presetige confirm', '/prestige confirm'.", - permissions = "ranks.user", - altPermissions = {"ranks.rankup.prestiges"}, +// permissions = "ranks.user", + altPermissions = {"ranks.user", "ranks.rankup.prestiges"}, onlyPlayers = false) public void prestigeCmd(CommandSender sender, @Arg(name = "playerName", def = "", @@ -324,14 +363,37 @@ public void prestigeCmd(CommandSender sender, } + + boolean isPrestigesEnabled = Prison.get().getPlatform().getConfigBooleanFalse( "prestiges" ) || + Prison.get().getPlatform().getConfigBooleanFalse( "prestige.enabled" ); + + + boolean hasPrestigePerm = sender.hasPermission( "ranks.user" ) || + sender.hasPermission( "ranks.rankup.prestiges"); + + boolean isPrestigeBypassPermCheck = + isPrestigesEnabled && + Prison.get().getPlatform().getConfigBooleanTrue( + "prestige.prestige-bypass-perm-check" ); + + String permsCheck = String.format( + "isPrestigesEnabled: %s, isPrestigeBypassPermCheck: %s, 'ranks.user': %s, 'ranks.rankup.prestiges': %s ", + Boolean.toString(isPrestigesEnabled), + Boolean.toString(isPrestigeBypassPermCheck), + Boolean.toString( sender.hasPermission( "ranks.user" ) ), + + Boolean.toString( sender.hasPermission( "ranks.rankup.prestiges") ) + ); + + String perms = "ranks.rankup."; - String permsLadder = perms + LadderManager.LADDER_PRESTIGES; - boolean hasPermsLadder = sender.hasPermission(permsLadder); - boolean usePerms = Prison.get().getPlatform().getConfigBooleanFalse( "enable__ranks_rankup_prestiges__permission" ); - boolean hasAcessToPrestige = usePerms && hasPermsLadder || !usePerms; +// String permsLadder = perms + LadderManager.LADDER_PRESTIGES; +// boolean hasPermsLadder = sender.hasPermission(permsLadder); +// boolean usePerms = Prison.get().getPlatform().getConfigBooleanFalse( "enable__ranks_rankup_prestiges__permission" ); +// boolean hasAcessToPrestige = usePerms && hasPermsLadder || !usePerms; - boolean isPrestigesEnabled = Prison.get().getPlatform().getConfigBooleanFalse( "prestiges" ) || - Prison.get().getPlatform().getConfigBooleanFalse( "prestige.enabled" ); +// boolean isPrestigesEnabled = Prison.get().getPlatform().getConfigBooleanFalse( "prestiges" ) || +// Prison.get().getPlatform().getConfigBooleanFalse( "prestige.enabled" ); boolean isResetDefaultLadder = Prison.get().getPlatform().getConfigBooleanFalse( "prestige.resetDefaultLadder" ); boolean isResetMoney = Prison.get().getPlatform().getConfigBooleanFalse( "prestige.resetMoney" ); @@ -391,17 +453,15 @@ public void prestigeCmd(CommandSender sender, return; } - if ( isPrestigesEnabled && hasAcessToPrestige ) { + if ( isPrestigeBypassPermCheck || + + isPrestigesEnabled && hasPrestigePerm ) { Output.get().logDebug( DebugTarget.rankup, - "Rankup: cmd '/prestige %s%s' Has Access to '/prestiges': %b " - + "Has perms: %b Perms: %s", + "Rankup: cmd '/prestige %s%s' [%s]", (playerName.length() == 0 ? "" : " " + playerName ), (confirm == null ? "" : " " + confirm ), - - hasAcessToPrestige, - hasPermsLadder, - permsLadder ); + permsCheck ); List cmdTasks = new ArrayList<>(); @@ -413,6 +473,16 @@ public void prestigeCmd(CommandSender sender, Player player = getPlayer( sender, playerName ); submitCmdTasks( player, cmdTasks ); } + else { + Player player = getPlayer( sender, playerName ); + Output.get().logDebug( DebugTarget.rankup, + "Rankup: Failed: cmd '/prestige %s%s' Does not have the permission %s. [%s]", + (playerName.length() == 0 ? "" : " " + playerName ), + (confirm == null ? "" : " " + confirm ), + permsCheck ); + + //prestigeNoPermissionMsg( sender, "ranks.rankup.prestiges", player.getRankPlayer() ); + } } From 76fdd5118b14ba6e553fbfb732e4c8f5c56e756e Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 5 Jun 2024 02:48:06 -0400 Subject: [PATCH 013/323] Rankups: Change how rankups are working by default. They no longer require perms, but within the 'plugis/Prison/config.yml' they can be enabled. The reason for this change is due to the fact that a lot of people have been saying that perms are suddenly forcing a perm check, which has been failing. So although this is a change that may break a few servers which do not want players to be able to control their own rankup or prestige, this is a fix that will make it easier for many others. If these new settings are not added to the config.yml file, then they will default to true. ranks: rankup-bypass-perm-check: true prestige: prestige-bypass-perm-check: true --- docs/changelog_v3.3.x.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index cf5e21fde..0bc1953f1 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,20 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.18a 2024-05-30 +# 3.3.0-alpha.18a 2024-06-02 + + +* **Rankups: Change how rankups are working by default. They no longer require perms, but within the 'plugis/Prison/config.yml' they can be enabled.** +The reason for this change is due to the fact that a lot of people have been saying that perms are suddenly forcing a perm check, which has been failing. +So although this is a change that may break a few servers which do not want players to be able to control their own rankup or prestige, this is a fix that will make it easier for many others. + +```yaml +ranks: + rankup-bypass-perm-check: true +prestige: + prestige-bypass-perm-check: true +``` + * **Spigot utils: saw a rare situation where a NPE happened when prison had custom blocks setup, but the plugin was removed.** From e5a9d0911c967ad98af5d7bdf6a83178db2cdbf2 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 5 Jun 2024 02:56:56 -0400 Subject: [PATCH 014/323] Prison support troubleshoot autosell: Added a new feature to help identify why autosell may not be working. This new command also provides a lot more information about what the individual features do, and how they work. It also provides additional information on features related to sellall that the users may not understand or are aware of, these features may help provide understanding on how to fix issues they may have with other plugins. --- docs/changelog_v3.3.x.md | 8 +- .../mcprison/prison/spigot/SpigotCommand.java | 312 ++++++++++++++++++ 2 files changed, 319 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 0bc1953f1..2b78a1ae1 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.18a 2024-06-02 +# 3.3.0-alpha.18a 2024-06-05 + + +* **Prison support troubleshoot autosell: Added a new feature to help identify why autosell may not be working.** +This new command also provides a lot more information about what the individual features do, and how they work. +It also provides additional information on features related to sellall that the users may not understand or are aware of, +these features may help provide understanding on how to fix issues they may have with other plugins. * **Rankups: Change how rankups are working by default. They no longer require perms, but within the 'plugis/Prison/config.yml' they can be enabled.** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotCommand.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotCommand.java index c1be0120a..2b943df5d 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotCommand.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotCommand.java @@ -1,10 +1,19 @@ package tech.mcprison.prison.spigot; +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.configuration.file.YamlConfiguration; + import tech.mcprison.prison.Prison; +import tech.mcprison.prison.autofeatures.AutoFeaturesWrapper; +import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; import tech.mcprison.prison.commands.Command; import tech.mcprison.prison.internal.CommandSender; import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.sellall.PrisonSellall; import tech.mcprison.prison.spigot.customblock.PrisonItemsAdder; +import tech.mcprison.prison.spigot.sellall.SellAllUtil; public class SpigotCommand { @@ -14,6 +23,309 @@ public SpigotCommand() { // Register these commands: Prison.get().getCommandHandler().registerCommands( this ); } + + + + @Command(identifier = "prison support troubleshoot autosell", + description = "Prison support troubleshooting: autosell. " + + "This command can be ran at any time. It does not make " + + "any changes to any configs. This will help identify if " + + "autosell is properly configured, and if not, then it " + + "will suggest changes.", + aliases = "prison reload players", + onlyPlayers = false, permissions = "ranks.set") + public void supportRanksCmd(CommandSender sender ){ + + List msgs = new ArrayList<>(); + + List perms = new ArrayList<>(); + perms.add( "prison.admin" ); + perms.add( "prison.sellall.delay" ); + perms.add( "prison.autosell.edit" ); + perms.add( "prison.sellall.toggle" ); + perms.add( "" ); + perms.add( "" ); + + msgs.add( "&3Prison support troubleshoot autosell:" ); + + msgs.add( " The following information is intended to help confirmm if " ); + msgs.add( " autosell is enabled, and if it isn't then it will identify " ); + msgs.add( " what settings need to be changed to enable it." ); + + boolean sellall = SpigotPrison.getInstance().isSellAllEnabled(); + + if ( !sellall ) { + msgs.add( "&cWarning: sellall is disabled. It needs to be turned on." ); + + YamlConfiguration modulesConf = SpigotPrison.getInstance().loadConfig("modules.yml"); + String sellallModuleName = PrisonSellall.MODULE_NAME.toLowerCase(); + boolean isSellallModuleDefined = modulesConf.contains(sellallModuleName); + + if ( isSellallModuleDefined ) { + + msgs.add( " The sellall module is enabled." ); + msgs.add( "&c But sellall is disabled." ); + } + else { + msgs.add( "&c The sellall module is not enabled; please enable." ); + msgs.add( "&c Enable by editing file: '&6plugins/Prison/modules.yml&c'" ); + msgs.add( "&c Ensure '&6sellall: true&c' is set to '&6true&c' " ); + msgs.add( "&c Use '&2/prison reload sellall&c' to load the autosell settings." ); + + } + perms.add( "" ); + + msgs.add( " Note: In the 'plugins/Prison/config.yml' there is an older setting " ); + msgs.add( " 'sellall: true' which is no longer used. Do not add it, or enable it, " ); + msgs.add( " since it will be ignored." ); + + perms.add( "" ); + + } + else { + SellAllUtil saUtils = SellAllUtil.get(); + + // Options.Sell_Permission_Enabled: 'false' + // Options.Sell_Permission: prison.admin + // Options.Full_Inv_AutoSell: true + // Options.Full_Inv_AutoSell_Notification: 'true' + // Options.Full_Inv_AutoSell_perUserToggleable: true + // Options.Full_Inv_AutoSell_perUserToggleable_Need_Perm: 'false' + // Options.Full_Inv_AutoSell_PerUserToggleable_Permission: prison.sellall.toggle + // Options.Sell_Per_Block_Permission_Enabled: 'false' + // Options.Sell_Per_Block_Permission: prison.sellall. + // Options.SellAll_ignoreCustomNames: false + + boolean saPermsEnabled = saUtils.isSellAllSellPermissionEnabled; + String saPermsStr = saUtils.permissionSellAllSell; + boolean saFullInvAutosell = saUtils.isAutoSellEnabled; + boolean saUserToggle = saUtils.isAutoSellPerUserToggleable; + boolean saUserTogglePermEnable = saUtils.isAutoSellPerUserToggleablePermEnabled; + String saUserTogglePermStr = saUtils.permissionAutoSellPerUserToggleable; + + + msgs.add( " SellAll is enabled." ); + + msgs.add( " Perms enabled: " + Boolean.toString( saPermsEnabled )); + msgs.add( " 'Options.Sell_Permission_Enabled: " + Boolean.toString( saPermsEnabled ) + "'" ); + if ( saPermsEnabled ) { + + msgs.add( " Perm: 'Options.Sell_Permission: " + saPermsStr + "'" ); + } + msgs.add( " SellAll autosell on full inventory: " + Boolean.toString( saFullInvAutosell ) ); + msgs.add( " 'Options.Full_Inv_AutoSell: " + Boolean.toString( saFullInvAutosell ) + "'" ); + + msgs.add( " SellAll user controlled autosell toggle enabled: " + + Boolean.toString( saUserToggle ) ); + msgs.add( " 'Options.Full_Inv_AutoSell_perUserToggleable: " + Boolean.toString( saUserToggle ) + "'" ); + msgs.add( " SellAll user toggle perms enabled: " + Boolean.toString( saUserTogglePermEnable ) ); + if ( saUserTogglePermEnable ) { + + msgs.add( " 'Options.Full_Inv_AutoSell_PerUserToggleable_Permission: " + saUserTogglePermStr + "'" ); + } + msgs.add( " " ); + + if ( !saFullInvAutosell ) { + + msgs.add( "&c To get auto sell to work, you must enable the SellAll autosell on full inventory." ); + msgs.add( "&c See the above setting on what needs to be changed in the autosell configs." ); + } + + msgs.add( " " ); + + + AutoFeaturesWrapper afWrap = AutoFeaturesWrapper.getInstance(); + + boolean afAutoManagerEnabled = afWrap.isBoolean( AutoFeatures.isAutoManagerEnabled ); + + if ( !afAutoManagerEnabled ) { + + msgs.add( "&c AutoManager is disabled. This needs to be enabled." ); + msgs.add( "&c Config file: '&6plugins/Prison/autoFeaturesConfig.yml&c'" ); + msgs.add( "&c Set '&6autoManager.isAutoManagerEnabled: true&c' to a value of '&6true&c'." ); + msgs.add( "&c Use '&2/prison reload autofeatures&c' to reload the auto features settings." ); + msgs.add( " " ); + } + else { + + boolean afAutoSellIfInventoryIsFull = afWrap.isBoolean( AutoFeatures.isAutoSellIfInventoryIsFull ); + boolean afAutoSellPerBlock = afWrap.isBoolean( AutoFeatures.isAutoSellPerBlockBreakEnabled ); + + String afAutoSellPerBlockPerm = afWrap.getMessage( AutoFeatures.permissionAutoSellPerBlockBreakEnabled ); + boolean afAutoSellPerBlockPermIsEnabled = + !afAutoSellPerBlockPerm.equalsIgnoreCase( "disable" ) && + !afAutoSellPerBlockPerm.equalsIgnoreCase( "disabled" ) && + !afAutoSellPerBlockPerm.equalsIgnoreCase( "false" ) + ; + + boolean afAutoSellForceCheck = afWrap.isBoolean( AutoFeatures.isForceSellAllOnInventoryWhenBukkitBlockBreakEventFires ); + boolean afAutoSellForceDelayedCheck = afWrap.isBoolean( AutoFeatures.isEnabledDelayedSellAllOnInventoryWhenBukkitBlockBreakEventFires ); + long afAutoSellForceDelayedCheckTicks = afWrap.getInteger( AutoFeatures.isEnabledDelayedSellAllOnInventoryDelayInTicks ); + + boolean afAutoSellForceDebugLoggin = afWrap.isBoolean( AutoFeatures.isAutoSellLeftoversForceDebugLogging ); + + msgs.add( " AutoManager is enabled. This is required to use autosell features." ); + msgs.add( " AutoSell on full inventory: " + Boolean.toString( afAutoSellIfInventoryIsFull ) ); + msgs.add( " Note: This setting applies only to the processing of block breakage events. Other " ); + msgs.add( " ways blocks get in to the player's inventory will not trigger this autosell." ); + if ( !afAutoSellIfInventoryIsFull ) { + + msgs.add( " To enable set: 'options.inventory.isAutoSellIfInventoryIsFull: true' to a value of true." ); + } + msgs.add( " AutoSell per block breakage: " + Boolean.toString( afAutoSellPerBlock ) ); + if ( !afAutoSellPerBlock ) { + + msgs.add( " To enable set: 'options.inventory.isAutoSellPerBlockBreakEnabled: true' to a value of true." ); + } + msgs.add( " Per block perms enabled: " + afAutoSellPerBlockPerm + " (" + + (afAutoSellPerBlockPermIsEnabled ? "is enabled" : "is disabled") + + ")"); + msgs.add( " Perm: 'options.inventory.permissionAutoSellPerBlockBreakEnabled: '" + afAutoSellPerBlockPerm + "'" ); + msgs.add( " To disable perms, use either 'disable' or 'false' instead of an actual perm." ); + + msgs.add( " " ); + + + msgs.add( " MineBombs: Since sellall is enabled, the minebomb's autosell feature can be use." ); + msgs.add( " MineBomb's autosell does not require autosell to be enabled since it can " ); + msgs.add( " force an autosell. Autosell is useful for when the mine bomb's drops would " ); + msgs.add( " be far too large for a player's inventory to handle, and may even cause server " ); + msgs.add( " lag." ); + msgs.add( " " ); + + + if ( afAutoSellPerBlock && afAutoSellIfInventoryIsFull ) { + + msgs.add( "Autosell is enabled in autoFeatures for both per block and full inventory. " ); + msgs.add( "Since per block autosell is enabled, Prison will never use the full inventory autosell " ); + msgs.add( "through autoFeatures. " ); + msgs.add( "Per block autosell will sell the items that were just mined, and will not place those items" ); + msgs.add( "in the player's inventory prior to selling them. Per block autosell will only sell what is " ); + msgs.add( "being mined, and will not sell anything that is already in the player's inventory." ); + msgs.add( " " ); + } + else if ( afAutoSellPerBlock ) { + + msgs.add( "Autosell is enabled in autoFeatures for just per block autosell. You do not need to " ); + msgs.add( "enable full inventory autosell since it will never be used anyway; per block autosell " ); + msgs.add( "overrides the full inventory autosell within the autoFeatures. " ); + msgs.add( "Per block autosell will sell the items that were just mined, and will not place those items" ); + msgs.add( "in the player's inventory prior to selling them. Per block autosell will only sell what is " ); + msgs.add( "being mined, and will not sell anything that is already in the player's inventory." ); + msgs.add( " " ); + } + else if ( afAutoSellIfInventoryIsFull ) { + + msgs.add( "Autosell is enabled in autoFeatures only when handling block break events, and a player's " ); + msgs.add( "inventory becomes full. Other actions outside of handling block break events will not trigger " ); + msgs.add( "an autosell event even though the player's inventory may fill up." ); + msgs.add( " " ); + } + else { + + msgs.add( "Autosell has not been enabled in autoFeatures. " ); + msgs.add( "Please see the above settings to enable it. " ); + msgs.add( " " ); + } + + msgs.add( " " ); + msgs.add( "Additonal auto sell capabilities that can be enabled within Prison's auto features: " ); + msgs.add( " " ); + + msgs.add( "The player can turn off autosell by using the `/sellall autoSellToggle` command, if that " ); + msgs.add( "been enabled. See settings above. " ); + + msgs.add( " " ); + msgs.add( "&cPlease note that if autosell is working for other players, but some are complaining " ); + msgs.add( "&cthat it is not working for them, then please have them check their toggle status: " ); + msgs.add( "&c`&2/sellall autoSellToggle&c` " ); + msgs.add( " " ); + + + msgs.add( " " ); + msgs.add( "Note: The following property is not enabled: 'options.inventory.isAutoSellIfInventoryIsFullForBLOCKEVENTSPriority: '" ); + msgs.add( " Since it is not enabled, examples on how to use it is moot and will not be provided." ); + msgs.add( " " ); + msgs.add( "Prison is very flexible because the configuration of many servers can be very complex and involve " ); + msgs.add( "the use of many different plugins, somme of which may conflict with Prison, or it is preferred by " ); + msgs.add( "admins to use another plugin to handle Prison's functions, such as handling the block breakage. " ); + msgs.add( "Therefore, acknowledging the complexity of the plugin mix, Prison has a couple of autosell " ); + msgs.add( "features that can help handle some edge cases. These features generally are not used, but they " ); + msgs.add( "can solve some complex issues. Thease features are listed below..." ); + msgs.add( "" ); + msgs.add( " Check player's inventory for full inventory autosell: " + + (afAutoSellForceCheck ? "is enabled" : "is disabled" ) + ); + msgs.add( " Setting: 'options.inventory.isForceSellAllOnInventoryWhenBukkitBlockBreakEventFires: " + + Boolean.toString(afAutoSellForceCheck)+ " '" ); + msgs.add( " Prison's autoFeature's autosell does not inspect the player's inventory since it is selling " ); + msgs.add( " the blocks that are being mined. Bypassing the player's inventory save a lot of processing " ); + msgs.add( " overhead that could contribute to lag. Therefore this option, which only is tied to " ); + msgs.add( " the 'org.bukkit.BlockBreakEvent' handling, can check the player's inventory to see if it is " ); + msgs.add( " full so a sellall can be fired. This is useful if you have to use another plugins block " ); + msgs.add( " handling but you're using prison's sellall. This could be used in conjunction with a " ); + msgs.add( " event priority of MONITOR, BLOCKEVENTS, ACESS, ACCESSBLOCKEVENTS, and ACCESSMONITOR." ); + msgs.add( " NOTE: This can be applied without enabling autosell directly." ); + msgs.add( " " ); + msgs.add( " Delayed player inventory autosell: " + + (afAutoSellForceDelayedCheck ? "is enabled" : "is disabled" ) + ); + msgs.add( " Delayed for: " + Long.toString( afAutoSellForceDelayedCheckTicks) + " ticks." ); + msgs.add( " Setting: 'options.inventory.isEnabledDelayedSellAllOnInventoryWhenBukkitBlockBreakEventFires: " + + Boolean.toString( afAutoSellForceDelayedCheck ) + " '" ); + msgs.add( " Setting: 'options.inventory.isEnabledDelayedSellAllOnInventoryDelayInTicks: " + + Long.toString( afAutoSellForceDelayedCheckTicks ) + " '" ); + msgs.add( " This option is similar to the check player's inventory for full inventory with autosell, except " ); + msgs.add( " that each time this task runs, it will sell everything in the player's inventory that is sellable." ); + msgs.add( " This process is the same as if the player used `/sellall sell` but on a delay." ); + msgs.add( " " ); + + msgs.add( " How this setting is different, is that it will submit a task to run in 'n' ticks to check " ); + msgs.add( " the player's inventory and then performm an autosell if needed. " ); + msgs.add( " This is very useful for when another plugin is handling the block breaks, and the " ); + msgs.add( " blocks are not yet placed in the player's inventory by the time prison is handling the " ); + msgs.add( " MONITOR (or other) priorities." ); + msgs.add( " Valid tick values are 0 and higher, with 2 ticks being the default. Setting this value to " ); + msgs.add( " one second (20 ticks) or higher is reasonable, and can reduce server load, but the player will " ); + msgs.add( " see a slight delay from when their inventoy becommes full and when it is sold. " ); + msgs.add( " This submits a player task to check their inventory in the future, as defined by " ); + msgs.add( " the number of ticks. While this submitted task is waiting to run, or is running, " ); + msgs.add( " addtional mining by the player will not submit more of these tasks. One task per player " ); + msgs.add( " can be submitted at time, since the task will handle all prior mining activiies." ); + msgs.add( " " ); + msgs.add( " " ); + + + msgs.add( " Force debug logging on autosell overflow conditions: " + + (afAutoSellForceDebugLoggin ? "is enabled" : "is disabled" ) ); + msgs.add( " Setting: 'options.inventory.isAutoSellLeftoversForceDebugLogging: " + + Boolean.toString( afAutoSellForceDebugLoggin ) + " '" ); + msgs.add( " It would be a VERY rare condition for blocks not autoselling, and could be a sign that the " ); + msgs.add( " block has not been setup in the Prison sellall shop." ); + msgs.add( " Therefore, if this situation is identified, where there are leftover blocks that have not been " ); + msgs.add( " auto sold, then this will trigger a block break debug logging even for that transaction so it's " ); + msgs.add( " added to the console. This will make it easier to track down configuration issues with sellall." ); + msgs.add( " The block break debuging informmation is being shown in full since it can help provide " ); + msgs.add( " more information which would help address other possible issues." ); + msgs.add( " This only works when prison debug mode is turned off, and it will only log just that one" ); + msgs.add( " transaction (it will not turn on prison debug mode)." ); + msgs.add( " This condition will be logged every time the issue happens, which can result in many logged messages." ); + + msgs.add( " " ); + + } + msgs.add( " " ); + + + } + + //msgs.add( "" ); + + + sender.sendMessage(msgs); + } + + @Command(identifier = "prison support test itemsAdder", description = "Initial test of accessing ItemsAdder.", From 14d095d3852c8548dd08c37e8bb6148f95109479 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 5 Jun 2024 02:58:40 -0400 Subject: [PATCH 015/323] Rankup: config.yml settings to bypass perms in both the default and prestige ladders. --- prison-spigot/src/main/resources/config.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/prison-spigot/src/main/resources/config.yml b/prison-spigot/src/main/resources/config.yml index efa966b30..f2c9e7a37 100644 --- a/prison-spigot/src/main/resources/config.yml +++ b/prison-spigot/src/main/resources/config.yml @@ -99,6 +99,7 @@ prestige: prestige-confirm-gui: true force-sellall: false no-prestige-value: "" + prestige-bypass-perm-check: true enable__ranks_rankup_prestiges__permission: false @@ -142,6 +143,7 @@ ranks: gui-prestiges-include-rankup-button: true gui-others-include-rankup-button: true player-economy-cache-update-delay-ticks: 60 + rankup-bypass-perm-check: true From eaff1c56d4ab8c393b73ca359db4d37557d60f8f Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 7 Jun 2024 03:08:02 -0400 Subject: [PATCH 016/323] Prison support troubleshoot sellallmines: This new commmand will review all blocks used in all mines, and show a report based upon each block to identify if it is setup in the sellall shop. This is a good way to identify if all blocks that are used have an entry within sellall. Note that this only reviews the blocks, but not their possible drops, which may differ. --- docs/changelog_v3.3.x.md | 7 +- .../mcprison/prison/spigot/SpigotCommand.java | 287 +++++++++++++++++- .../prison/spigot/sellall/SellAllUtil.java | 7 + .../prison/spigot/utils/BlockUtils.java | 1 - 4 files changed, 295 insertions(+), 7 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 2b78a1ae1..b61a87259 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.18a 2024-06-05 +# 3.3.0-alpha.18a 2024-06-07 + + +* **Prison support troubleshoot sellallmines: This new commmand will review all blocks used in all mines, and show a report based upon each block to identify if it is setup in the sellall shop.** +This is a good way to identify if all blocks that are used have an entry within sellall. +Note that this only reviews the blocks, but not their possible drops, which may differ. * **Prison support troubleshoot autosell: Added a new feature to help identify why autosell may not be working.** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotCommand.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotCommand.java index 2b943df5d..4907fbaac 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotCommand.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotCommand.java @@ -1,15 +1,22 @@ package tech.mcprison.prison.spigot; +import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; +import java.util.Set; +import java.util.TreeMap; import org.bukkit.configuration.file.YamlConfiguration; import tech.mcprison.prison.Prison; -import tech.mcprison.prison.autofeatures.AutoFeaturesWrapper; import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; +import tech.mcprison.prison.autofeatures.AutoFeaturesWrapper; +import tech.mcprison.prison.commands.Arg; import tech.mcprison.prison.commands.Command; import tech.mcprison.prison.internal.CommandSender; +import tech.mcprison.prison.internal.block.PrisonBlock; +import tech.mcprison.prison.mines.PrisonMines; +import tech.mcprison.prison.mines.data.Mine; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.sellall.PrisonSellall; import tech.mcprison.prison.spigot.customblock.PrisonItemsAdder; @@ -32,9 +39,9 @@ public SpigotCommand() { + "any changes to any configs. This will help identify if " + "autosell is properly configured, and if not, then it " + "will suggest changes.", - aliases = "prison reload players", - onlyPlayers = false, permissions = "ranks.set") - public void supportRanksCmd(CommandSender sender ){ + onlyPlayers = false, + permissions = "ranks.set") + public void supportTroubleshootAutosellCmd(CommandSender sender ){ List msgs = new ArrayList<>(); @@ -325,9 +332,279 @@ else if ( afAutoSellIfInventoryIsFull ) { sender.sendMessage(msgs); } + + + + + @Command(identifier = "prison support troubleshoot sellallMines", + description = "Prison support troubleshooting: sellall for Mines. " + + "This command can be ran at any time. It does not make " + + "any changes to any configs. This will help identify if " + + "sellall is properly setup for all mines. This will " + + "check all mines to confirm that all blocks are represented " + + "within sellall.", + onlyPlayers = false, + permissions = "ranks.set") + public void supportTroubleshootSellallMinesCmd(CommandSender sender, + @Arg(name = "action", + description = "Perform different actions related to this comand. " + + "The default action will show only the blocks that are not " + + "setup in sellall." + + "The action 'all' will show all of the blocks, including which " + + "mines are using that block, including the chance. ", + def = "notInSellall" ) + String action ) { + + List msgs = new ArrayList<>(); + + boolean reportAllblocks = action != null && action.trim().equalsIgnoreCase( "all" );; + + boolean sellallEnabled = SpigotPrison.getInstance().isSellAllEnabled(); + + if ( !sellallEnabled ) { + msgs.add( "&cWarning: sellall is disabled. It needs to be turned on." ); + + msgs.add( "" ); + msgs.add( "This support commmand cannot validate if the blocks used within the mines " ); + msgs.add( "are within sellall if sellall is not even enabled." ); + msgs.add( "" ); + msgs.add( "If you are not wanting to use Prison's sellall ,then do not use this command " ); + msgs.add( "since it will not help you configure, or troubleshoot, other plugins that " ); + msgs.add( "are handling the selling of the blocks players are getting from mining." ); + msgs.add( "" ); + + } + else { + SellAllUtil saUtils = SellAllUtil.get(); + + int sellallItemCount = saUtils.getSellAllItems().size(); + + msgs.add( " SellAll is enabled." ); + + msgs.add( " Items in sellall: " + sellallItemCount ); + + msgs.add( "" ); + + boolean minesEnabled = PrisonMines.getInstance().isEnabled(); + + if ( !minesEnabled ) { + msgs.add( "&cWarning: mines are disabled. It needs to be turned on." ); + + msgs.add( "" ); + msgs.add( "This support commmand cannot validate if the blocks used within the mines " ); + msgs.add( "are supported within sellall if the Prison Mines's module isn't even enabled." ); + msgs.add( "" ); + + } + else { + PrisonMines pMines = PrisonMines.getInstance(); + List mines = pMines.getMines(); + + TreeMap blocksInMines = new TreeMap<>(); + + + + msgs.add( " Mines are enabled." ); + + msgs.add( " Total mines: " + mines.size() ); + + + for (Mine mine : mines) { + + List blocks = mine.getPrisonBlocks(); + + for ( PrisonBlock block : blocks ) { + + if ( !blocksInMines.containsKey( block.getBlockName() ) ) { + SupportBlockMines blockMines = new SupportBlockMines( block ); + blocksInMines.put( blockMines.getKey(), blockMines ); + } + + SupportBlockMines blockMines = blocksInMines.get(block.getBlockName()); + + blockMines.addMine( mine ); + + } + + } + + msgs.add( " Unique blocks within all mines: " + blocksInMines.size() ); + msgs.add( "" ); + + + Set keys = blocksInMines.keySet(); + + int validBlocks = 0; + int invalidBlocks = 0; + + + // validate all blocks with sellall: + for (String key : keys) { + SupportBlockMines blockMines = blocksInMines.get( key ); + + //saUtils.getSellAllItems().get( ) + + PrisonBlock saPrisonBlock = saUtils.getSellallItem( + blockMines.getBlock() ); + + if ( saPrisonBlock != null ) { + + blockMines.setBlockInSellall( true ); + validBlocks++; + } + else { + + blockMines.setBlockInSellall( false ); + invalidBlocks++; + } + + } + + + msgs.add( "Total blocks in all mines: " + (validBlocks + invalidBlocks) ); + msgs.add( " Total valid blocks: " + validBlocks ); + msgs.add( " Total invalid blocks: " + invalidBlocks ); + msgs.add( " " ); + + if ( reportAllblocks ) { + + msgs.add( "All valid and invalid blocks: " ); + } + else { + + msgs.add( "Only invalid blocks. Rerun with 'all' to view all blocks." ); + } + msgs.add( " " ); + + + + // Print block lists: + SupportBlockMines headers = new SupportBlockMines(); + msgs.add( headers.header1() ); + msgs.add( headers.header2() ); + for (String key : keys) { + SupportBlockMines blockMines = blocksInMines.get( key ); + + if ( !reportAllblocks && !blockMines.isBlockInSellall() || + reportAllblocks ) { + + String msg = blockMines.toString(); + + msgs.add( msg ); + } + } + + + + } + + msgs.add( "" ); + msgs.add( "" ); + msgs.add( "" ); + + } + + + sender.sendMessage(msgs); + } + + public class SupportBlockMines { + private PrisonBlock block; + + private boolean blockInSellall; + + private TreeMap mines; + + public SupportBlockMines() { + super(); + + this.block = null; + this.blockInSellall = false; + this.mines = new TreeMap<>(); + } + + public SupportBlockMines( PrisonBlock block ) { + this(); + + this.block = block; + } + + public String getKey() { + return block.getBlockName(); + } + + public void addMine(Mine mine) { + String key = mine.getName(); + if ( !getMines().containsKey(key)) { + getMines().put(key, mine); + } + } + + public String header1() { + return " Block: mine (chance), ..."; + } + public String header2() { + return " ------ -------------- ..."; + } + + + public String toString() { + StringBuilder sb = new StringBuilder(); + + DecimalFormat dFmt = Prison.getDecimalFormatStaticDouble(); + + sb.append( " ").append( getKey() ) + .append( ": " ); + + if ( getMines() != null ) { + + Set keys = getMines().keySet(); + + int len = sb.length(); + for ( String key : keys ) { + if ( sb.length() != len ) { + sb.append( ", " ); + } + Mine mine = getMines().get(key); + + // Must get the mine's PrisonBlock since that will contain the chance: + PrisonBlock mineBlock = mine.getPrisonBlock( getKey() ); + sb.append( mine.getName() ) + .append( " (" ) + .append( dFmt.format( mineBlock.getChance()) ) + .append( ")" ); + + } + } + + return sb.toString(); + } + + public PrisonBlock getBlock() { + return block; + } + public void setBlock(PrisonBlock block) { + this.block = block; + } + + public boolean isBlockInSellall() { + return blockInSellall; + } + public void setBlockInSellall(boolean blockInSellall) { + this.blockInSellall = blockInSellall; + } + + public TreeMap getMines() { + return mines; + } + public void setMines(TreeMap mines) { + this.mines = mines; + } + } + - @Command(identifier = "prison support test itemsAdder", + @Command(identifier = "prison support test itemsAdder", description = "Initial test of accessing ItemsAdder.", onlyPlayers = false, permissions = "prison.admin" ) public void testItemAdderCommand(CommandSender sender ) { 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 145bc08a3..efd508489 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 @@ -930,6 +930,13 @@ private SellAllData sellItemStack( SpigotItemStack iStack, double multiplier ) { return soldItem; } + public PrisonBlock getSellallItem( PrisonBlock block ) { + + PrisonBlock pBlockSellAll = sellAllItems.get( block.getBlockNameSearch() ); + + return pBlockSellAll; + } + // /** // * Get SellAll Sell Money, calculated from all the enabled backpacks (from sellAll config and integrations) and // * main inventory. diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/BlockUtils.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/BlockUtils.java index 9a85e63b3..33086c27e 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/BlockUtils.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/BlockUtils.java @@ -5,7 +5,6 @@ import tech.mcprison.prison.internal.block.PrisonBlock; import tech.mcprison.prison.mines.data.Mine; -import tech.mcprison.prison.output.Output; import tech.mcprison.prison.spigot.block.SpigotBlock; import tech.mcprison.prison.tasks.PrisonTaskSubmitter; import tech.mcprison.prison.util.Location; From 146ebcf2a4c1485e7b6089eb152ceaa57ec8301b Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 8 Jun 2024 14:37:43 -0400 Subject: [PATCH 017/323] New feature: AutoFeatures: Smelt and Blocking: New option to include the player's current inventory when performing a smelting and/or blocking. The way this works, is that before "trying" to smelt or block an item in the drops list for the player, that it removes that same item from the player's inventory, and adds them to the player's drops. This ensures that the inventory gets smelted or blocked, and any leftovers are then returned to the inventory. These new features default to false, which off, so as the older behavior is honored and this will not break any existing servers. --- docs/changelog_v3.3.x.md | 8 +- .../tech/mcprison/prison/PrisonCommand.java | 11 ++ .../autofeatures/AutoFeaturesFileConfig.java | 4 +- .../prison/spigot/SpigotPlatform.java | 10 ++ .../mcprison/prison/spigot/SpigotUtil.java | 16 ++ .../autofeatures/AutoManagerFeatures.java | 168 ++++++++++++++---- 6 files changed, 185 insertions(+), 32 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index b61a87259..53536a947 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.18a 2024-06-07 +# 3.3.0-alpha.18a 2024-06-08 + + +* **New feature: AutoFeatures: Smelt and Blocking: New option to include the player's current inventory when performing a smelting and/or blocking.** +The way this works, is that before "trying" to smelt or block an item in the drops list for the player, that it removes that same item from the player's inventory, and adds them to the player's drops. +This ensures that the inventory gets smelted or blocked, and any leftovers are then returned to the inventory. +These new features default to false, which off, so as the older behavior is honored and this will not break any existing servers. * **Prison support troubleshoot sellallmines: This new commmand will review all blocks used in all mines, and show a report based upon each block to identify if it is setup in the sellall shop.** 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 6eea9900f..d012f5d9d 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java +++ b/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java @@ -1070,6 +1070,16 @@ public void autoFeaturesInformation(CommandSender sender) { + + display.addText( "&b " ); + display.addText( "&b options.inventory.includePlayerInventoryWhenSmelting %s", + afw.isBoolean( AutoFeatures.includePlayerInventoryWhenSmelting )); + display.addText( "&b options.inventory.includePlayerInventoryWhenBlocking %s", + afw.isBoolean( AutoFeatures.includePlayerInventoryWhenBlocking )); + + + + display.addText( "&b " ); display.addText( "&b options.general.isCalculateDurabilityEnabled %s", afw.isBoolean( AutoFeatures.isCalculateDurabilityEnabled )); @@ -1086,6 +1096,7 @@ public void autoFeaturesInformation(CommandSender sender) { display.addText( "&b options.general.fortuneMultiplierMax %s", afw.getMessage( AutoFeatures.fortuneMultiplierMax )); + display.addText( "&b " ); display.addText( "&b options.isProcessMcMMOBlockBreakEvents %s", afw.isBoolean( AutoFeatures.isProcessMcMMOBlockBreakEvents )); 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 538f13608..06d1baf83 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 @@ -248,7 +248,9 @@ public enum AutoFeatures { actionBarMessageIfInventoryIsFull(inventory, true), // hologramIfInventoryIsFull(general, false), - + + includePlayerInventoryWhenSmelting(inventory, false), + includePlayerInventoryWhenBlocking(inventory, false), tokens(options), 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 f3c071f31..491a0e473 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 @@ -2417,6 +2417,16 @@ public List getActiveFeatures( boolean showLaddersAndRanks ) { + results.add( " " ); + results.add( String.format(". Include player inventory when smelting:&b%s", + (afw.isBoolean( AutoFeatures.includePlayerInventoryWhenSmelting ) ? "&2Enabled" : "&cDisabled" ) + ) ); + results.add( String.format(". Include player inventory when blocking:&b%s", + (afw.isBoolean( AutoFeatures.includePlayerInventoryWhenBlocking ) ? "&2Enabled" : "&cDisabled" ) + ) ); + + + results.add( " " ); boolean isDurabilityEnabled = afw.isBoolean( AutoFeatures.isCalculateDurabilityEnabled ); 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 395e78406..3a870942e 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 @@ -471,6 +471,22 @@ public static int itemStackRemoveAll( XMaterial xMat, Inventory inv ) { return count; } + + public static void getAllDroppedItemTypesFromPlayerInventory( + Player player, XMaterial xMat, SpigotItemStack drop ) { + + if ( xMat != null ) { + + int inventoryCount = itemStackRemoveAll(player, xMat); + + if ( inventoryCount > 0 ) { + + int count = drop.getAmount(); + drop.setAmount( count + inventoryCount ); + } + } + } + /** *

This function is used to convert a map to a String. It has been created to provide a * String conversion for ItemStack.serialize() functions. 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 d11f389ca..50b30921f 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 @@ -3,7 +3,6 @@ import java.text.DecimalFormat; import java.util.ArrayList; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map.Entry; import java.util.Random; @@ -556,6 +555,9 @@ private int applyAutoEventsDetails( PrisonMinesBlockBreakEvent pmEvent ) { isAutoBlock = (mine != null || mine == null && !limit2minesBlock) && isAutoBlock; + boolean includePlayerInventoryWhenSmelting = isBoolean( AutoFeatures.includePlayerInventoryWhenSmelting ); + boolean includePlayerInventoryWhenBlocking = isBoolean( AutoFeatures.includePlayerInventoryWhenBlocking ); + if ( Output.get().isDebug( DebugTarget.blockBreak ) ) { pmEvent.getDebugInfo().append( "{br}|| (applyAutoEvents: " ) @@ -586,6 +588,7 @@ private int applyAutoEventsDetails( PrisonMinesBlockBreakEvent pmEvent ) { .append( permSmelt ? "perm " : "" ) .append( configSmelt ? "config " : "" ) .append( limit2minesSmelt ? "mines" : "noLimit" ) + .append( includePlayerInventoryWhenSmelting ? " includePlayerInventory" : "" ) .append( "] ") .append( " Block [") @@ -594,6 +597,7 @@ private int applyAutoEventsDetails( PrisonMinesBlockBreakEvent pmEvent ) { .append( permBlock ? "perm " : "" ) .append( configBlock ? "config " : "" ) .append( limit2minesBlock ? "mines" : "noLimit" ) + .append( includePlayerInventoryWhenBlocking ? " includePlayerInventory" : "" ) .append( "] "); } @@ -625,10 +629,13 @@ private int applyAutoEventsDetails( PrisonMinesBlockBreakEvent pmEvent ) { .append( "{br}|| (NormalDrop handling enabled: " ) .append( "normalDropSmelt[" ) .append( configNormalDropSmelt ? "enabled" : "disabled" ) + .append( configNormalDropSmelt && includePlayerInventoryWhenSmelting ? " includePlayerInventory" : "" ) .append( "] " ) .append( "normalDropBlock[" ) .append( configNormalDropBlock ? "enabled" : "disabled" ) + .append( configNormalDropBlock && includePlayerInventoryWhenBlocking ? " includePlayerInventory" : "" ) .append( "] " ) + .append( "normalDropCheckForFullInventory[" ) .append( configNormalDropCheckForFullInventory ? "enabled" : "disabled" ) .append( "] " ) @@ -870,14 +877,16 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, // Smelt if ( isAutoSmelt ) { debugInfo.append( "(autoSmelting: drops)" ); - normalDropSmelt( drops ); + + normalDropSmelt( pmEvent.getPlayer(), drops ); } // Block if ( isAutoBlock ) { debugInfo.append( "(autoBlocking: drops)" ); - normalDropBlock( drops ); + + normalDropBlock( pmEvent.getPlayer(), drops ); } String mineName = pmEvent.getMine() == null ? null : pmEvent.getMine().getName(); @@ -1186,13 +1195,15 @@ public int calculateNormalDrop( PrisonMinesBlockBreakEvent pmEvent ) { if ( isBoolean( AutoFeatures.normalDropSmelt ) ) { pmEvent.getDebugInfo().append( "(normSmelting: drops)" ); - normalDropSmelt( drops ); + + normalDropSmelt( pmEvent.getPlayer(), drops ); } if ( isBoolean( AutoFeatures.normalDropBlock ) ) { pmEvent.getDebugInfo().append( "(normBlocking: drops)" ); - normalDropBlock( drops ); + + normalDropBlock( pmEvent.getPlayer(), drops ); } @@ -2227,11 +2238,13 @@ else if ( isBoolean( AutoFeatures.pickupBlockNameListEnabled ) && pickupBlockNam * * @param drops */ - protected void normalDropSmelt( List drops ) { + protected void normalDropSmelt( Player player, List drops ) { boolean isAll = isBoolean( AutoFeatures.smeltAllBlocks ); - Set xMats = new HashSet<>(); + boolean includePlayerInventory = isBoolean( AutoFeatures.includePlayerInventoryWhenSmelting ); + + TreeMap xMats = new TreeMap<>(); for ( SpigotItemStack sItemStack : drops ) { if ( sItemStack.getMaterial().getBlockType() == PrisonBlockType.CustomItems || @@ -2251,21 +2264,25 @@ else if ( sItemStack.getMaterial() != null ) { xMat = SpigotCompatibility.getInstance().getXMaterial( sItemStack.getMaterial() ); } - if ( xMat != null && !xMats.contains( xMat ) ) { - xMats.add( xMat ); + if ( xMat != null && !xMats.containsKey( xMat ) ) { + xMats.put( xMat, sItemStack ); } } - - for ( XMaterial source : xMats ) { - + Set keys = xMats.keySet(); + for ( XMaterial source : keys ) { + SpigotItemStack drop = xMats.get( source ); switch ( source ) { case COBBLESTONE: if ( isAll || isBoolean( AutoFeatures.smeltCobblestone ) ) { + if ( includePlayerInventory ) { + SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( + player, source, drop ); + } SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.STONE, 1 ); } break; @@ -2277,6 +2294,10 @@ else if ( sItemStack.getMaterial() != null ) { if ( isAll || isBoolean( AutoFeatures.smeltGoldOre ) ) { + if ( includePlayerInventory ) { + SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( + player, source, drop ); + } SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.GOLD_INGOT, 1 ); } break; @@ -2286,6 +2307,10 @@ else if ( sItemStack.getMaterial() != null ) { case RAW_IRON: if ( isAll || isBoolean( AutoFeatures.smeltIronOre ) ) { + if ( includePlayerInventory ) { + SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( + player, source, drop ); + } SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.IRON_INGOT, 1 ); } break; @@ -2294,6 +2319,10 @@ else if ( sItemStack.getMaterial() != null ) { case DEEPSLATE_COAL_ORE: if ( isAll || isBoolean( AutoFeatures.smeltCoalOre ) ) { + if ( includePlayerInventory ) { + SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( + player, source, drop ); + } SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.COAL, 1 ); } break; @@ -2302,6 +2331,10 @@ else if ( sItemStack.getMaterial() != null ) { case DEEPSLATE_DIAMOND_ORE: if ( isAll || isBoolean( AutoFeatures.smeltDiamondlOre ) ) { + if ( includePlayerInventory ) { + SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( + player, source, drop ); + } SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.DIAMOND, 1 ); } break; @@ -2310,6 +2343,10 @@ else if ( sItemStack.getMaterial() != null ) { case DEEPSLATE_EMERALD_ORE: if ( isAll || isBoolean( AutoFeatures.smeltEmeraldOre ) ) { + if ( includePlayerInventory ) { + SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( + player, source, drop ); + } SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.EMERALD, 1 ); } break; @@ -2318,6 +2355,10 @@ else if ( sItemStack.getMaterial() != null ) { case DEEPSLATE_LAPIS_ORE: if ( isAll || isBoolean( AutoFeatures.smeltLapisOre ) ) { + if ( includePlayerInventory ) { + SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( + player, source, drop ); + } SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.LAPIS_LAZULI, 1 ); } break; @@ -2326,6 +2367,10 @@ else if ( sItemStack.getMaterial() != null ) { case DEEPSLATE_REDSTONE_ORE: if ( isAll || isBoolean( AutoFeatures.smeltRedstoneOre ) ) { + if ( includePlayerInventory ) { + SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( + player, source, drop ); + } SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.REDSTONE, 1 ); } break; @@ -2333,6 +2378,10 @@ else if ( sItemStack.getMaterial() != null ) { case NETHER_QUARTZ_ORE: if ( isAll || isBoolean( AutoFeatures.smeltNetherQuartzOre ) ) { + if ( includePlayerInventory ) { + SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( + player, source, drop ); + } SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.QUARTZ, 1 ); } break; @@ -2340,6 +2389,10 @@ else if ( sItemStack.getMaterial() != null ) { case ANCIENT_DEBRIS: if ( isAll || isBoolean( AutoFeatures.smeltAncientDebris ) ) { + if ( includePlayerInventory ) { + SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( + player, source, drop ); + } SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.NETHERITE_SCRAP, 1 ); } break; @@ -2350,6 +2403,10 @@ else if ( sItemStack.getMaterial() != null ) { case RAW_COPPER: if ( isAll || isBoolean( AutoFeatures.smeltCopperOre ) ) { + if ( includePlayerInventory ) { + SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( + player, source, drop ); + } SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.COPPER_INGOT, 1); } break; @@ -2369,11 +2426,13 @@ else if ( sItemStack.getMaterial() != null ) { * * @param drops */ - protected void normalDropBlock( List drops ) { + protected void normalDropBlock( Player player, List drops ) { boolean isAll = isBoolean( AutoFeatures.smeltAllBlocks ); - Set xMats = new HashSet<>(); + boolean includePlayerInventory = isBoolean( AutoFeatures.includePlayerInventoryWhenSmelting ); + + TreeMap xMats = new TreeMap<>(); for ( SpigotItemStack sItemStack : drops ) { if ( sItemStack.getMaterial().getBlockType() == PrisonBlockType.CustomItems || @@ -2386,97 +2445,146 @@ protected void normalDropBlock( List drops ) { XMaterial source = XMaterial.matchXMaterial( sItemStack.getBukkitStack() ); - if ( !xMats.contains( source ) ) { - xMats.add( source ); + if ( !xMats.containsKey( source ) ) { + xMats.put( source, sItemStack ); } } } - - for ( XMaterial source : xMats ) { + Set keys = xMats.keySet(); + for ( XMaterial source : keys ) { + SpigotItemStack drop = xMats.get( source ); switch ( source ) { case GOLD_INGOT: if ( isAll || isBoolean( AutoFeatures.blockGoldBlock ) ) { - + + if ( includePlayerInventory ) { + SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( + player, source, drop ); + } SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.GOLD_BLOCK, 9 ); } break; case IRON_INGOT: if ( isAll || isBoolean( AutoFeatures.blockIronBlock ) ) { - + + if ( includePlayerInventory ) { + SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( + player, source, drop ); + } SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.IRON_BLOCK, 9 ); } break; case COAL: if ( isAll || isBoolean( AutoFeatures.blockCoalBlock ) ) { - + + if ( includePlayerInventory ) { + SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( + player, source, drop ); + } SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.COAL_BLOCK, 9 ); } break; case DIAMOND: if ( isAll || isBoolean( AutoFeatures.blockDiamondBlock ) ) { - + + if ( includePlayerInventory ) { + SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( + player, source, drop ); + } SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.DIAMOND_BLOCK, 9 ); } break; case REDSTONE: if ( isAll || isBoolean( AutoFeatures.blockRedstoneBlock ) ) { - + + if ( includePlayerInventory ) { + SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( + player, source, drop ); + } SpigotUtil.itemStackReplaceItems( drops, source,XMaterial.REDSTONE_BLOCK, 9 ); } break; case EMERALD: if ( isAll || isBoolean( AutoFeatures.blockEmeraldBlock ) ) { - + + if ( includePlayerInventory ) { + SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( + player, source, drop ); + } SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.EMERALD_BLOCK, 9 ); } break; case QUARTZ: if ( isAll || isBoolean( AutoFeatures.blockQuartzBlock ) ) { - + + if ( includePlayerInventory ) { + SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( + player, source, drop ); + } SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.QUARTZ_BLOCK, 4 ); } break; case PRISMARINE_SHARD: if ( isAll || isBoolean( AutoFeatures.blockPrismarineBlock ) ) { - + + if ( includePlayerInventory ) { + SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( + player, source, drop ); + } SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.PRISMARINE, 4 ); } break; case SNOWBALL: if ( isAll || isBoolean( AutoFeatures.blockSnowBlock ) ) { - + + if ( includePlayerInventory ) { + SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( + player, source, drop ); + } SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.SNOW_BLOCK, 4 ); } break; case GLOWSTONE_DUST: if ( isAll || isBoolean( AutoFeatures.blockGlowstone ) ) { - + + if ( includePlayerInventory ) { + SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( + player, source, drop ); + } SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.GLOWSTONE, 4 ); } break; case LAPIS_LAZULI: if ( isAll || isBoolean( AutoFeatures.blockLapisBlock ) ) { - + + if ( includePlayerInventory ) { + SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( + player, source, drop ); + } SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.LAPIS_BLOCK, 9 ); } break; case COPPER_INGOT: if ( isAll || isBoolean( AutoFeatures.blockCopperBlock ) ) { - + + if ( includePlayerInventory ) { + SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( + player, source, drop ); + } SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.COPPER_BLOCK, 9 ); } break; From feb21f71a4eae591393a83cd8fd436342b393eb0 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 22 Jun 2024 23:21:47 -0400 Subject: [PATCH 018/323] Upgrade XSeries to v11.1.0 to support spigot v1.21.0. XSeries v11.x no longer directly supports the matching to spigot 1.8 resources by the use of id and data byte. So added the support directly to the prison compatibility class for spigot 1.8 so prison can continue to use XSeries with spigot 1.8 without any issues. --- docs/changelog_v3.3.x.md | 6 ++- gradle/libs.versions.toml | 2 +- .../spigot/compat/Spigot_1_8_Blocks.java | 47 ++++++++++++++++++- 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 53536a947..07e7dd6ed 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.18a 2024-06-08 +# 3.3.0-alpha.18a 2024-06-22 + + +* **Upgrade XSeries to v11.1.0 to support spigot v1.21.0.** +XSeries v11.x no longer directly supports the matching to spigot 1.8 resources by the use of id and data byte. So added the support directly to the prison compatibility class for spigot 1.8 so prison can continue to use XSeries with spigot 1.8 without any issues. * **New feature: AutoFeatures: Smelt and Blocking: New option to include the player's current inventory when performing a smelting and/or blocking.** diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 62104e59f..4c8c7ce8e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -28,7 +28,7 @@ commons-lang3 = "3.12.0" groovy = "3.0.9" gson = "2.10.1" spiget = "1.4.6-SNAPSHOT" -xseries = "10.0.0" +xseries = "11.1.0" junit = "4.12" guava = "31.1-jre" spigotApi = "1.13.2-R0.1-SNAPSHOT" diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_8_Blocks.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_8_Blocks.java index fbb1b65c6..cb0d7773e 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_8_Blocks.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_8_Blocks.java @@ -228,7 +228,9 @@ public XMaterial getXMaterial( Block spigotBlock ) { if ( results == null ) { // Last chance: try to match by id: int id = spigotBlock.getType().getId(); - results = XMaterial.matchXMaterial( id, data ).orElse( null ); + + results = matchXMaterial( id, data ); +// results = XMaterial.matchXMaterial( id, data ).orElse( null ); } if ( results == null ) { @@ -262,6 +264,49 @@ public XMaterial getXMaterial( Block spigotBlock ) { return results == NULL_TOKEN ? null : results; } + + /** + * This function was removed from XMaterial as of XSeries v11.0.0. + * + * This behaves the same, so spigot 1.8 can still be used with + * XSeries v11.1.0+. + * + * Gets the XMaterial based on the material's ID (Magic Value) and data value.
+ * You should avoid using this for performance issues. + * + * Since prison uses a material cache in this function, this will only get the + * XMaterial the first time the item is requested. So performance is bad, but + * it's a one time hit. + * + * Warning: this method loops through all the available materials and matches their + * ID using {@link #getId()} which takes a really long time. + * + * @param id the ID (Magic value) of the material. + * @param data the data value of the material. + * @return a parsed XMaterial with the same ID and data value. + * @see #matchXMaterial(ItemStack) + */ + public static XMaterial matchXMaterial(int id, byte data) { + XMaterial results = null; + + // NOTE: XMaterial.MAX_ID == 2267. +// if (id < 0 || id > 2267 || data < 0) return null; + + if (id >= 0 && id <= 2267 && data >= 0) { + + for (XMaterial materials : XMaterial.VALUES) { + if (materials.getData() == data && materials.getId() == id) { + + results = materials; + break; + } + } + } + + return results; + } + + @Override public XMaterial getXMaterial( PrisonBlock prisonBlock ) { XMaterial results = NULL_TOKEN; From 96b7759ea6d168258a825f4005387ac5503c682f Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 22 Jun 2024 23:26:15 -0400 Subject: [PATCH 019/323] XMaterial bug fix. If a newer version of spigot is being use that XSeries does not support, there is a chance an error could happen if a newer block type is added to the sellall shop list, or some other need tries to access all block types on the server. This prevents a parse error within XMaterial from shutting down prison's ability to process all of the blocks. This should have been a very rare condition, but now it's guarded against cause problems. --- docs/changelog_v3.3.x.md | 4 ++++ .../tech/mcprison/prison/spigot/SpigotUtil.java | 14 +++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 07e7dd6ed..0fe034a07 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.18a 2024-06-22 +* **XMaterial bug fix. If a newer version of spigot is being use that XSeries does not support**, there is a chance an error could happen if a newer block type is added to the sellall shop list, or some other need tries to access all block types on the server. +This prevents a parse error within XMaterial from shutting down prison's ability to process all of the blocks. This should have been a very rare condition, but now it's guarded against cause problems. + + * **Upgrade XSeries to v11.1.0 to support spigot v1.21.0.** XSeries v11.x no longer directly supports the matching to spigot 1.8 resources by the use of id and data byte. So added the support directly to the prison compatibility class for spigot 1.8 so prison can continue to use XSeries with spigot 1.8 without any issues. 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 3a870942e..6295fc029 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 @@ -663,7 +663,19 @@ public static List getAllPlatformBlockTypes() { for ( XMaterial xMat : XMaterial.values() ) { if ( xMat.isSupported() ) { - ItemStack itemStack = xMat.parseItem(); + ItemStack itemStack = null; + + try { + itemStack = xMat.parseItem(); + } + catch (Exception e) { + Output.get().logInfo( + "Notice: invalid XMaterial type encountered when trying to use 'parseItem()'. %s " + + "Contact prison support. XSeries may need to be updated to support " + + "the current version of spigot. ", + xMat.name() + ); + } if ( xMat.name().toLowerCase().contains( "_wood" ) ) { From a6b13b9786f618f7a2b411488de81547ce8f35fa Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 22 Jun 2024 23:28:30 -0400 Subject: [PATCH 020/323] Block break of unknown block type: Handle a condition of when a target block is not a known. Cancels the event. --- docs/changelog_v3.3.x.md | 3 +++ .../prison/spigot/block/OnBlockBreakMines.java | 12 +++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 0fe034a07..ad8f61694 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.18a 2024-06-22 +* **Block break of unknown block type: Handle a condition of when a target block is not a known.*** Cancels the event. + + * **XMaterial bug fix. If a newer version of spigot is being use that XSeries does not support**, there is a chance an error could happen if a newer block type is added to the sellall shop list, or some other need tries to access all block types on the server. This prevents a parse error within XMaterial from shutting down prison's ability to process all of the blocks. This should have been a very rare condition, but now it's guarded against cause problems. 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 a99068edd..80e7c8a6e 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 @@ -46,7 +46,8 @@ enum EventResultsReasons { ignore_event__block_already_counted, cancel_event__block_already_counted, ignore_event__monitor_priority_but_not_AIR, - cancel_event__player_has_no_access + cancel_event__player_has_no_access, + cancel_event__block_is_not_mappable_to_target_block ; } @@ -382,6 +383,15 @@ else if ( !ignoreBlockReuse && targetBlock.isCounted() ) { } } } + else { + // A targetBlock could not be found for the current block. + // So it must be invalid: + + // Do not cancel the event... + results.setResultsReason( EventResultsReasons.cancel_event__block_is_not_mappable_to_target_block ); + + results.setCancelEvent( true ); + } } From b64530af1d0978d83c9a0f779438c9503d0c6a59 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 22 Jun 2024 23:31:06 -0400 Subject: [PATCH 021/323] Rankup and Presetige: Fixed a bug where when prestiging for the first time that it was taking the cost of the default ladder's first rank (generally zero value). This now uses the correct ladder based upon which ladder is being targeted for the rankup or prestige. --- docs/changelog_v3.3.x.md | 4 ++++ .../src/main/java/tech/mcprison/prison/ranks/RankUtil.java | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index ad8f61694..a5f3fe77e 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.18a 2024-06-22 +* **Rankup and Presetige: Fixed a bug where when prestiging for the first time that it was taking the cost of the default ladder's first rank (generally zero value).** +This now uses the correct ladder based upon which ladder is being targeted for the rankup or prestige. + + * **Block break of unknown block type: Handle a condition of when a target block is not a known.*** Cancels the event. diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/RankUtil.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/RankUtil.java index 642d26442..08001c4c0 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/RankUtil.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/RankUtil.java @@ -452,8 +452,12 @@ private void rankupPlayerInternal(RankupResults results, PlayerRank pRankNext = null; + + // ??? Why not use targetRank here? Isn't that always non-null? if ( originalRank == null ) { - Rank nextRank = PrisonRanks.getInstance().getDefaultLadder().getLowestRank().orElse( null ); + Rank nextRank = ladder.getLowestRank().orElse( null ); +// Rank nextRank = PrisonRanks.getInstance().getDefaultLadder().getLowestRank().orElse( null ); + pRankNext = rankPlayer.createPlayerRank(nextRank); } else { From 3e5ce05e880e0e4367ee1938d33bde3963b8518a Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 22 Jun 2024 23:35:15 -0400 Subject: [PATCH 022/323] Auto and manual smelting: List all possible smelting conditions. Should provide a similar list for blocking. This list shows what manual settings will effect the actual blocks, since one setting can control multiple blocks. --- docs/changelog_v3.3.x.md | 4 ++ .../autofeatures/AutoManagerFeatures.java | 61 +++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index a5f3fe77e..5776282b3 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.18a 2024-06-22 +* **Auto and manual smelting: List all possible smelting conditions.** +Should provide a similar list for blocking. This list shows what manual settings will effect the actual blocks, since one setting can control multiple blocks. + + * **Rankup and Presetige: Fixed a bug where when prestiging for the first time that it was taking the cost of the default ladder's first rank (generally zero value).** This now uses the correct ladder based upon which ladder is being targeted for the rankup or prestige. 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 50b30921f..61b90adac 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 @@ -2274,6 +2274,67 @@ else if ( sItemStack.getMaterial() != null ) { for ( XMaterial source : keys ) { SpigotItemStack drop = xMats.get( source ); + // smeltCobblestone: + // cCobblestone : stone + // smeltGoldOre: + // gold_ore : gold_ingot + // nether_gold_ore : gold_ingot + // deepslate_gold_ore : gold_ingot + // raw_gold : gold_ingot + // smeltIronOre: + // iron_ore : iron_ingot + // deepslate_iron_ore : iron_ingot + // raw_iron : iron__ingot + // smeltCoalOre: + // coal_ore: coal + // deeplate_core__ore : coal + // smeltDiamondlOre: + // diamond_ore : diamond + // deepslate_diamon_ore : diamond + // smeltEmeraldOre: + // emerald_ore : emerald + // deepslate_emerald_ore : emerald + // smeltLapisOre: + // lapis_ore : lapis_lazuli + // deepslate_lapis_ore : lapis_lazuli + // smeltRedstoneOre: + // redstone_ore : redstone + // deepslate_redstone_ore : redstone + // smeltNetherQuartzOre: + // nether_quartz__ore : quartz + // smeltAncientDebris: + // ancient_debris : netherite_scrap + // smeltCopperOre: + // copper_ore : copper_ingot + // deepslate_copper_ore : copper_ingot + // raw_copper : copper_ingot + + // No smelting: + // stone : smooth stone + // stone_bricks : cracked_stone_bricks + // cobbled_deepslate : deepslate + // deepslate_bricks : cracked_deepslate_bricks + // deepslate_tiles : cracked_deepslate_tiles + // sandstone : smooth_red_sandstone + // red_sandstone : smooth_red_sandstone + // nether_bricks : cracked_nether_bricks + // basalt : smooth_basalt + // polished_blackstone_bricks : cracked_polished_blackstone_bricks + // block_of_quartz : smooth_quartz + // clay : terracotta + // dyed terracotta : glazed_terracotta + // sand : glass + // wet_sponge : sponge + // log : charcoal + // wood : charcoal + // stripped_log : charcoal + // stripped_wood : charcoal + // chorus_fruit : popped_chorus_fruit + // sea_pickle : lime_dye + // cactus : green_dye + // clay_ball : brick + // netherrack : nether_brick + switch ( source ) { case COBBLESTONE: From f0f6361402583394a0ae86cb4a755fbd6178a0ab Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 23 Jun 2024 01:38:50 -0400 Subject: [PATCH 023/323] Upgraded nbtApi to v2.13.1 from v2.12.4. This better supports spigot 1.21.x. --- docs/changelog_v3.3.x.md | 3 +++ gradle/libs.versions.toml | 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 5776282b3..e6dc86de9 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -16,6 +16,9 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.18a 2024-06-22 +* **Upgraded nbtApi to v2.13.1 from v2.12.4.** +This better supports spigot 1.21.x. + * **Auto and manual smelting: List all possible smelting conditions.** Should provide a similar list for blocking. This list shows what manual settings will effect the actual blocks, since one setting can control multiple blocks. diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4c8c7ce8e..31462e4ef 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -13,6 +13,12 @@ # https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 # https://mvnrepository.com/artifact/com.google.guava/guava # +## NOTE: mavenrepository.com is not the offical repo. +## NOTE: This item-nbt MUST use the API and not the plugin version! +## Good: https://repo.codemc.io/service/rest/repository/browse/maven-public/de/tr7zw/item-nbt-api/ +## Bad?: https://repo.codemc.io/service/rest/repository/browse/maven-public/de/tr7zw/item-nbt-api-plugin/2.11.3/ + + # Note: papi has two possible URLs: The second one is the offical but the repo does not work well. # com.github.placeholderapi:placeholderapi # me.clip:placeholderapi @@ -33,7 +39,7 @@ junit = "4.12" guava = "31.1-jre" spigotApi = "1.13.2-R0.1-SNAPSHOT" -nbtApi = "2.12.4" +nbtApi = "2.13.1" papi = "2.11.5" vault = "1.7.1" From e06b49f1d83d2e9471b3ccd4c6bcc5146c1ab3c2 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 23 Jun 2024 01:42:16 -0400 Subject: [PATCH 024/323] Prison nbtApi: Found an issue when a newer version of spigot broke the functionality of the nbtApi library, it was causing failures in prison. Made changes to prevent an nbt failure from causing prison to fail. Provided new controls to log a simple error message, but still enable the rest of the prison's functions to work. The under laying problem was with a 3rd party library and not prison. But this fix allows prison to better handle when future of versions of spigot may break things again. --- docs/changelog_v3.3.x.md | 6 ++ .../prison/spigot/nbt/PrisonNBTUtil.java | 91 ++++++++++++++----- 2 files changed, 74 insertions(+), 23 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index e6dc86de9..79fb9ddbd 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.18a 2024-06-22 + +* **Prison nbtApi: Found an issue when a newer version of spigot broke the functionality of the nbtApi library, it was causing failures in prison.** +Made changes to prevent an nbt failure from causing prison to fail. Provided new controls to log a simple error message, but still enable the rest of the prison's functions to work. +The under laying problem was with a 3rd party library and not prison. But this fix allows prison to better handle when future of versions of spigot may break things again. + + * **Upgraded nbtApi to v2.13.1 from v2.12.4.** This better supports spigot 1.21.x. 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 ed4edbff0..73bc6bbf6 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 @@ -46,10 +46,19 @@ public static boolean hasNBTString( ItemStack bukkitStack, String key ) { public static String getNBTString( ItemStack bukkitStack, String key ) { String results = null; - Function gsFnc = nbt -> nbt.getString(key); - - results = NBT.get(bukkitStack, gsFnc ); -// results = NBT.get(bukkitStack, nbt -> nbt.getString(key)); + try { + Function gsFnc = nbt -> nbt.getString(key); + + results = NBT.get(bukkitStack, gsFnc ); +// results = NBT.get(bukkitStack, nbt -> nbt.getString(key)); + } + catch (Exception e) { + Output.get().logInfo( + "PrisonNBTUtil.getNBTString(): Failure trying to use NBTs. " + + "Contact prison support. The NBT library may need to be updated. [%s]", + e.getMessage() + ); + } return results; } @@ -57,45 +66,81 @@ public static String getNBTString( ItemStack bukkitStack, String key ) { public static String getNBTString( Block bukkitBlock, String key ) { String results = null; - Function gsFnc = nbt -> nbt.getString(key); - - BlockState blockState = bukkitBlock.getState(); - - results = NBT.get(blockState, gsFnc ); + try { + Function gsFnc = nbt -> nbt.getString(key); + + BlockState blockState = bukkitBlock.getState(); + + results = NBT.get(blockState, gsFnc ); + } + catch (Exception e) { + Output.get().logInfo( + "PrisonNBTUtil.getNBTString(block): Failure trying to use NBTs. " + + "Contact prison support. The NBT library may need to be updated. [%s]", + e.getMessage() + ); + } return results; } public static void setNBTString( ItemStack bukkitStack, String key, String value ) { - NBT.modify(bukkitStack, nbt -> { - nbt.setString(key, value); - }); - - if ( isEnableDebugLogging() ) { - nbtDebugLog( bukkitStack, "setNBTString" ); + try { + NBT.modify(bukkitStack, nbt -> { + nbt.setString(key, value); + }); + + if ( isEnableDebugLogging() ) { + nbtDebugLog( bukkitStack, "setNBTString" ); + } + } + catch (Exception e) { + Output.get().logInfo( + "PrisonNBTUtil.setNBTString(): Failure trying to use NBTs. " + + "Contact prison support. The NBT library may need to be updated. [%s]", + e.getMessage() + ); } } public static boolean getNBTBoolean( ItemStack bukkitStack, String key ) { boolean results = false; - Function gbFnc = nbt -> nbt.getBoolean(key); + try { + Function gbFnc = nbt -> nbt.getBoolean(key); - results = NBT.get(bukkitStack, gbFnc ); + results = NBT.get(bukkitStack, gbFnc ); // results = NBT.get(bukkitStack, nbt -> nbt.getBoolean(key)); + } + catch (Exception e) { + Output.get().logInfo( + "PrisonNBTUtil.getNBTBoolean(): Failure trying to use NBTs. " + + "Contact prison support. The NBT library may need to be updated. [%s]", + e.getMessage() + ); + } return results; } public static void setNBTBoolean( ItemStack bukkitStack, String key, boolean value ) { - NBT.modify(bukkitStack, nbt -> { - nbt.setBoolean(key, value); - }); - - if ( isEnableDebugLogging() ) { - nbtDebugLog( bukkitStack, "setNBTBoolean" ); + try { + NBT.modify(bukkitStack, nbt -> { + nbt.setBoolean(key, value); + }); + + if ( isEnableDebugLogging() ) { + nbtDebugLog( bukkitStack, "setNBTBoolean" ); + } + } + catch (Exception e) { + Output.get().logInfo( + "PrisonNBTUtil.setNBTBoolean(): Failure trying to use NBTs. " + + "Contact prison support. The NBT library may need to be updated. [%s]", + e.getMessage() + ); } } From 6c3e63fe8fa23cd218faa9541d5800de580ef584 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 23 Jun 2024 01:44:29 -0400 Subject: [PATCH 025/323] v3.3.0-alpha.18b 2024-06-23 --- 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 79fb9ddbd..4f8bf7e59 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.18a 2024-06-22 +# 3.3.0-alpha.18b 2024-06-22 + + +** v3.3.0-alpha.18b 2024-06-23** * **Prison nbtApi: Found an issue when a newer version of spigot broke the functionality of the nbtApi library, it was causing failures in prison.** diff --git a/gradle.properties b/gradle.properties index 94e87c1b7..1235bab9f 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.18a +version=3.3.0-alpha.18b From be53c42c37b92c9db877994476a6700de2a73c14 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 28 Jun 2024 03:07:22 -0400 Subject: [PATCH 026/323] ranks ladder moveRank: Added the ability to remove a rank from a ladder. This was not possible before, but yet prison would temporarily disconnect a rank from a ladder before assigning it to another ladder. It should be noted that ranks should always be tied to a ladder, so this is mostly used for testing purposes. --- docs/changelog_v3.3.x.md | 7 ++++++- .../prison/ranks/commands/LadderCommands.java | 19 +++++++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 4f8bf7e59..bf1ed201f 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.18b 2024-06-22 +# 3.3.0-alpha.18b 2024-06-28 + + +* **ranks ladder moveRank: Added the ability to remove a rank from a ladder.** +This was not possible before, but yet prison would temporarily disconnect a rank from a ladder before assigning it to another ladder. +It should be noted that ranks should always be tied to a ladder, so this is mostly used for testing purposes. ** v3.3.0-alpha.18b 2024-06-23** 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 a5e73fa1f..2669bbed3 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 @@ -255,7 +255,9 @@ public ChatDisplay getLadderList() { "ladder position or a new ladder.", onlyPlayers = false, permissions = "ranks.ladder") public void ladderMoveRank(CommandSender sender, - @Arg(name = "ladderName") String ladderName, + @Arg(name = "ladderName", + description = "Use a valid ladder name, or '*no-ladder*' " + + "to remove the ladder.") String ladderName, @Arg(name = "rankName") String rankName, @Arg(name = "position", def = "0", verifiers = "min[0]", description = "Position where you want the rank to be moved to. " + @@ -264,7 +266,13 @@ public void ladderMoveRank(CommandSender sender, ladderMoveRankNoticeMsg( sender ); ladderRemoveRank( sender, rankName ); - ladderAddRank(sender, ladderName, rankName, position ); + + // If '*no-ladder*' then don't try to reassign it to another ladder: + if ( !ladderName.equalsIgnoreCase( "*no-ladder*" ) ) { + + ladderAddRank(sender, ladderName, rankName, position ); + } + } // @Command(identifier = "ranks ladder addrank", description = "Adds a rank to a ladder, or move a rank.", @@ -342,7 +350,14 @@ public void ladderRemoveRank(CommandSender sender, RankLadder ladder = rank.getLadder(); + if ( ladder == null ) { + Output.get().logInfo( + "The rank %s has no ladder, so ladder cannot be removed.", + rank.getName() ); + return; + } ladder.removeRank( rank ); + // ladder.removeRank(ladder.getPositionOfRank(rank)); if ( PrisonRanks.getInstance().getLadderManager().save(ladder) ) { From 77fbf35614f8c1f77f67392d105bffb7f662a069 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 28 Jun 2024 03:11:57 -0400 Subject: [PATCH 027/323] sellall multiplier add to many ranks: new feature to add (replace) a rank multiplier and have it apply that value to all higher ranks until the end of the ladder or until it hits another rank with a multiplier. So if you have p10 and p20 setup and want to fill in p11 through p19, you can use this command by reading p10 with this new option and it will apply the multiplier through p19. --- docs/changelog_v3.3.x.md | 4 +++ .../commands/PrisonSpigotSellAllCommands.java | 17 ++++++++-- .../prison/spigot/sellall/SellAllUtil.java | 34 ++++++++++++++----- 3 files changed, 45 insertions(+), 10 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index bf1ed201f..86eab6233 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.18b 2024-06-28 +* **sellall multiplier add to many ranks: new feature to add (replace) a rank multiplier and have it apply that value to all higher ranks until the end of the ladder or until it hits another rank with a multiplier.** +So if you have p10 and p20 setup and want to fill in p11 through p19, you can use this command by reading p10 with this new option and it will apply the multiplier through p19. + + * **ranks ladder moveRank: Added the ability to remove a rank from a ladder.** This was not possible before, but yet prison would temporarily disconnect a rank from a ladder before assigning it to another ladder. It should be noted that ranks should always be tied to a ladder, so this is mostly used for testing purposes. 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 73e671b1b..fda4f23e3 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 @@ -1278,6 +1278,9 @@ else if ( tryLowerCase ) { "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. " + + "Please note that sellall rank multiplers will NOT apply to higher ranks. " + + "If there is a sellall rank multiplier for P1 and not P2, and when the player ranks " + + "up to P2, they will not get the multiplier from P1. " + "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 " @@ -1289,7 +1292,15 @@ else if ( tryLowerCase ) { permissions = "prison.admin", onlyPlayers = false) 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) { + @Arg(name = "multiplier", description = "Multiplier value.") Double multiplier, + @Arg(name = "options", def = "Use '*applyToHigherRanks*' to copy this " + + "multipler to all higher ranks above this rank. This will apply the multipler " + + "through to the last rank, or until it hits a higher rank that already has a " + + "multipler defined. Example: If you have a multiplier set for P20 and you " + + "add one at P10 with this option enabled, then P11 through P19 will get the " + + "same multiplier that is given to P10.", + description = "") String options + ) { if (!isEnabled() ) { return; @@ -1301,7 +1312,9 @@ private void sellAllAddMultiplierCommand(CommandSender sender, return; } - if (sellAllUtil.addSellallRankMultiplier(rank, multiplier)){ + boolean applyToHigherRanks = options != null && "*applyToHigherRanks*".equalsIgnoreCase(options); + + if (sellAllUtil.addSellallRankMultiplier(rank, multiplier, applyToHigherRanks)){ Output.get().sendInfo(sender, messages.getString(MessagesConfig.StringID.spigot_message_sellall_multiplier_add_success)); } else { 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 efd508489..8634f98b0 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 @@ -1478,6 +1478,9 @@ public boolean addSellAllBlock(XMaterial xMaterial, String displayName, double v // return addSellAllBlock(XMaterial.matchXMaterial(material), value); // } + public boolean addSellallRankMultiplier(String rankName, double multiplier){ + return addSellallRankMultiplier(rankName, multiplier, false); + } /** * Add Multiplier to SellAll depending on the Rank (Rank from any ladder). * @@ -1485,10 +1488,11 @@ public boolean addSellAllBlock(XMaterial xMaterial, String displayName, double v * * @param rankName - Name of the Rank as String. * @param multiplier - Double value. + * @param applyToHigherRanks * * @return boolean. * */ - public boolean addSellallRankMultiplier(String rankName, double multiplier){ + public boolean addSellallRankMultiplier(String rankName, double multiplier, boolean applyToHigherRanks){ PrisonRanks rankPlugin = (PrisonRanks) (Prison.get().getModuleManager() == null ? null : Prison.get().getModuleManager().getModule(PrisonRanks.MODULE_NAME) ); @@ -1523,14 +1527,17 @@ public boolean addSellallRankMultiplier(String rankName, double multiplier){ File sellAllFile = new File(SpigotPrison.getInstance().getDataFolder() + "/SellAllConfig.yml"); FileConfiguration conf = YamlConfiguration.loadConfiguration(sellAllFile); - if ( rank.getLadder().isPrestiges() ) { - conf.set("Multiplier." + rank.getName() + ".PRESTIGE_NAME", rank.getName()); - } - else { - conf.set("Multiplier." + rank.getName() + ".RANK_NAME", rank.getName()); - } + setRankMultiplier(rank, multiplier, conf); - conf.set("Multiplier." + rank.getName() + ".MULTIPLIER", multiplier); + if ( applyToHigherRanks ) { + + Rank nextRank = rank.getRankNext(); + while ( nextRank != null && !getPrestigeMultipliers().containsKey(nextRank.getName()) ) { + + setRankMultiplier(nextRank, multiplier, conf); + nextRank = nextRank.getRankNext(); + } + } conf.save(sellAllFile); } @@ -1545,6 +1552,17 @@ public boolean addSellallRankMultiplier(String rankName, double multiplier){ return true; } + private void setRankMultiplier(Rank rank, double multiplier, FileConfiguration conf) { + 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); + } + /** * Add SellAll Item Trigger. * From b1aa99a1729e9018ad81e02b306ae11028a5f2d0 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 29 Jun 2024 14:44:57 -0400 Subject: [PATCH 028/323] Mine bombs: Setup a better system to validate mine bombs when creating the defaults and when loading from the save file. Now if a mine bomb effect is not valid for that version of bukkit/spigot, it will not be included in the mine bomb so this will eliminate the startup error messages. --- .../mcprison/prison/bombs/MineBombData.java | 21 +++ .../bombs/MineBombDefaultConfigSettings.java | 142 +++++++++--------- .../prison/bombs/MineBombEffectsData.java | 60 +++++++- .../tech/mcprison/prison/bombs/MineBombs.java | 3 + .../prison/bombs/MineBombsConfigData.java | 23 +++ .../prison/internal/platform/Platform.java | 4 + .../tech/mcprison/prison/TestPlatform.java | 5 + .../prison/bombs/MineBombEffectsDataTest.java | 5 + .../prison/spigot/SpigotPlatform.java | 21 +++ .../spigot/utils/PrisonUtilsMineBombs.java | 77 ++++++++++ 10 files changed, 282 insertions(+), 79 deletions(-) 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 b31b7169f..97d91d60f 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 @@ -4,6 +4,8 @@ import java.util.List; import java.util.TreeSet; +import tech.mcprison.prison.Prison; +import tech.mcprison.prison.bombs.MineBombEffectsData.EffectType; import tech.mcprison.prison.internal.block.Block; import tech.mcprison.prison.internal.block.PrisonBlock; @@ -558,6 +560,16 @@ public void setApplyToPlayersBlockCount(boolean applyToPlayersBlockCount) { this.applyToPlayersBlockCount = applyToPlayersBlockCount; } + + public void addSoundEffects( MineBombEffectsData effect ) { + effect.setEffectType( EffectType.sounds ); + + Prison.get().getPlatform().validateMineBombEffect( effect ); + + if ( effect.isValid() ) { + getSoundEffects().add(effect); + } + } public TreeSet getSoundEffects() { return soundEffects; } @@ -565,6 +577,15 @@ public void setSoundEffects( TreeSet soundEffects ) { this.soundEffects = soundEffects; } + public void addVisualEffects( MineBombEffectsData effect ) { + effect.setEffectType( EffectType.visuals ); + + Prison.get().getPlatform().validateMineBombEffect( effect ); + + if ( effect.isValid() ) { + getVisualEffects().add(effect); + } + } public TreeSet getVisualEffects() { return visualEffects; } 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 ef03e2c9b..1ed2f295b 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 @@ -63,16 +63,16 @@ public void setupDefaultMineBombData(MineBombs mineBombs) mbd.getLore().add( "&4Lore line 2" ); mbd.getLore().add( "&aLore line &73" ); - mbd.getSoundEffects().add( mbeSound01.clone() ); - mbd.getSoundEffects().add( mbeSound02.clone().setOffsetTicks( 30 ) ); - mbd.getSoundEffects().add( mbeSound03.clone() ); + mbd.addSoundEffects( mbeSound01.clone() ); + mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 30 ) ); + mbd.addSoundEffects( mbeSound03.clone() ); - mbd.getVisualEffects().add( mbeExplode04.clone() ); - mbd.getVisualEffects().add( mbeExplode03.clone().setOffsetTicks( 30 ) ); + mbd.addVisualEffects( mbeExplode04.clone() ); + mbd.addVisualEffects( mbeExplode03.clone().setOffsetTicks( 30 ) ); - mbd.getVisualEffects().add( mbeExplode06a.clone() ); - mbd.getVisualEffects().add( mbeExplode10.clone() ); - mbd.getVisualEffects().add( mbeExplode06.clone() ); + mbd.addVisualEffects( mbeExplode06a.clone() ); + mbd.addVisualEffects( mbeExplode10.clone() ); + mbd.addVisualEffects( mbeExplode06.clone() ); mbd.setCooldownTicks( 10 ); @@ -92,15 +92,15 @@ public void setupDefaultMineBombData(MineBombs mineBombs) mbd.setToolInHandName( "DIAMOND_PICKAXE" ); mbd.setToolInHandFortuneLevel( 3 ); - mbd.getSoundEffects().add( mbeSound01.clone() ); - mbd.getSoundEffects().add( mbeSound02.clone().setOffsetTicks( 30 ) ); - mbd.getSoundEffects().add( mbeSound03.clone() ); + mbd.addSoundEffects( mbeSound01.clone() ); + mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 30 ) ); + mbd.addSoundEffects( mbeSound03.clone() ); - mbd.getVisualEffects().add( mbeExplode04.clone() ); - mbd.getVisualEffects().add( mbeExplode03.clone().setOffsetTicks( 30 ) ); + mbd.addVisualEffects( mbeExplode04.clone() ); + mbd.addVisualEffects( mbeExplode03.clone().setOffsetTicks( 30 ) ); - mbd.getVisualEffects().add( mbeExplode10.clone() ); - mbd.getVisualEffects().add( mbeExplode06.clone() ); + mbd.addVisualEffects( mbeExplode10.clone() ); + mbd.addVisualEffects( mbeExplode06.clone() ); mbd.setCooldownTicks( 60 ); @@ -121,16 +121,16 @@ public void setupDefaultMineBombData(MineBombs mineBombs) mbd.setToolInHandName( "DIAMOND_PICKAXE" ); mbd.setToolInHandFortuneLevel( 3 ); - mbd.getSoundEffects().add( mbeSound01.clone() ); - mbd.getSoundEffects().add( mbeSound02.clone().setOffsetTicks( 30 ) ); - mbd.getSoundEffects().add( mbeSound03.clone().setVolumne( 2.0f ) ); + mbd.addSoundEffects( mbeSound01.clone() ); + mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 30 ) ); + mbd.addSoundEffects( mbeSound03.clone().setVolumne( 2.0f ) ); - mbd.getVisualEffects().add( mbeExplode04.clone() ); - mbd.getVisualEffects().add( mbeExplode03.clone().setOffsetTicks( 30 ) ); + mbd.addVisualEffects( mbeExplode04.clone() ); + mbd.addVisualEffects( mbeExplode03.clone().setOffsetTicks( 30 ) ); - mbd.getVisualEffects().add( mbeExplode10.clone() ); - mbd.getVisualEffects().add( mbeExplode06.clone() ); - mbd.getVisualEffects().add( mbeExplode06a.clone() ); + mbd.addVisualEffects( mbeExplode10.clone() ); + mbd.addVisualEffects( mbeExplode06.clone() ); + mbd.addVisualEffects( mbeExplode06a.clone() ); mbd.setCooldownTicks( 60 ); @@ -151,38 +151,38 @@ public void setupDefaultMineBombData(MineBombs mineBombs) mbd.setToolInHandName( "GOLDEN_PICKAXE" ); mbd.setToolInHandFortuneLevel( 13 ); - mbd.getSoundEffects().add( mbeSound01.clone() ); - mbd.getSoundEffects().add( mbeSound02.clone().setOffsetTicks( 10 ).setVolumne( 0.25f ).setPitch( 0.25f ) ); - mbd.getSoundEffects().add( mbeSound02.clone().setOffsetTicks( 20 ).setVolumne( 0.5f ).setPitch( 0.5f ) ); - mbd.getSoundEffects().add( mbeSound02.clone().setOffsetTicks( 30 ).setVolumne( 1.0f ).setPitch( 0.75f ) ); - mbd.getSoundEffects().add( mbeSound02.clone().setOffsetTicks( 40 ).setVolumne( 2.0f ).setPitch( 1.5f ) ); - mbd.getSoundEffects().add( mbeSound02.clone().setOffsetTicks( 50 ).setVolumne( 5.0f ).setPitch( 2.5f ) ); - - mbd.getSoundEffects().add( mbeSound03.clone().setOffsetTicks( 0 ).setVolumne( 3.0f ) ); - mbd.getSoundEffects().add( mbeSound04.clone().setOffsetTicks( 5 ).setVolumne( 1.5f ) ); - mbd.getSoundEffects().add( mbeSound03.clone().setOffsetTicks( 10 ).setVolumne( 2.5f ) ); - mbd.getSoundEffects().add( mbeSound04.clone().setOffsetTicks( 15 ).setVolumne( 1.0f ) ); - mbd.getSoundEffects().add( mbeSound03.clone().setOffsetTicks( 20 ).setVolumne( 2.0f ) ); - mbd.getSoundEffects().add( mbeSound04.clone().setOffsetTicks( 25 ).setVolumne( 0.75f ) ); - mbd.getSoundEffects().add( mbeSound03.clone().setOffsetTicks( 30 ).setVolumne( 1.5f ) ); - mbd.getSoundEffects().add( mbeSound04.clone().setOffsetTicks( 35 ).setVolumne( 0.55f ) ); - mbd.getSoundEffects().add( mbeSound03.clone().setOffsetTicks( 40 ).setVolumne( 1.0f ) ); - mbd.getSoundEffects().add( mbeSound04.clone().setOffsetTicks( 45 ).setVolumne( 0.25f ) ); - mbd.getSoundEffects().add( mbeSound03.clone().setOffsetTicks( 50 ).setVolumne( 0.5f ) ); - mbd.getSoundEffects().add( mbeSound04.clone().setOffsetTicks( 55 ).setVolumne( 0.15f ) ); - - - mbd.getVisualEffects().add( mbeExplode06.clone() ); - mbd.getVisualEffects().add( mbeExplode06a.clone() ); - mbd.getVisualEffects().add( mbeExplode03.clone() ); - mbd.getVisualEffects().add( mbeExplode12.clone() ); - mbd.getVisualEffects().add( mbeExplode12.clone().setOffsetTicks( 30 ) ); - mbd.getVisualEffects().add( mbeExplode12.clone().setOffsetTicks( 60 ) ); - mbd.getVisualEffects().add( mbeExplode07.clone().setOffsetTicks( 60 ) ); - mbd.getVisualEffects().add( mbeExplode08.clone().setOffsetTicks( 90 ) ); - - mbd.getVisualEffects().add( mbeExplode10.clone() ); - mbd.getVisualEffects().add( mbeExplode06.clone().setOffsetTicks( 20 ) ); + mbd.addSoundEffects( mbeSound01.clone() ); + mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 10 ).setVolumne( 0.25f ).setPitch( 0.25f ) ); + mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 20 ).setVolumne( 0.5f ).setPitch( 0.5f ) ); + mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 30 ).setVolumne( 1.0f ).setPitch( 0.75f ) ); + mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 40 ).setVolumne( 2.0f ).setPitch( 1.5f ) ); + mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 50 ).setVolumne( 5.0f ).setPitch( 2.5f ) ); + + mbd.addSoundEffects( mbeSound03.clone().setOffsetTicks( 0 ).setVolumne( 3.0f ) ); + mbd.addSoundEffects( mbeSound04.clone().setOffsetTicks( 5 ).setVolumne( 1.5f ) ); + mbd.addSoundEffects( mbeSound03.clone().setOffsetTicks( 10 ).setVolumne( 2.5f ) ); + mbd.addSoundEffects( mbeSound04.clone().setOffsetTicks( 15 ).setVolumne( 1.0f ) ); + mbd.addSoundEffects( mbeSound03.clone().setOffsetTicks( 20 ).setVolumne( 2.0f ) ); + mbd.addSoundEffects( mbeSound04.clone().setOffsetTicks( 25 ).setVolumne( 0.75f ) ); + mbd.addSoundEffects( mbeSound03.clone().setOffsetTicks( 30 ).setVolumne( 1.5f ) ); + mbd.addSoundEffects( mbeSound04.clone().setOffsetTicks( 35 ).setVolumne( 0.55f ) ); + mbd.addSoundEffects( mbeSound03.clone().setOffsetTicks( 40 ).setVolumne( 1.0f ) ); + mbd.addSoundEffects( mbeSound04.clone().setOffsetTicks( 45 ).setVolumne( 0.25f ) ); + mbd.addSoundEffects( mbeSound03.clone().setOffsetTicks( 50 ).setVolumne( 0.5f ) ); + mbd.addSoundEffects( mbeSound04.clone().setOffsetTicks( 55 ).setVolumne( 0.15f ) ); + + + mbd.addVisualEffects( mbeExplode06.clone() ); + mbd.addVisualEffects( mbeExplode06a.clone() ); + mbd.addVisualEffects( mbeExplode03.clone() ); + mbd.addVisualEffects( mbeExplode12.clone() ); + mbd.addVisualEffects( mbeExplode12.clone().setOffsetTicks( 30 ) ); + mbd.addVisualEffects( mbeExplode12.clone().setOffsetTicks( 60 ) ); + mbd.addVisualEffects( mbeExplode07.clone().setOffsetTicks( 60 ) ); + mbd.addVisualEffects( mbeExplode08.clone().setOffsetTicks( 90 ) ); + + mbd.addVisualEffects( mbeExplode10.clone() ); + mbd.addVisualEffects( mbeExplode06.clone().setOffsetTicks( 20 ) ); mbd.setAutosell( true ); mbd.setGlowing( true ); @@ -226,19 +226,19 @@ public void setupDefaultMineBombData(MineBombs mineBombs) 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() ); + mbd.addSoundEffects( mbeSound01.clone() ); + mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 30 ) ); + mbd.addSoundEffects( mbeSound03.clone() ); - mbd.getVisualEffects().add( mbeExplode01.clone() ); - mbd.getVisualEffects().add( mbeExplode02.clone().setOffsetTicks( 30 ) ); - mbd.getVisualEffects().add( mbeExplode03.clone().setOffsetTicks( 10 ) ); - mbd.getVisualEffects().add( mbeExplode04.clone() ); + mbd.addVisualEffects( mbeExplode01.clone() ); + mbd.addVisualEffects( mbeExplode02.clone().setOffsetTicks( 30 ) ); + mbd.addVisualEffects( mbeExplode03.clone().setOffsetTicks( 10 ) ); + mbd.addVisualEffects( mbeExplode04.clone() ); - mbd.getVisualEffects().add( mbeExplode10.clone() ); - mbd.getVisualEffects().add( mbeExplode06.clone() ); - mbd.getVisualEffects().add( mbeExplode06a.clone() ); - mbd.getVisualEffects().add( mbeExplode11.clone().setOffsetTicks( 05 ) ); + mbd.addVisualEffects( mbeExplode10.clone() ); + mbd.addVisualEffects( mbeExplode06.clone() ); + mbd.addVisualEffects( mbeExplode06a.clone() ); + mbd.addVisualEffects( mbeExplode11.clone().setOffsetTicks( 05 ) ); mbd.setCooldownTicks( 3 * 20 ); // 3 seconds mbd.setFuseDelayTicks( 2 * 20 ); // 2 seconds @@ -266,12 +266,12 @@ public void setupDefaultMineBombData(MineBombs mineBombs) mbd.setToolInHandFortuneLevel( 7 ); mbd.setRemovalChance( 100.0d ); - mbd.getSoundEffects().add( mbeSound01.clone() ); - mbd.getSoundEffects().add( mbeSound02.clone().setOffsetTicks( 30 ) ); - mbd.getSoundEffects().add( mbeSound03.clone() ); + mbd.addSoundEffects( mbeSound01.clone() ); + mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 30 ) ); + mbd.addSoundEffects( mbeSound03.clone() ); - mbd.getVisualEffects().add( mbeExplode04.clone() ); - mbd.getVisualEffects().add( mbeExplode02.clone().setOffsetTicks( 30 ) ); + mbd.addVisualEffects( mbeExplode04.clone() ); + mbd.addVisualEffects( mbeExplode02.clone().setOffsetTicks( 30 ) ); mbd.setGlowing( true ); diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombEffectsData.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombEffectsData.java index 21e9a5b44..e444dd1b9 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombEffectsData.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombEffectsData.java @@ -23,6 +23,8 @@ public class MineBombEffectsData Comparable { + private EffectType effectType; + private String effectName; private EffectState effectState; @@ -32,6 +34,14 @@ public class MineBombEffectsData private float volumne; private float pitch; + private transient boolean valid; + + + public enum EffectType { + sounds, + visuals; + } + public enum EffectState { placed, explode, @@ -40,22 +50,30 @@ public enum EffectState { protected MineBombEffectsData() { super(); + + this.valid = true; } - public MineBombEffectsData( String effectName, EffectState effectState, + public MineBombEffectsData( + String effectName, EffectState effectState, int offsetTicks ) { super(); + this.effectType = null; + this.effectName = effectName; this.effectState = effectState; this.offsetTicks = offsetTicks; this.volumne = 1.0f; this.pitch = 1.0f; + + this.valid = true; } - public MineBombEffectsData( String effectName, EffectState effectState, + public MineBombEffectsData( + String effectName, EffectState effectState, int offsetTicks, float volume, float pitch ) { this( effectName, effectState, offsetTicks ); @@ -65,30 +83,42 @@ public MineBombEffectsData( String effectName, EffectState effectState, public MineBombEffectsData clone() { - return new MineBombEffectsData( getEffectName(), getEffectState(), getOffsetTicks(), + MineBombEffectsData cloned = new MineBombEffectsData( + getEffectName(), getEffectState(), getOffsetTicks(), getVolumne(), getPitch() ); + + cloned.setEffectType( getEffectType() ); + cloned.setValid( isValid() ); + + return cloned; } @Override public String toString() { - return getEffectName() + " (state: " + getEffectState().name() + " offset: " + getOffsetTicks() + + return getEffectName() + " (" + getEffectType().name() + + " state: " + getEffectState().name() + " offset: " + getOffsetTicks() + " ticks v: " + getVolumne() + " p: " + getPitch() + ")"; } public String toStringShort() { - return getEffectName() + " (state: " + getEffectState().name() + " offset: " + getOffsetTicks() + + return getEffectName() + " (" + getEffectType().name() + + " state: " + getEffectState().name() + " offset: " + getOffsetTicks() + " ticks)"; } @Override public int compare( MineBombEffectsData o1, MineBombEffectsData o2 ) { - int results = o1.getEffectState().compareTo( o2.getEffectState() ); + int results = o1.getEffectType().compareTo( o2.getEffectType() ); if ( results == 0 ) { - results = Integer.compare( o1.getOffsetTicks(), o2.getOffsetTicks() ); + results = o1.getEffectState().compareTo( o2.getEffectState() ); if ( results == 0 ) { - results = o1.getEffectName().compareTo( o2.getEffectName() ); + results = Integer.compare( o1.getOffsetTicks(), o2.getOffsetTicks() ); + + if ( results == 0 ) { + results = o1.getEffectName().compareTo( o2.getEffectName() ); + } } } return results; @@ -101,6 +131,13 @@ public int compareTo( MineBombEffectsData o ) } + public EffectType getEffectType() { + return effectType; + } + public void setEffectType(EffectType effectType) { + this.effectType = effectType; + } + public String getEffectName() { return effectName; } @@ -144,4 +181,11 @@ public MineBombEffectsData setPitch( float pitch ) { return this; } + public boolean isValid() { + return valid; + } + public void setValid(boolean valid) { + this.valid = valid; + } + } 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 0a1c2e592..9272cf236 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 @@ -164,6 +164,9 @@ public void loadConfigJson() { (MineBombsConfigData) fio.readJsonFile( configFile, getConfigData() ); if ( configs != null ) { + + configs.validateMineBombEffects(); + setConfigData( configs ); if ( configs.getDataFormatVersion() < 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 2f39f4dec..abfe60a2b 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 @@ -1,7 +1,9 @@ package tech.mcprison.prison.bombs; import java.util.Map; +import java.util.Set; import java.util.TreeMap; +import java.util.TreeSet; import tech.mcprison.prison.file.FileIOData; @@ -37,6 +39,27 @@ public void setDataFormatVersion( int dataFormatVersion ) { this.dataFormatVersion = dataFormatVersion; } + public void validateMineBombEffects() { + + Set keys = getBombs().keySet(); + for ( String key : keys ) { + MineBombData bomb = getBombs().get( key ); + + TreeSet sounds = new TreeSet<>( bomb.getSoundEffects() ); + bomb.getSoundEffects().clear(); + for ( MineBombEffectsData sound : sounds ) { + bomb.addSoundEffects( sound ); + } + + TreeSet visuals = new TreeSet<>( bomb.getVisualEffects() ); + bomb.getVisualEffects().clear(); + for ( MineBombEffectsData visual : visuals ) { + bomb.addVisualEffects( visual ); + } + + } + } + public Map getBombs() { return bombs; } 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 d1f88dce2..a0adfb5f1 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 @@ -26,6 +26,7 @@ import java.util.UUID; import tech.mcprison.prison.backpacks.PlayerBackpack; +import tech.mcprison.prison.bombs.MineBombEffectsData; import tech.mcprison.prison.commands.PluginCommand; import tech.mcprison.prison.file.YamlFileIO; import tech.mcprison.prison.internal.CommandSender; @@ -502,4 +503,7 @@ public String autoCreateMineLinerAssignment(ModuleElement eMine, public Map loadYaml(File file); + public MineBombEffectsData validateMineBombEffect(MineBombEffectsData mineBombEffectsData); + + } 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 1ef8451db..85a838815 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/TestPlatform.java +++ b/prison-core/src/test/java/tech/mcprison/prison/TestPlatform.java @@ -30,6 +30,7 @@ import tech.mcprison.prison.PrisonCommand.RegisteredPluginsData; import tech.mcprison.prison.backpacks.PlayerBackpack; +import tech.mcprison.prison.bombs.MineBombEffectsData; import tech.mcprison.prison.commands.PluginCommand; import tech.mcprison.prison.file.FileStorage; import tech.mcprison.prison.file.YamlFileIO; @@ -600,4 +601,8 @@ public String dumpEventListenersPlayerPickupItemEvents() { // TODO Auto-generated method stub return null; } + + public MineBombEffectsData validateMineBombEffect(MineBombEffectsData mineBombEffectsData) { + return mineBombEffectsData; + } } diff --git a/prison-core/src/test/java/tech/mcprison/prison/bombs/MineBombEffectsDataTest.java b/prison-core/src/test/java/tech/mcprison/prison/bombs/MineBombEffectsDataTest.java index e958991ff..40f93a9d5 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/bombs/MineBombEffectsDataTest.java +++ b/prison-core/src/test/java/tech/mcprison/prison/bombs/MineBombEffectsDataTest.java @@ -17,12 +17,17 @@ public final void testCompare() { MineBombEffectsData mbef01 = new MineBombEffectsData("ABC", EffectState.explode, 0 ); + mbef01.setEffectType( EffectType.sounds ); MineBombEffectsData mbef02 = new MineBombEffectsData("XYZ", EffectState.placed, 3 ); + mbef02.setEffectType( EffectType.sounds ); MineBombEffectsData mbef03 = new MineBombEffectsData("BDF", EffectState.finished, 14 ); + mbef03.setEffectType( EffectType.sounds ); MineBombEffectsData mbef04 = new MineBombEffectsData("DEF", EffectState.finished, 0 ); + mbef04.setEffectType( EffectType.sounds ); MineBombEffectsData mbef05 = new MineBombEffectsData("ABC", EffectState.placed, 0 ); + mbef05.setEffectType( EffectType.sounds ); assertEquals( 1, compare( mbef01, mbef02 ) ); 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 491a0e473..9d0492ce4 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 @@ -67,6 +67,7 @@ import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; import tech.mcprison.prison.autofeatures.AutoFeaturesWrapper; import tech.mcprison.prison.backpacks.BackpackEnums.BackpackType; +import tech.mcprison.prison.bombs.MineBombEffectsData; import tech.mcprison.prison.backpacks.PlayerBackpack; import tech.mcprison.prison.chat.FancyMessage; import tech.mcprison.prison.commands.PluginCommand; @@ -143,6 +144,7 @@ import tech.mcprison.prison.spigot.spiget.BluesSpigetSemVerComparator; import tech.mcprison.prison.spigot.util.ActionBarUtil; import tech.mcprison.prison.spigot.util.SpigotYamlFileIO; +import tech.mcprison.prison.spigot.utils.PrisonUtilsMineBombs; import tech.mcprison.prison.spigot.utils.tasks.PlayerAutoRankupTask; import tech.mcprison.prison.store.Storage; import tech.mcprison.prison.util.Bounds.Edges; @@ -3557,4 +3559,23 @@ public Map loadYaml( File file ) { return values; } + + + /** + * This function is used when setting up mine bomb's effects. + * If first checks to see if an effect is valid for the platform's version, + * and if it is, then the effect is marked as valid. + * + * Any invalid effects are not added to the mine bombs. This eliminates and + * runtime errors using invalid effects. + * + */ + public MineBombEffectsData validateMineBombEffect(MineBombEffectsData mineBombEffect ) { + + PrisonUtilsMineBombs mbUtil = PrisonUtilsMineBombs.getInstance(); + + mbUtil.validateMineBommbEffect( mineBombEffect ); + + return mineBombEffect; + } } 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 d66e85304..eb5fa251a 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 @@ -20,6 +20,7 @@ import tech.mcprison.prison.autofeatures.AutoFeaturesWrapper; import tech.mcprison.prison.bombs.MineBombData; import tech.mcprison.prison.bombs.MineBombEffectsData; +import tech.mcprison.prison.bombs.MineBombEffectsData.EffectType; import tech.mcprison.prison.bombs.MineBombs; import tech.mcprison.prison.bombs.MineBombs.ExplosionShape; import tech.mcprison.prison.commands.Arg; @@ -1089,8 +1090,84 @@ public boolean validateMineBombsSpigotVersion() { return results; } + + public void validateMineBommbEffect(MineBombEffectsData mineBombEffect) { + + if ( !isEnableMineBombs() ) { + + Output.get().logInfo( "Prison's utils command mine bombs is disabled in modules.yml." ); + } + else if ( mineBombEffect == null ) { + + Output.get().logInfo( "Prison utils MineBomb: MineBombEffect is null. The specified effects cannot include nulls." ); + } + else { + + switch ( mineBombEffect.getEffectType() ) { + + case sounds: + + { + mineBombEffect.setValid( false ); + + for ( XSound p : XSound.values() ) { + if ( p.name().equalsIgnoreCase( mineBombEffect.getEffectName() ) ) { + mineBombEffect.setValid( true ); + break; + } + } + } + + break; + + case visuals: + + { + mineBombEffect.setValid( false ); + + // 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( mineBombEffect.getEffectName() ) ) { + mineBombEffect.setValid( true ); + break; + } + } + + } + else { + + for ( Particle p : Particle.values() ) { + if ( p.name().equalsIgnoreCase( mineBombEffect.getEffectName() ) ) { + mineBombEffect.setValid( true ); + break; + } + } + } + } + + break; + + default: + break; + } + + if ( mineBombEffect.getEffectType() == EffectType.sounds ) { + + } + if ( mineBombEffect.getEffectType() == EffectType.visuals ) { + + } + } + } + public boolean utilsMineBombsValidate( String mbObjectType, String name ) { From 69b217f7ff814c201da1ea8235dc9d77915a7011 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 29 Jun 2024 14:51:28 -0400 Subject: [PATCH 029/323] Mine Bombs: Added support for an AnimationPattern for the mine bombs. This Animation pattern will control the animation sequence as the bomb is ticking down. --- docs/changelog_v3.3.x.md | 11 ++++++++++- .../mcprison/prison/bombs/MineBombData.java | 14 ++++++++++++++ .../bombs/MineBombDefaultConfigSettings.java | 13 +++++++++++++ .../tech/mcprison/prison/bombs/MineBombs.java | 18 +++++++++++++++++- 4 files changed, 54 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 86eab6233..9e993635d 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.18b 2024-06-28 +# 3.3.0-alpha.18b 2024-06-29 + + +* **Mine Bombs: Added support for an AnimationPattern for the mine bombs.** +This Animation pattern will control the animation sequence as the bomb is ticking down. + + +* **Mine bombs: Setup a better system to validate mine bombs when creating the defaults and when loading from the save file.** +Now if a mine bomb effect is not valid for that version of bukkit/spigot, it will not be included in the mine bomb so this will eliminate the startup error messages. + * **sellall multiplier add to many ranks: new feature to add (replace) a rank multiplier and have it apply that value to all higher ranks until the end of the ladder or until it hits another rank with a multiplier.** 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 97d91d60f..92800059a 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 @@ -6,6 +6,7 @@ import tech.mcprison.prison.Prison; import tech.mcprison.prison.bombs.MineBombEffectsData.EffectType; +import tech.mcprison.prison.bombs.MineBombs.AnimationPattern; import tech.mcprison.prison.internal.block.Block; import tech.mcprison.prison.internal.block.PrisonBlock; @@ -155,6 +156,10 @@ public class MineBombData { private int itemRemovalDelayTicks = 5; // 0.25 seconds + + private AnimationPattern animationPattern = AnimationPattern.infinity; + + /** *

On spigot versions that support it, the bomb, when placed, will glow. * Was introduced with Minecraft 1.9. Applies only to Entities, of which @@ -276,6 +281,8 @@ public MineBombData( String name, String itemType, String explosionShape, this.itemRemovalDelayTicks = 5; + this.animationPattern = AnimationPattern.infinity; + this.glowing = false; this.gravity = true; @@ -518,6 +525,13 @@ public void setItemRemovalDelayTicks( int itemRemovalDelayTicks ) { this.itemRemovalDelayTicks = itemRemovalDelayTicks; } + public AnimationPattern getAnimationPattern() { + return animationPattern; + } + public void setAnimationPattern(AnimationPattern animationPattern) { + this.animationPattern = animationPattern; + } + public boolean isAutosell() { return autosell; } 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 1ed2f295b..00106a082 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 @@ -1,6 +1,7 @@ package tech.mcprison.prison.bombs; import tech.mcprison.prison.bombs.MineBombEffectsData.EffectState; +import tech.mcprison.prison.bombs.MineBombs.AnimationPattern; import tech.mcprison.prison.bombs.MineBombs.ExplosionShape; import tech.mcprison.prison.output.Output; @@ -76,6 +77,8 @@ public void setupDefaultMineBombData(MineBombs mineBombs) mbd.setCooldownTicks( 10 ); + mbd.setAnimationPattern( AnimationPattern.infinity ); + mineBombs.getConfigData().getBombs().put( mbd.getName().toLowerCase(), mbd ); } @@ -103,6 +106,8 @@ public void setupDefaultMineBombData(MineBombs mineBombs) mbd.addVisualEffects( mbeExplode06.clone() ); mbd.setCooldownTicks( 60 ); + + mbd.setAnimationPattern( AnimationPattern.infinity ); mineBombs.getConfigData().getBombs().put( mbd.getName().toLowerCase(), mbd ); @@ -133,6 +138,8 @@ public void setupDefaultMineBombData(MineBombs mineBombs) mbd.addVisualEffects( mbeExplode06a.clone() ); mbd.setCooldownTicks( 60 ); + + mbd.setAnimationPattern( AnimationPattern.infinity ); mineBombs.getConfigData().getBombs().put( mbd.getName().toLowerCase(), mbd ); } @@ -190,6 +197,8 @@ public void setupDefaultMineBombData(MineBombs mineBombs) mbd.setCooldownTicks( 60 ); mbd.setFuseDelayTicks( 13 * 20 ); // 13 seconds + + mbd.setAnimationPattern( AnimationPattern.infinity ); mineBombs.getConfigData().getBombs().put( mbd.getName().toLowerCase(), mbd ); } @@ -248,6 +257,8 @@ public void setupDefaultMineBombData(MineBombs mineBombs) mbd.setCooldownTicks( 5 ); + mbd.setAnimationPattern( AnimationPattern.infinity ); + mineBombs.getConfigData().getBombs().put( mbd.getName().toLowerCase(), mbd ); } @@ -277,6 +288,8 @@ public void setupDefaultMineBombData(MineBombs mineBombs) mbd.setCooldownTicks( 60 ); + mbd.setAnimationPattern( AnimationPattern.infinity ); + mineBombs.getConfigData().getBombs().put( mbd.getName().toLowerCase(), mbd ); } 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 9272cf236..469ca0daf 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 @@ -80,7 +80,23 @@ public enum ExplosionOrientation { full } - private MineBombs() { + + public enum AnimationPattern { + none, + infinity, + bounce, + orbital + + ; + } + + /** + * DO NOT USE! + * This has been set to protected only to be used by + * junit tests! + * DO NOT USE this constructor! + */ + protected MineBombs() { super(); this.configData = new MineBombsConfigData(); From b8d7cb392241d8a984f21bdeb6ce118002f1ce41 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 29 Jun 2024 14:57:09 -0400 Subject: [PATCH 030/323] Mine Bombs: Setup reporting on when validation of bomb effects fail. It's not an error as much as that version of the effect is not supported by the active spigot/paper version the server is running. It's a runtime check. Added unit tests for the conversion of mine bombs to JSON and back to the mine bomb config objects. Added units for cloning that are similar in how it validates what has been cloned and restored from json. --- .../mcprison/prison/bombs/MineBombData.java | 85 ++++++++++++++++++- .../tech/mcprison/prison/bombs/MineBombs.java | 46 +++++++++- .../prison/bombs/MineBombsConfigData.java | 73 +++++++++++++++- .../tech/mcprison/prison/file/JsonFileIO.java | 9 ++ .../prison/bombs/MineBombEffectsDataTest.java | 69 +++++++++++++++ 5 files changed, 272 insertions(+), 10 deletions(-) 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 92800059a..4e6868483 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 @@ -9,8 +9,11 @@ import tech.mcprison.prison.bombs.MineBombs.AnimationPattern; import tech.mcprison.prison.internal.block.Block; import tech.mcprison.prison.internal.block.PrisonBlock; +import tech.mcprison.prison.output.Output; -public class MineBombData { +public class MineBombData + implements Comparable +{ public static final String MINE_BOMB_DEFAULT_ITEM_NAME = "&c-= &7{name}&c =-"; @@ -360,6 +363,52 @@ public MineBombData clone() { return cloned; } + + + + @Override + public int compareTo(MineBombData o) { + int results = 0; + + if ( o == null ) { + results = -1; + } + + results = getName().compareTo( o.getName() ); + + // This is basically used in unit testing and with JSON conversions. + // conversions of numeric values shouldn't be an issue, so do not + // add to this compareTo. + + + if ( results == 0 ) { + + results = getNameTag().compareTo( o.getNameTag() ); + if ( results == 0 ) { + + results = getDescription().compareTo( o.getDescription() ); + if ( results == 0 ) { + + results = getAnimationPattern().compareTo( o.getAnimationPattern() ); + if ( results == 0 ) { + + results = Integer.compare( getSoundEffects().size(), o.getSoundEffects().size() ); + if ( results == 0 ) { + + results = Integer.compare( getVisualEffects().size(), o.getVisualEffects().size()); + if ( results == 0 ) { + + results = getExplosionShape().compareTo( o.getExplosionShape() ); + } + } + } + } + } + } + + return results; + } + public String getName() { return name; @@ -575,7 +624,9 @@ public void setApplyToPlayersBlockCount(boolean applyToPlayersBlockCount) { } - public void addSoundEffects( MineBombEffectsData effect ) { + public boolean addSoundEffects( MineBombEffectsData effect ) { + boolean results = false; + effect.setEffectType( EffectType.sounds ); Prison.get().getPlatform().validateMineBombEffect( effect ); @@ -583,6 +634,19 @@ public void addSoundEffects( MineBombEffectsData effect ) { if ( effect.isValid() ) { getSoundEffects().add(effect); } + else { + String msg = String.format( + "MineBombData.addSoundEffects: Invalid effect. " + + "This effect is not valid for the version of Spigot that you're " + + "running and will be excluded. This is not an error. " + + "MineBomb: %s Effect: [[%s]] ", + getName(), + effect.toString() + ); + Output.get().logInfo( msg ); + results = true; + } + return results; } public TreeSet getSoundEffects() { return soundEffects; @@ -591,7 +655,9 @@ public void setSoundEffects( TreeSet soundEffects ) { this.soundEffects = soundEffects; } - public void addVisualEffects( MineBombEffectsData effect ) { + public boolean addVisualEffects( MineBombEffectsData effect ) { + boolean results = false; + effect.setEffectType( EffectType.visuals ); Prison.get().getPlatform().validateMineBombEffect( effect ); @@ -599,6 +665,19 @@ public void addVisualEffects( MineBombEffectsData effect ) { if ( effect.isValid() ) { getVisualEffects().add(effect); } + else { + String msg = String.format( + "MineBombData.addVisualEffects: Invalid effect. " + + "This effect is not valid for the version of Spigot that you're " + + "running and will be excluded. This is not an error. " + + "MineBomb: %s Effect: [[%s]] ", + getName(), + effect.toString() + ); + Output.get().logInfo( msg ); + results = true; + } + return results; } public TreeSet getVisualEffects() { return visualEffects; 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 469ca0daf..8b1b7472b 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 @@ -14,6 +14,7 @@ import tech.mcprison.prison.util.Text; public class MineBombs + implements Comparable { public static final String MINE_BOMBS_FILE_NAME = "mineBombsConfig.json"; public static final String MINE_BOMBS_PATH_NAME = "module_conf/mines"; @@ -117,6 +118,28 @@ public static MineBombs getInstance() { } return instance; } + + + @Override + public int compareTo(MineBombs o) { + + int results = 0; + + if ( o == null ) { + results = -1; + } + + if ( results == 0 ) { + + MineBombsConfigData cData = getConfigData(); + MineBombsConfigData cDataO = o.getConfigData(); + + results = cData.compareTo( cDataO ); + } + + return results; + } + /** *

This finds a bomb with the given name, and returns a clone. The clone is @@ -152,6 +175,22 @@ public void saveConfigJson() { } + public String toJson() { + JsonFileIO fio = new JsonFileIO( null, null ); + + String json = fio.toString( this ); + + return json; + } + + public static MineBombs fromJson( String json ) { + JsonFileIO fio = new JsonFileIO(); + + MineBombs mBombs = fio.fromString( json, MineBombs.class ); + + return mBombs; + } + public File getConfigFile( JsonFileIO jsonFileIO ) { File path = new File( jsonFileIO.getProjectRootDiretory(), MINE_BOMBS_PATH_NAME ); @@ -181,11 +220,12 @@ public void loadConfigJson() { if ( configs != null ) { - configs.validateMineBombEffects(); + boolean dirty = configs.validateMineBombEffects(); setConfigData( configs ); - if ( configs.getDataFormatVersion() < + if ( dirty || + configs.getDataFormatVersion() < MineBombsConfigData.MINE_BOMB_DATA_FORMAT_VERSION ) { // Need to update the format version then save a new copy of the configs. @@ -200,7 +240,7 @@ public void loadConfigJson() { boolean renamed = configFile.renameTo( backupFile ); - if ( renamed ) { + if ( renamed || dirty ) { configs.setDataFormatVersion( MineBombsConfigData.MINE_BOMB_DATA_FORMAT_VERSION ); fio.saveJsonFile( configFile, configs ); 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 abfe60a2b..99d8f9006 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 @@ -1,5 +1,7 @@ package tech.mcprison.prison.bombs; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; @@ -8,7 +10,8 @@ import tech.mcprison.prison.file.FileIOData; public class MineBombsConfigData - implements FileIOData + implements FileIOData, + Comparable { /** *

If the format of this class, or any other variables and their @@ -19,6 +22,7 @@ public class MineBombsConfigData *

*/ public static final int MINE_BOMB_DATA_FORMAT_VERSION = 3; +// public static final int MINE_BOMB_DATA_FORMAT_VERSION = 4; private int dataFormatVersion = 0; @@ -39,7 +43,8 @@ public void setDataFormatVersion( int dataFormatVersion ) { this.dataFormatVersion = dataFormatVersion; } - public void validateMineBombEffects() { + public boolean validateMineBombEffects() { + boolean results = false; Set keys = getBombs().keySet(); for ( String key : keys ) { @@ -48,16 +53,22 @@ public void validateMineBombEffects() { TreeSet sounds = new TreeSet<>( bomb.getSoundEffects() ); bomb.getSoundEffects().clear(); for ( MineBombEffectsData sound : sounds ) { - bomb.addSoundEffects( sound ); + if ( bomb.addSoundEffects( sound ) && !results ) { + results = true; + } } TreeSet visuals = new TreeSet<>( bomb.getVisualEffects() ); bomb.getVisualEffects().clear(); for ( MineBombEffectsData visual : visuals ) { - bomb.addVisualEffects( visual ); + if ( bomb.addVisualEffects( visual ) && !results ) { + results = true; + } } } + + return results; } public Map getBombs() { @@ -66,4 +77,58 @@ public Map getBombs() { public void setBombs( Map bombs ) { this.bombs = bombs; } + + + /** + * This compareTo function will check to see if the two + * MineBombsConfigData objects have the same number of + * bombs, and they that have the same bomb names. + * + * If the bomb names match, then it compares each bomb. + * + */ + @Override + public int compareTo(MineBombsConfigData o) { + int results = 0; + + if ( o == null ) { + results = -1; + } + + if ( results == 0 ) { + results = Integer.compare( getDataFormatVersion(), o.getDataFormatVersion() ); + + if ( results == 0 ) { + results = Integer.compare( getBombs().size(), o.getBombs().size() ); + + if ( results == 0 ) { + List keys = new ArrayList<>( getBombs().keySet() ); + List keysO = new ArrayList<>( o.getBombs().keySet() ); + + for ( int i = 0; i < keys.size(); i++ ) { + + String key = keys.get(i); + String keyO = keysO.get(i); + + results = key.compareTo(keyO); + + if ( results == 0 ) { + MineBombData mBomb = getBombs().get(key); + MineBombData mBombO = o.getBombs().get(keyO); + + mBomb.compareTo( mBombO ); + } + + if ( results != 0 ) { + break; + } + } + + } + + } + } + + return results; + } } 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 729aedb65..d4ff4f7fd 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 @@ -254,6 +254,15 @@ public String toString( Object obj ) { return json; } + public T fromString( String json, Class klass ) { + + + T obj = getGson().fromJson( json, klass ); + + + return obj; + } + public static FileFilter getPrisonFileFilter() { diff --git a/prison-core/src/test/java/tech/mcprison/prison/bombs/MineBombEffectsDataTest.java b/prison-core/src/test/java/tech/mcprison/prison/bombs/MineBombEffectsDataTest.java index 40f93a9d5..a82400ccf 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/bombs/MineBombEffectsDataTest.java +++ b/prison-core/src/test/java/tech/mcprison/prison/bombs/MineBombEffectsDataTest.java @@ -1,13 +1,21 @@ package tech.mcprison.prison.bombs; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import java.io.File; import java.util.ArrayList; import java.util.List; +import java.util.Set; import java.util.TreeSet; import org.junit.Test; +import tech.mcprison.prison.Prison; +import tech.mcprison.prison.TestPlatform; +import tech.mcprison.prison.internal.platform.Platform; + public class MineBombEffectsDataTest extends MineBombEffectsData { @@ -58,5 +66,66 @@ public final void testCompare() assertEquals( mbef03, testList.get( 4 ) ); } + + @Test + public final void testJson() + { + + Platform platform = new TestPlatform( new File("tempDir"), true ); + Prison.get().setPlatform( platform ); + + + MineBombs mBombs = new MineBombs(); + + // First build the default bombs: + MineBombDefaultConfigSettings defConfigs = new MineBombDefaultConfigSettings(); + defConfigs.setupDefaultMineBombData(mBombs); + + String json = mBombs.toJson(); + + MineBombs mBombsTwo = MineBombs.fromJson(json); + + assertNotNull( mBombs ); + assertNotNull( mBombsTwo ); + + assertEquals( 0, mBombs.compareTo(mBombsTwo )); + +// assertEquals( mBombs, mBombsTwo ); + } + + + @Test + public final void testClone() + { + + Platform platform = new TestPlatform( new File("tempDir"), true ); + Prison.get().setPlatform( platform ); + + + MineBombs mBombs = new MineBombs(); + + // First build the default bombs: + MineBombDefaultConfigSettings defConfigs = new MineBombDefaultConfigSettings(); + defConfigs.setupDefaultMineBombData(mBombs); + + MineBombs mBombsTwo = new MineBombs(); + + Set keys = mBombs.getConfigData().getBombs().keySet(); + for (String key : keys) { + MineBombData mBomb = mBombs.getConfigData().getBombs().get(key); + + mBombsTwo.getConfigData().getBombs().put( + key, mBomb.clone() ); + + } + + assertNotNull( mBombs ); + assertNotNull( mBombsTwo ); + + assertEquals( 0, mBombs.compareTo(mBombsTwo )); + +// assertEquals( mBombs, mBombsTwo ); + } + } From d2208959e60859f2ea3e83e80804dacbc929d526 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 29 Jun 2024 14:57:27 -0400 Subject: [PATCH 031/323] Mine Bombs: Setup reporting on when validation of bomb effects fail. It's not an error as much as that version of the effect is not supported by the active spigot/paper version the server is running. It's a runtime check. Added unit tests for the conversion of mine bombs to JSON and back to the mine bomb config objects. Added units for cloning that are similar in how it validates what has been cloned and restored from json. --- docs/changelog_v3.3.x.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 9e993635d..79bb77b7c 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.18b 2024-06-29 +* **Mine Bombs: Setup reporting on when validation of bomb effects fail. ** It's not an error as much as that version of the effect is not supported by the active spigot/paper version the server is running. It's a runtime check. +**Added unit tests for the conversion of mine bombs to JSON and back to the mine bomb config objects.** **Added units for cloning** that are similar in how it validates what has been cloned and restored from json. + + * **Mine Bombs: Added support for an AnimationPattern for the mine bombs.** This Animation pattern will control the animation sequence as the bomb is ticking down. From 7e6fd95be15535a52b59ed51276c9bad31aaf456 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 29 Jun 2024 14:59:29 -0400 Subject: [PATCH 032/323] Json File IO: Changed how errors are reported. Since the exception message may be null, provided a check and an alternative message instead of just passing a null value to the string formatting parameter. The JSON data can be huge, so only printing the first 500 characters. --- .../main/java/tech/mcprison/prison/file/JsonFileIO.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) 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 d4ff4f7fd..4bbba04df 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 @@ -340,8 +340,11 @@ public FileIOData readJsonFile( File file, FileIOData data ) String message = String.format( "JsonFileIO.readJsonFile: JsonParse failure: file: [%s] " + "error: [%s] json: [%s] ", - file.getAbsoluteFile(), e.getMessage(), - json ); + file.getAbsoluteFile(), + (e.getMessage() == null ? "no-error-message" : e.getMessage()), + (json.length() > 500 ? + json.substring(0, 500) + "... (first 500 chars)" : json ) + .replace("%", "\\%")); Output.get().logError( message ); From 05a4ae441ada0ade5c96483ec1c2b86b279b9bf0 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 29 Jun 2024 15:00:25 -0400 Subject: [PATCH 033/323] Json File IO: Changed how errors are reported. Since the exception message may be null, provided a check and an alternative message instead of just passing a null value to the string formatting parameter. The JSON data can be huge, so only printing the first 500 characters. --- docs/changelog_v3.3.x.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 79bb77b7c..ccf99e77d 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.18b 2024-06-29 +* **Json File IO: Changed how errors are reported.** Since the exception message may be null, provided a check and an alternative message instead of just passing a null value to the string formatting parameter. +The JSON data can be huge, so only printing the first 500 characters. + + * **Mine Bombs: Setup reporting on when validation of bomb effects fail. ** It's not an error as much as that version of the effect is not supported by the active spigot/paper version the server is running. It's a runtime check. **Added unit tests for the conversion of mine bombs to JSON and back to the mine bomb config objects.** **Added units for cloning** that are similar in how it validates what has been cloned and restored from json. From c8bac0ac6c0e813ae6bf9753848bcc5807bbbd63 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 29 Jun 2024 15:02:44 -0400 Subject: [PATCH 034/323] Prison platform: Added a setPlatform function so this can be used for unit testing. The test fixture is the TestPlatform object that is not connect to any spigot runtime. --- docs/changelog_v3.3.x.md | 3 +++ .../src/main/java/tech/mcprison/prison/Prison.java | 11 +++++++++++ 2 files changed, 14 insertions(+) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index ccf99e77d..918521c6e 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.18b 2024-06-29 +* **Prison platform: Added a setPlatform function so this can be used for unit testing.** The test fixture is the TestPlatform object that is not connect to any spigot runtime. + + * **Json File IO: Changed how errors are reported.** Since the exception message may be null, provided a check and an alternative message instead of just passing a null value to the string formatting parameter. The JSON data can be huge, so only printing the first 500 characters. diff --git a/prison-core/src/main/java/tech/mcprison/prison/Prison.java b/prison-core/src/main/java/tech/mcprison/prison/Prison.java index 8c8b4d5a5..3c3e2363a 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/Prison.java +++ b/prison-core/src/main/java/tech/mcprison/prison/Prison.java @@ -768,6 +768,17 @@ public String getName() { public Platform getPlatform() { return platform; } + + /** + * Do not use! + * This is for junit tests only to create and use a test fixture. + * DO NOT USE! + * + * @param platform + */ + public void setPlatform( Platform platform ) { + this.platform = platform; + } /** * Returns the core data folder, which is located at "/plugins/Prison". This contains the From 5d779c93264714e62f14d66d1b7b4145ef020aa6 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 29 Jun 2024 17:40:38 -0400 Subject: [PATCH 035/323] Mine Bombs: Finalizing the validation and hooking in the new AnimationPatterns. Next is to work on adding new animation patterns. --- docs/changelog_v3.3.x.md | 4 +++ .../mcprison/prison/bombs/MineBombData.java | 29 +++++++++++++++++-- .../prison/bombs/MineBombEffectsData.java | 7 +++-- .../tech/mcprison/prison/bombs/MineBombs.java | 16 ++++++++++ 4 files changed, 51 insertions(+), 5 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 918521c6e..0855020ea 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.18b 2024-06-29 +* **Mine Bombs: Finalizing the validation and hooking in the new AnimationPatterns.** +Next is to work on adding new animation patterns. + + * **Prison platform: Added a setPlatform function so this can be used for unit testing.** The test fixture is the TestPlatform object that is not connect to any spigot runtime. 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 4e6868483..35dc20437 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 @@ -159,7 +159,10 @@ public class MineBombData private int itemRemovalDelayTicks = 5; // 0.25 seconds - + /** + *

This setting controls the animation while the bomb counts down. + *

+ */ private AnimationPattern animationPattern = AnimationPattern.infinity; @@ -285,6 +288,7 @@ public MineBombData( String name, String itemType, String explosionShape, this.itemRemovalDelayTicks = 5; this.animationPattern = AnimationPattern.infinity; +// setAnimationPattern( AnimationPattern.infinity ); this.glowing = false; this.gravity = true; @@ -327,6 +331,8 @@ public MineBombData clone() { cloned.setGlowing( isGlowing() ); cloned.setGravity( isGravity() ); + cloned.setAnimationPattern( getAnimationPattern() ); + cloned.setItemRemovalDelayTicks( getItemRemovalDelayTicks() ); cloned.setAutosell( isAutosell() ); @@ -574,11 +580,30 @@ public void setItemRemovalDelayTicks( int itemRemovalDelayTicks ) { this.itemRemovalDelayTicks = itemRemovalDelayTicks; } + + /** + * If the animationPatternString is null, this will default to the + * infinity pattern. + * + * AnimationPattern should never be null, so it will fall back to it's default + * value which is infinity. + * + * @return + */ public AnimationPattern getAnimationPattern() { + if ( animationPattern == null ) { + // Note: if animationPatternString is null it will return 'infinity' which + // is the default value. + animationPattern = AnimationPattern.infinity; + } return animationPattern; } public void setAnimationPattern(AnimationPattern animationPattern) { - this.animationPattern = animationPattern; + + this.animationPattern = + animationPattern == null ? + AnimationPattern.infinity : + animationPattern; } public boolean isAutosell() { diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombEffectsData.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombEffectsData.java index e444dd1b9..28debab78 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombEffectsData.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombEffectsData.java @@ -23,8 +23,8 @@ public class MineBombEffectsData Comparable { - private EffectType effectType; - + private EffectType effectType = EffectType.unknown; + private String effectName; private EffectState effectState; @@ -38,6 +38,7 @@ public class MineBombEffectsData public enum EffectType { + unknown, sounds, visuals; } @@ -59,7 +60,7 @@ public MineBombEffectsData( int offsetTicks ) { super(); - this.effectType = null; + this.effectType = EffectType.unknown; this.effectName = effectName; this.effectState = effectState; 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 8b1b7472b..aad7ce912 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 @@ -89,6 +89,22 @@ public enum AnimationPattern { orbital ; + + public static final AnimationPattern fromString( String animationPattern ) { + AnimationPattern results = AnimationPattern.infinity; + + if ( animationPattern != null ) { + + for (AnimationPattern ap : values() ) { + if ( ap.name().equalsIgnoreCase( animationPattern) ) { + results = ap; + break; + } + } + } + + return results; + } } /** From ea06e691c8e5d48411c293704b0116c84092be22 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 1 Jul 2024 01:12:27 -0400 Subject: [PATCH 036/323] File saves for players with the ranks and player cache: reworked how the files saves will work and how they will process the files. Before I had them setup to be "enabled" by a command that they admin would run. But there were some problems with that. One thing that happened on my test server was that the save file that kept the config status disappeared and as such, there was some conflicts with which file was actually being used. As a result, some of the settings got screwed up for a couple of players. The solution was to change how files are read... basically it checks to see if either the new format is being used, and if not, then checks for the old format, and if not, then it uses the new file. If the old file is used, then it's renamed. When checking for these files preexisting, it does as such with filtering all files to find files with the given prefix. Therefore, it finds the correct file even if the player's name has been changed. This appears to be working very well at this point. NOTE: There are other commits that need to happen, and will follow this one, that will allow everything to compile successfully. This commit may not e able to be compiled. --- docs/changelog_v3.3.x.md | 12 +- .../mcprison/prison/cache/CoreCacheFiles.java | 28 ++-- .../tech/mcprison/prison/file/JsonFileIO.java | 141 ++++++++++++++++-- .../prison/ranks/data/RankPlayer.java | 35 ++++- .../java/tech/mcprison/prison/TestPlayer.java | 3 +- .../spigot/game/SpigotOfflinePlayer.java | 54 ++++++- .../prison/spigot/game/SpigotPlayer.java | 48 +++++- 7 files changed, 287 insertions(+), 34 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 0855020ea..4f70435be 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,17 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.18b 2024-06-29 +# 3.3.0-alpha.18b 2024-07-01 + + +* **File saves for players with the ranks and player cache: reworked how the files saves will work and how they will process the files.** +Before I had them setup to be "enabled" by a command that they admin would run. But there were some problems with that. +One thing that happened on my test server was that the save file that kept the config status disappeared and as such, there was some conflicts with which file was actually being used. +As a result, some of the settings got screwed up for a couple of players. +The solution was to change how files are read... basically it checks to see if either the new format is being used, and if not, then checks for the old format, and if not, then it uses the new file. If the old file is used, then it's renamed. +When checking for these files preexisting, it does as such with filtering all files to find files with the given prefix. Therefore, it finds the correct file even if the player's name has been changed. +This appears to be working very well at this point. +NOTE: There are other commits that need to happen, and will follow this one, that will allow everything to compile successfully. This commit may not e able to be compiled. * **Mine Bombs: Finalizing the validation and hooking in the new AnimationPatterns.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/cache/CoreCacheFiles.java b/prison-core/src/main/java/tech/mcprison/prison/cache/CoreCacheFiles.java index b5d586b23..434de38da 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/cache/CoreCacheFiles.java +++ b/prison-core/src/main/java/tech/mcprison/prison/cache/CoreCacheFiles.java @@ -151,10 +151,12 @@ protected CoreCacheData fromJsonFile(File inputFile, Class classOfT ) { CoreCacheData results = null; - String cacheFilename = JsonFileIO.filenameCache(player); -// String playerId = player.getUUID().toString(); + File playerCacheFile = JsonFileIO.fileCache(player); - File playerCacheFile = getPlayerFile( cacheFilename ); +// String cacheFilename = JsonFileIO.filenameCache(player); +//// String playerId = player.getUUID().toString(); +// +// File playerCacheFile = getPlayerFile( cacheFilename ); // // This is the "target" file name for the player, based upon their // // current name. The saved cache file may not be named exactly the same, @@ -272,16 +274,16 @@ public void toJsonFile(CoreCacheData cacheData) { } } - /** - *

Constructs a File object for a specific player. - *

- * - * @param playerFileName - * @return - */ - protected File getPlayerFile(String playerFileName) { - return new File( getPlayerFilePath(), playerFileName ); - } +// /** +// *

Constructs a File object for a specific player. +// *

+// * +// * @param playerFileName +// * @return +// */ +// protected File getPlayerFile(String playerFileName) { +// return new File( getPlayerFilePath(), playerFileName ); +// } // protected TreeMap getPlayerFiles() { // // load the player's files: 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 4bbba04df..52a38702b 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 @@ -2,10 +2,13 @@ import java.io.File; import java.io.FileFilter; +import java.util.ArrayList; +import java.util.List; import com.google.gson.Gson; import com.google.gson.GsonBuilder; +import tech.mcprison.prison.Prison; import tech.mcprison.prison.backups.PrisonSystemSettings; import tech.mcprison.prison.error.ErrorManager; import tech.mcprison.prison.internal.Player; @@ -21,6 +24,9 @@ public class JsonFileIO public static final String FILE_SUFFIX_TEMP = ".temp"; public static final String FILE_SUFFIX_TXT = ".txt"; public static final String FILE_TIMESTAMP_FORMAT = "_yyyy-MM-dd_HH-mm-ss"; + + public static final String PLAYER_PATH = "data_storage/ranksDb/players/"; + public static final String CACHE_PATH = "data_storage/playerCache/"; private final Gson gson; @@ -122,25 +128,101 @@ public static String getFileNameUUIDFragment( String filename ) { // uuid.substring( 25 ); } - /** - *

This is a helper function to ensure that the given file name is - * always generated correctly and consistently. - *

+// /** +// *

This is a helper function to ensure that the given file name is +// * always generated correctly and consistently. +// *

+// * +// * @return "player_" plus the least significant bits of the UID +// */ +// public static String filenamePlayer( Player player ) +// { +// boolean useNewFormat = useFriendlyUserFileNames(); +// +// return useNewFormat ? filenamePlayerNew( player ) : filenamePlayerOld( player ); +// } + +// public static String filenameCache( Player player ) +// { +// boolean useNewFormat = useFriendlyUserFileNames(); +// +// return useNewFormat ? filenameCacheNew( player ) : filenameCacheOld( player ); +// } + + public String filenamePrefix( String filename, String prefixDeliminator ) { + int idx = filename.lastIndexOf( prefixDeliminator ) + 1; + String prefix = idx > 0 ? filename.substring(0, idx) : null; + return prefix; + } + + /** + * Using the path and file name, this will check to see if any files + * preexist with the given file prefix so if the player changes their + * name, it will still load the correct file. + * + * If no file is found, then it will crate a new File object based + * upon the path and filename. * - * @return "player_" plus the least significant bits of the UID + * If existing file are found, there should only be at most one, but + * if there is more than one, then use the first one. + * + * @param path + * @param filename + * @return */ - public static String filenamePlayer( Player player ) - { - boolean useNewFormat = useFriendlyUserFileNames(); + public File checkFile( File path, String filename, String prefixDeliminator ) { - return useNewFormat ? filenamePlayerNew( player ) : filenamePlayerOld( player ); + String prefix = filenamePrefix( filename, prefixDeliminator ); + + List files = getFilesFromPrefix( prefix, path ); + + return files.size() > 0 ? files.get(0) : new File( path, filename ); + } + + public static File filePlayer( Player player ) { + JsonFileIO jfIO = new JsonFileIO(); + return jfIO.checkFiles( filenamePlayerNew( player ), filenamePlayerOld( player ), PLAYER_PATH ); + } + + public static File fileCache( Player player ) { + JsonFileIO jfIO = new JsonFileIO(); + return jfIO.checkFiles( filenameCacheNew( player ), filenameCacheOld( player ), CACHE_PATH ); } - public static String filenameCache( Player player ) + private File checkFiles( String newFileName, String oldFileName, String pathName ) { - boolean useNewFormat = useFriendlyUserFileNames(); + File results = null; - return useNewFormat ? filenameCacheNew( player ) : filenameCacheOld( player ); + File path = new File( Prison.get().getDataFolder(), pathName ); + + File newPlayerFile = checkFile( path, newFileName, "_" ); + + if ( newPlayerFile.exists() ) { + results = newPlayerFile; + } + else { + File oldPlayerFile = checkFile( path, oldFileName, "." ); + + if ( oldPlayerFile.exists() ) { + results = oldPlayerFile; + } + } + + if ( results == null ) { + // Did not find a new format file, or an old file format, so use the new format: + results = newPlayerFile; + } + + // If the file chosen is not equal to the newFileName, then rename it: + else if ( !newFileName.equals(results.getName()) ) { + File newFile = new File( path, newFileName ); + results.renameTo(newFile); + + // Rename does not change the original file path in results so have to reassign it: + results = newFile; + } + + return results; } @@ -264,6 +346,41 @@ public T fromString( String json, Class klass ) { } + + public List getFilesFromPrefix( String filePrefix, File path ) { + List results = new ArrayList<>(); + + FileFilter fFilter = getFilePrefixFilter( filePrefix ); + + + File[] collectionFiles = path.listFiles( fFilter ); + for (File file : collectionFiles ) { + results.add(file); + } + + return results; + } + + + public FileFilter getFilePrefixFilter( String filePrefix ) { + + FileFilter fileFilter = (file) -> { + + String fname = file.getName(); + boolean isTemp = fname.startsWith( FILE_PREFIX_BACKUP ) || + fname.endsWith( FILE_SUFFIX_BACKUP ) || + fname.endsWith( FILE_SUFFIX_TEMP ) || + fname.endsWith( FILE_SUFFIX_TXT ); + + return + fname.toLowerCase().startsWith( filePrefix.toLowerCase() ) && + !file.isDirectory() && !isTemp && + fname.endsWith( FILE_SUFFIX_JSON ); + }; + + return fileFilter; + } + public static FileFilter getPrisonFileFilter() { FileFilter fileFilter = (file) -> { 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 81e560e59..1f1d911a7 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 @@ -17,6 +17,7 @@ package tech.mcprison.prison.ranks.data; +import java.io.File; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.HashMap; @@ -68,6 +69,10 @@ public class RankPlayer private UUID uid; + private transient File filePlayer; + private transient File fileCache; + + private long totalBlocks; @@ -141,6 +146,9 @@ public RankPlayer() { // this.blocksMined = new HashMap<>(); this.playerBalances = new TreeMap<>(); + + this.filePlayer = null; + this.fileCache = null; } public RankPlayer( UUID uid ) { @@ -468,6 +476,27 @@ public String getPlayerFileName() { return filenamePlayer(); } + + public File getFilePlayer() { + if ( filePlayer == null ) { + filePlayer = JsonFileIO.filePlayer( this );; + } + return filePlayer; + } + public void setFilePlayer(File filePlayer) { + this.filePlayer = filePlayer; + } + + public File getFileCache() { + if ( fileCache == null ) { + fileCache = JsonFileIO.fileCache( this ); + } + return fileCache; + } + public void setFileCache(File fileCache) { + this.fileCache = fileCache; + } + /** *

This is a helper function to ensure that the given file name is * always generated correctly and consistently. @@ -477,12 +506,14 @@ public String getPlayerFileName() { */ public String filenamePlayer() { - return JsonFileIO.filenamePlayer( this ); + return getFilePlayer().getName(); +// return JsonFileIO.filenamePlayer( this ); } public String filenameCache() { - return JsonFileIO.filenameCache( this ); + return getFileCache().getName(); +// return JsonFileIO.filenameCache( this ); } diff --git a/prison-core/src/test/java/tech/mcprison/prison/TestPlayer.java b/prison-core/src/test/java/tech/mcprison/prison/TestPlayer.java index db97bc0d8..b262cd219 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/TestPlayer.java +++ b/prison-core/src/test/java/tech/mcprison/prison/TestPlayer.java @@ -72,7 +72,8 @@ public List getInput() { */ public String getPlayerFileName() { - return JsonFileIO.filenamePlayer( this ); + return JsonFileIO.filePlayer( this ).getName(); +// return JsonFileIO.filenamePlayer( this ); } @Override public void updateInventory() { diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java index b6ffb5112..fb9334c11 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java @@ -1,5 +1,6 @@ package tech.mcprison.prison.spigot.game; +import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -33,6 +34,12 @@ public class SpigotOfflinePlayer private OfflinePlayer offlinePlayer; + + private transient File filePlayer; + private transient File fileCache; + + + public SpigotOfflinePlayer(OfflinePlayer offlinePlayer) { this.offlinePlayer = offlinePlayer; } @@ -59,8 +66,53 @@ public String getName() { */ public String getPlayerFileName() { - return JsonFileIO.filenamePlayer( this ); + return filenamePlayer(); } + + + public File getFilePlayer() { + if ( filePlayer == null ) { + filePlayer = JsonFileIO.filePlayer( this );; + } + return filePlayer; + } + public void setFilePlayer(File filePlayer) { + this.filePlayer = filePlayer; + } + + public File getFileCache() { + if ( fileCache == null ) { + fileCache = JsonFileIO.fileCache( this ); + } + return fileCache; + } + public void setFileCache(File fileCache) { + this.fileCache = fileCache; + } + + /** + *

This is a helper function to ensure that the given file name is + * always generated correctly and consistently. + *

+ * + * @return "player_" plus the least significant bits of the UID + */ + public String filenamePlayer() + { + return getFilePlayer().getName(); +// return JsonFileIO.filenamePlayer( this ); + } + + public String filenameCache() + { + return getFileCache().getName(); +// return JsonFileIO.filenameCache( this ); + } + +// public String getPlayerFileName() { +// +// return JsonFileIO.filenamePlayer( this ); +// } @Override public String toString() { 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 ff628e0f2..5214aaa33 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 @@ -18,6 +18,7 @@ package tech.mcprison.prison.spigot.game; +import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -70,6 +71,12 @@ public class SpigotPlayer private RankPlayer rankPlayer; private org.bukkit.entity.Player bukkitPlayer; + + + private transient File filePlayer; + private transient File fileCache; + + public SpigotPlayer(org.bukkit.entity.Player bukkitPlayer) { super(bukkitPlayer); @@ -93,12 +100,45 @@ public SpigotPlayer(org.bukkit.entity.Player bukkitPlayer) { */ public String getPlayerFileName() { - return JsonFileIO.filenamePlayer( this ); + return filenamePlayer(); } - @Override - public UUID getUUID() { - return bukkitPlayer.getUniqueId(); + + public File getFilePlayer() { + if ( filePlayer == null ) { + filePlayer = JsonFileIO.filePlayer( this );; + } + return filePlayer; + } + public void setFilePlayer(File filePlayer) { + this.filePlayer = filePlayer; + } + + public File getFileCache() { + if ( fileCache == null ) { + fileCache = JsonFileIO.fileCache( this ); + } + return fileCache; + } + public void setFileCache(File fileCache) { + this.fileCache = fileCache; + } + + /** + *

This is a helper function to ensure that the given file name is + * always generated correctly and consistently. + *

+ * + * @return "player_" plus the least significant bits of the UID + */ + public String filenamePlayer() + { + return getFilePlayer().getName(); + } + + public String filenameCache() + { + return getFileCache().getName(); } @Override public String getDisplayName() { From 3f89a71abcee06e3d19ea1e13be7b97482950b44 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 1 Jul 2024 01:22:00 -0400 Subject: [PATCH 037/323] Prison Entity support added! This is a major change to prison. Support for bukkit Entities has been added, which had to be worked in between the SpigotCommandSender and the players. This is a significant change since it does allow more complex support for other features, such as newer and enhanced support for mine bomb animations, which uses armour stands, which are entities. This will allow the animations to be moved to the core and be associated with the mine bomb package. --- docs/changelog_v3.3.x.md | 6 + .../tech/mcprison/prison/internal/Entity.java | 137 ++++++++++++++++++ .../mcprison/prison/internal/EntityType.java | 20 +++ .../tech/mcprison/prison/internal/Player.java | 2 +- .../tech/mcprison/prison/internal/World.java | 7 + .../prison/ranks/data/RankPlayer.java | 3 +- .../java/tech/mcprison/prison/TestPlayer.java | 4 +- .../java/tech/mcprison/prison/TestWorld.java | 7 + .../prison/bombs/MineBombEffectsDataTest.java | 1 - .../spigot/game/SpigotCommandSender.java | 28 +++- .../spigot/game/SpigotOfflinePlayer.java | 3 +- .../prison/spigot/game/SpigotPlayer.java | 74 +++++++--- .../prison/spigot/game/SpigotWorld.java | 45 +++++- 13 files changed, 300 insertions(+), 37 deletions(-) create mode 100644 prison-core/src/main/java/tech/mcprison/prison/internal/Entity.java create mode 100644 prison-core/src/main/java/tech/mcprison/prison/internal/EntityType.java diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 4f70435be..27c276295 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.18b 2024-07-01 +* **Prison Entity support added!** +This is a major change to prison. Support for bukkit Entities has been added, which had to be worked in between the SpigotCommandSender and the players. +This is a significant change since it does allow more complex support for other features, such as newer and enhanced support for mine bomb animations, which uses armour stands, which are entities. +This will allow the animations to be moved to the core and be associated with the mine bomb package. + + * **File saves for players with the ranks and player cache: reworked how the files saves will work and how they will process the files.** Before I had them setup to be "enabled" by a command that they admin would run. But there were some problems with that. One thing that happened on my test server was that the save file that kept the config status disappeared and as such, there was some conflicts with which file was actually being used. diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/Entity.java b/prison-core/src/main/java/tech/mcprison/prison/internal/Entity.java new file mode 100644 index 000000000..6d1079aca --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/Entity.java @@ -0,0 +1,137 @@ +package tech.mcprison.prison.internal; + +import java.util.List; +import java.util.UUID; + +import tech.mcprison.prison.util.Location; +import tech.mcprison.prison.util.Vector; + +public interface Entity + extends CommandSender +{ + + + /** Returns a unique and persistent id for this entity */ + public UUID getUniqueId(); + + + /** Gets the custom name on a mob. */ + public String getCustomName(); + + /** Returns a unique id for this entity */ + public int getEntityId(); + + /** Eject any passenger. */ + public boolean eject(); + + /** Gets the entity's current position */ + public Location getLocation(); + + /** Stores the entity's current position in the provided Location object. */ + public Location getLocation(Location loc); + + + /** Returns the distance this entity has fallen */ + public float getFallDistance(); + + /** Returns the entity's current fire ticks (ticks before the entity stops being on fire). */ + public int getFireTicks(); + + /** Retrieve the last EntityDamageEvent inflicted on this entity. */ +// public EntityDamageEvent getLastDamageCause(); + + /** Returns the entity's maximum fire ticks. */ + public int getMaxFireTicks(); + + /** Returns a list of entities within a bounding box centered around this entity */ + public List getNearbyEntities(double x, double y, double z); + + /** Gets the primary passenger of a vehicle. */ + public Entity getPassenger(); + + /** Gets the Server that contains this Entity */ + //public Server getServer(); + + /** Gets the amount of ticks this entity has lived for. */ + public int getTicksLived(); + + /** Get the type of the entity. */ + public EntityType getType(); + + /** Get the vehicle that this player is inside. */ + public Entity getVehicle(); + + /** Gets this entity's current velocity */ + public Vector getVelocity(); + + /** Gets the current world this entity resides in */ + public World getWorld(); + + /** Gets whether or not the mob's custom name is displayed client side. */ + public boolean isCustomNameVisible(); + + /** Sets a custom name on a mob. */ + public void setCustomName(String name); + + /** Sets whether or not to display the mob's custom name client side. */ + public void setCustomNameVisible(boolean flag); + + + /** Returns true if this entity has been marked for removal. */ + public boolean isDead(); + + /** Check if a vehicle has passengers. */ + public boolean isEmpty(); + + /** Returns whether this entity is inside a vehicle. */ + public boolean isInsideVehicle(); + + /** Returns true if the entity is supported by a block. */ + public boolean isOnGround(); + + /** Returns false if the entity has died or been despawned for some other reason. */ + public boolean isValid(); + + /** Leave the current vehicle. */ + public boolean leaveVehicle(); + + /** Performs the specified EntityEffect for this entity. */ + //public void playEffect(EntityEffect type); + + /** Mark the entity's removal. */ + public void remove(); + + /** Sets the fall distance for this entity */ + public void setFallDistance(float distance); + + /** Sets the entity's current fire ticks (ticks before the entity stops being on fire). */ + public void setFireTicks(int ticks); + + /** Record the last EntityDamageEvent inflicted on this entity */ + //public void setLastDamageCause(EntityDamageEvent event); + + /** Set the passenger of a vehicle. */ + public boolean setPassenger(Entity passenger); + + /** Sets the amount of ticks this entity has lived for. */ + public void setTicksLived(int value); + + /** Sets this entity's velocity */ + public void setVelocity(Vector velocity); + + //public Entity.Spigot spigot(); + + /** Teleports this entity to the target Entity. */ + boolean teleport(Entity destination); + + /** Teleports this entity to the target Entity. */ + //public boolean teleport(Entity destination, PlayerTeleportEvent.TeleportCause cause); + + /** Teleports this entity to the given location. */ + public boolean teleport(Location location); + + /** Teleports this entity to the given location. */ + // public boolean teleport(Location location, PlayerTeleportEvent.TeleportCause cause); + + +} diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/EntityType.java b/prison-core/src/main/java/tech/mcprison/prison/internal/EntityType.java new file mode 100644 index 000000000..20b3882d3 --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/EntityType.java @@ -0,0 +1,20 @@ +package tech.mcprison.prison.internal; + +public class EntityType { + + private String entityType; + + public EntityType( String entityType ) { + super(); + + this.entityType = entityType; + } + + public String getEntityType() { + return entityType; + } + public void setEntityType(String entityType) { + this.entityType = entityType; + } + +} diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/Player.java b/prison-core/src/main/java/tech/mcprison/prison/internal/Player.java index a0c7e61ae..5a390b45b 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/Player.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/Player.java @@ -105,7 +105,7 @@ public interface Player * * @param location The new {@link Location}. */ - public void teleport(Location location); + public boolean teleport(Location location); /** * @return Returns true if the player is online, false otherwise. diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/World.java b/prison-core/src/main/java/tech/mcprison/prison/internal/World.java index 00f70483c..36f00a1f0 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/World.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/World.java @@ -44,6 +44,13 @@ public interface World { */ List getPlayers(); + + /** + * Returns a list of all entities in this world. + * @return + */ + List getEntities(); + /** * Returns the {@link Block} at a specified location. * 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 1f1d911a7..7f8ceab29 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 @@ -1106,8 +1106,9 @@ public List getLineOfSightBlocks() { @Override - public void teleport( Location location ) { + public boolean teleport( Location location ) { // Output.get().logError( "RankPlayer.teleport: Offline players cannot be teleported." ); + return false; } @Override diff --git a/prison-core/src/test/java/tech/mcprison/prison/TestPlayer.java b/prison-core/src/test/java/tech/mcprison/prison/TestPlayer.java index b262cd219..f70d21b23 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/TestPlayer.java +++ b/prison-core/src/test/java/tech/mcprison/prison/TestPlayer.java @@ -133,8 +133,8 @@ public List getLineOfSightBlocks() { } - @Override public void teleport(Location location) { - + @Override public boolean teleport(Location location) { + return false; } @Override public boolean isOnline() { diff --git a/prison-core/src/test/java/tech/mcprison/prison/TestWorld.java b/prison-core/src/test/java/tech/mcprison/prison/TestWorld.java index 873d31269..d6944d59e 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/TestWorld.java +++ b/prison-core/src/test/java/tech/mcprison/prison/TestWorld.java @@ -18,8 +18,10 @@ package tech.mcprison.prison; +import java.util.ArrayList; import java.util.List; +import tech.mcprison.prison.internal.Entity; import tech.mcprison.prison.internal.Player; import tech.mcprison.prison.internal.PrisonStatsElapsedTimeNanos; import tech.mcprison.prison.internal.World; @@ -76,5 +78,10 @@ public void setBlocksSynchronously( List tBlocks, } + @Override + public List getEntities() { + return new ArrayList<>(); + } + } diff --git a/prison-core/src/test/java/tech/mcprison/prison/bombs/MineBombEffectsDataTest.java b/prison-core/src/test/java/tech/mcprison/prison/bombs/MineBombEffectsDataTest.java index a82400ccf..a400e9f1d 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/bombs/MineBombEffectsDataTest.java +++ b/prison-core/src/test/java/tech/mcprison/prison/bombs/MineBombEffectsDataTest.java @@ -2,7 +2,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; import java.io.File; import java.util.ArrayList; 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 9d5d4c9f4..b1ae3ad97 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 @@ -22,6 +22,7 @@ import java.util.List; import java.util.Optional; import java.util.Set; +import java.util.UUID; import org.bukkit.Bukkit; import org.bukkit.command.ConsoleCommandSender; @@ -51,14 +52,25 @@ public SpigotCommandSender(org.bukkit.command.CommandSender sender) { this.bukkitSender = sender; } -// @Override -// public UUID getUUID() { -// UUID uuid = null; -// if ( isPlayer() ) { -// uuid = ((org.bukkit.entity.Player) bukkitSender).getUniqueId(); -// } -// return uuid; -// } + + /** + * We have both this function, getUniqueId() and getUUID(), because different + * sources (player vs entity) have different requirements and expectations for + * field names. + * + * @return + */ + public UUID getUniqueId() { + return getUUID(); + } + + public UUID getUUID() { + UUID uuid = null; + if ( isPlayer() ) { + uuid = ((org.bukkit.entity.Player) bukkitSender).getUniqueId(); + } + return uuid; + } @Override public String getName() { diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java index fb9334c11..cb44115f3 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java @@ -197,8 +197,9 @@ public Location getLocation() { } @Override - public void teleport( Location location ) { + public boolean teleport( Location location ) { Output.get().logError( "SpigotOfflinePlayer.teleport: Offline players cannot be teleported." ); + return false; } @Override 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 5214aaa33..49ea6806d 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 @@ -22,14 +22,12 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; -import java.util.UUID; import org.bukkit.GameMode; import org.bukkit.Material; import org.bukkit.Statistic; import org.bukkit.block.Block; import org.bukkit.entity.ExperienceOrb; -import org.bukkit.event.player.PlayerTeleportEvent; import com.cryptomorin.xseries.XMaterial; @@ -65,7 +63,8 @@ * @author Faizaan A. Datoo */ public class SpigotPlayer - extends SpigotCommandSender + extends SpigotEntity +// extends SpigotCommandSender implements Player, Comparable { private RankPlayer rankPlayer; @@ -140,41 +139,65 @@ public String filenameCache() { return getFileCache().getName(); } +// public String getPlayerFileName() { +// +// return JsonFileIO.filenamePlayer( this ); +// } + +// @Override +// public UUID getUUID() { +// return bukkitPlayer.getUniqueId(); +// } + +// @Override +// public String getName() { +// return bukkitPlayer.getName(); +// } - @Override public String getDisplayName() { + @Override + public String getDisplayName() { return bukkitPlayer.getDisplayName(); } - @Override public void setDisplayName(String newDisplayName) { + @Override + public void setDisplayName(String newDisplayName) { bukkitPlayer.setDisplayName(newDisplayName); } - @Override public void give(ItemStack itemStack) { + @Override + public void give(ItemStack itemStack) { bukkitPlayer.getInventory().addItem(SpigotUtil.prisonItemStackToBukkit(itemStack)); } - @Override public Location getLocation() { - return SpigotUtil.bukkitLocationToPrison(bukkitPlayer.getLocation()); - } +// @Override +// public Location getLocation() { +// return SpigotUtil.bukkitLocationToPrison(bukkitPlayer.getLocation()); +// } - @Override public void teleport(Location location) { - bukkitPlayer.teleport(SpigotUtil.prisonLocationToBukkit(location), - PlayerTeleportEvent.TeleportCause.PLUGIN); - } +// @Override public boolean teleport(Location location) { +// +// +// return bukkitPlayer.teleport(SpigotUtil.prisonLocationToBukkit(location), +// PlayerTeleportEvent.TeleportCause.PLUGIN); +// } - @Override public boolean isOnline() { + @Override + public boolean isOnline() { return bukkitPlayer.isOnline(); } - @Override public void setScoreboard(Scoreboard scoreboard) { + @Override + public void setScoreboard(Scoreboard scoreboard) { bukkitPlayer.setScoreboard(((SpigotScoreboard) scoreboard).getWrapper()); } - @Override public Gamemode getGamemode() { + @Override + public Gamemode getGamemode() { return Gamemode.valueOf(getWrapper().getGameMode().toString()); } - @Override public void setGamemode(Gamemode gamemode) { + @Override + public void setGamemode(Gamemode gamemode) { getWrapper().setGameMode(GameMode.valueOf(gamemode.toString())); } @@ -283,11 +306,15 @@ public SpigotPlayerInventory getSpigotPlayerInventory() { bukkitPlayer.updateInventory(); } -// @Override -// public void recalculatePermissions() { -// bukkitPlayer.recalculatePermissions(); -// } + @Override + public void recalculatePermissions() { + bukkitPlayer.recalculatePermissions(); + } + @Override + public boolean isPlayer() { + return true; + } // @Override // public boolean isOp() { @@ -351,7 +378,8 @@ public SpigotPlayerInventory getSpigotPlayerInventory() { @Override public int compareTo( SpigotPlayer sPlayer) { - return getName().compareTo( sPlayer.getName() ); + return getUUID().compareTo( sPlayer.getUUID() ); +// return getName().compareTo( sPlayer.getName() ); } @@ -1104,4 +1132,6 @@ public boolean checkAutoSellTogglePerms( StringBuilder debugInfo ) { return results; } + + } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotWorld.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotWorld.java index fc899a239..a8b36100a 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotWorld.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotWorld.java @@ -18,12 +18,17 @@ package tech.mcprison.prison.spigot.game; +import java.util.ArrayList; import java.util.List; import java.util.function.Function; import java.util.stream.Collectors; import org.bukkit.Bukkit; +import com.cryptomorin.xseries.XEntityType; + +import tech.mcprison.prison.internal.Entity; +import tech.mcprison.prison.internal.EntityType; import tech.mcprison.prison.internal.ItemStack; import tech.mcprison.prison.internal.Player; import tech.mcprison.prison.internal.PrisonStatsElapsedTimeNanos; @@ -43,7 +48,8 @@ /** * @author Faizaan A. Datoo */ -public class SpigotWorld implements World { +public class SpigotWorld + implements World { private org.bukkit.World bukkitWorld; @@ -67,6 +73,41 @@ public SpigotWorld(org.bukkit.World bukkitWorld) { .map((Function) SpigotPlayer::new) .collect(Collectors.toList()); } + + @Override + public List getEntities() { + List results = new ArrayList<>(); + + for (org.bukkit.entity.Entity bukkitEnitity : getWrapper().getEntities() ) { + + results.add( new SpigotEntity( bukkitEnitity) ); + } + + return results; + } + + /** + * Filters the returned Entities by the selected EntityType. + * + * @param eType + * @return + */ + public List getEntities( EntityType eType ) { + List results = new ArrayList<>(); + + SpigotEntityType seType = eType == null ? null : (SpigotEntityType) eType; + + for (org.bukkit.entity.Entity bukkitEnitity : getWrapper().getEntities() ) { + + if ( seType == null || + seType.getxEType() == XEntityType.of(bukkitEnitity) ) { + + results.add( new SpigotEntity( bukkitEnitity )); + } + } + + return results; + } /** *

This should be the ONLY usage in the whole Prison plugin that gets the @@ -219,6 +260,8 @@ public void setBlocksSynchronously( List tBlocks, MineRes public org.bukkit.World getWrapper() { return bukkitWorld; } + + } From 897b2b8a15cd068279208a14b1f35e331b267fe7 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 1 Jul 2024 01:26:48 -0400 Subject: [PATCH 038/323] Player info fix: When creating the new entity support, there were times when the names were being lost and as such this code was failing because the name was null. Normally it never will be null, so I cannot really call this a bug. But this fixes the issue if it happens again in the future. If a name is null, it now will properly support it. --- docs/changelog_v3.3.x.md | 4 ++++ .../tech/mcprison/prison/ranks/managers/PlayerManager.java | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 27c276295..af329ce46 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.18b 2024-07-01 +* **Player info fix: When creating the new entity support, there were times when the names were being lost and as such this code was failing because the name was null.** +Normally it never will be null, so I cannot really call this a bug. But this fixes the issue if it happens again in the future. If a name is null, it now will properly support it. + + * **Prison Entity support added!** This is a major change to prison. Support for bukkit Entities has been added, which had to be worked in between the SpigotCommandSender and the players. This is a significant change since it does allow more complex support for other features, such as newer and enhanced support for mine bomb animations, which uses armour stands, which are entities. diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java index 794a897de..3ea25f7f3 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java @@ -474,7 +474,11 @@ public void debugLogPlayerInfo( String eventName, String playerName, boolean dat if ( Output.get().isDebug() ) { - boolean newPlayer = !getPlayersByName().containsKey( playerName ); + boolean newPlayer = playerName != null ? !getPlayersByName().containsKey( playerName ) : false; + + if ( playerName == null ) { + playerName = "**Error No player name**"; + } SimpleDateFormat sdFmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); From e013f7cac42b97d78de04a9be49cfe3e7b0c05db Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 1 Jul 2024 01:28:28 -0400 Subject: [PATCH 039/323] Mine bombs: potential bug fix. If a mine bomb is null, this was causing problems. This now properly handles null mine bombs. --- docs/changelog_v3.3.x.md | 3 +++ .../events/AutoManagerPrisonsExplosiveBlockBreakEvents.java | 6 ++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index af329ce46..5b9c2c6ef 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.18b 2024-07-01 +* **Mine bombs: potential bug fix. If a mine bomb is null, this was causing problems. This now properly handles null mine bombs.** + + * **Player info fix: When creating the new entity support, there were times when the names were being lost and as such this code was failing because the name was null.** Normally it never will be null, so I cannot really call this a bug. But this fixes the issue if it happens again in the future. If a name is null, it now will properly support it. 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 c429dc195..befc5b33f 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 @@ -336,8 +336,10 @@ protected void handleExplosiveBlockBreakEvent( ExplosiveBlockBreakEvent e, - pmEvent.setApplyToPlayersBlockCount( - e.getMineBomb().isApplyToPlayersBlockCount() ); + if ( e.getMineBomb() != null ) { + pmEvent.setApplyToPlayersBlockCount( + e.getMineBomb().isApplyToPlayersBlockCount() ); + } if ( !validateEvent( pmEvent ) ) { From 24cb025db82bd5c99ba69990fe9cde64b96b3118 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 1 Jul 2024 02:42:24 -0400 Subject: [PATCH 040/323] Mine Bombs: New feature to remove stray amour stands. `/prison utils bomb findAmourStands help` This lists all amour stands in a given radius and you have the option to remove them. Early on, mine bombs use of amour stands could glitch and not be removed. This command can identify them, and remove them. This command should be used with caution since you could also remove holographic displays too, and if you do, you may not be able to regenerate them too easily, so use with caution. --- docs/changelog_v3.3.x.md | 8 + .../spigot/utils/PrisonUtilsMineBombs.java | 157 ++++++++++++++++++ 2 files changed, 165 insertions(+) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 5b9c2c6ef..d3b618169 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,14 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.18b 2024-07-01 +* **Mine Bombs: New feature to remove stray amour stands.** +`/prison utils bomb findAmourStands help` +This lists all amour stands in a given radius and you have the option to remove them. +Early on, mine bombs use of amour stands could glitch and not be removed. +This command can identify them, and remove them. +This command should be used with caution since you could also remove holographic displays too, and if you do, you may not be able to regenerate them too easily, so use with caution. + + * **Mine bombs: potential bug fix. If a mine bomb is null, this was causing problems. This now properly handles null mine 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 eb5fa251a..cd441533c 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 @@ -1,5 +1,6 @@ package tech.mcprison.prison.spigot.utils; +import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -13,9 +14,11 @@ //import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; +import com.cryptomorin.xseries.XEntityType; import com.cryptomorin.xseries.XMaterial; import com.cryptomorin.xseries.XSound; +import tech.mcprison.prison.Prison; import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; import tech.mcprison.prison.autofeatures.AutoFeaturesWrapper; import tech.mcprison.prison.bombs.MineBombData; @@ -25,7 +28,9 @@ import tech.mcprison.prison.bombs.MineBombs.ExplosionShape; import tech.mcprison.prison.commands.Arg; import tech.mcprison.prison.commands.Command; +import tech.mcprison.prison.commands.Wildcard; import tech.mcprison.prison.internal.CommandSender; +import tech.mcprison.prison.internal.Entity; import tech.mcprison.prison.internal.block.Block; import tech.mcprison.prison.mines.data.Mine; import tech.mcprison.prison.output.Output; @@ -36,11 +41,14 @@ import tech.mcprison.prison.spigot.block.SpigotItemStack; import tech.mcprison.prison.spigot.compat.Compatibility.EquipmentSlot; import tech.mcprison.prison.spigot.compat.SpigotCompatibility; +import tech.mcprison.prison.spigot.game.SpigotEntity; +import tech.mcprison.prison.spigot.game.SpigotEntityType; import tech.mcprison.prison.spigot.game.SpigotPlayer; import tech.mcprison.prison.spigot.game.SpigotWorld; import tech.mcprison.prison.spigot.inventory.SpigotPlayerInventory; import tech.mcprison.prison.spigot.nbt.PrisonNBTUtil; import tech.mcprison.prison.spigot.spiget.BluesSpigetSemVerComparator; +import tech.mcprison.prison.util.Bounds; import tech.mcprison.prison.util.Location; import tech.mcprison.prison.util.Text; @@ -95,6 +103,155 @@ protected Boolean initialize() return true; } + + + @Command(identifier = "prison utils bomb findArmorStands", + description = "This will remove abandonded/zombi armor stands within " + + "a radius of a player, or self.", + onlyPlayers = false, + permissions = "prison.utils.bombs", + altPermissions = "prison.utils.bombs.others") + public void utilsFindMineBombsArmorStands( CommandSender sender, + @Arg(name = "radius", def = "10", + description = "Number of blocks in a radius from the player " + + "to search for armor stands to remove.") int radius, + @Arg(name = "playerName", description = "Player name") String playerName, + @Wildcard(join=true) + @Arg(name = "options", def = "list", + description = "Action to perform. 'list' will list all armor stands within" + + "the general cubic-radius. " + + "'show' will make the armor stands visible for a few minutes " + + "and optionally provide an id for showing only one. " + + "removeAll' will remove all armor stands " + + "within the general cubic-radius. And 'removeId' will remove " + + "only one armor stand that matches the supplied ID. " + + " [list, show , removeAll, removeId ]") String options + + ) { + if ( !isEnableMineBombs() ) { + + Output.get().logInfo( "Prison's utils command mine bombs is disabled in modules.yml." ); + } + else { + + SpigotPlayer player = checkPlayerPerms( sender, playerName, + "prison.utils.bomb", "prison.utils.bomb.others" ); + + boolean list = false; + boolean show = false; + boolean removeAll = false; + boolean removeId = false; + + + String uuid = null; + + options = options.toLowerCase().trim(); + + if ( options.contains( "list" ) ) { + list = true; + options = options.replace( "list", "" ).trim(); + } + if ( options.contains( "show" ) ) { + show = true; + options = options.replace( "show", "" ).trim(); + uuid = options; + } + if ( options.contains( "removeall" ) ) { + removeAll = true; + options = options.replace( "removeall", "" ).trim(); + } + if ( options.contains( "removeid" ) ) { + removeId = true; + options = options.replace( "removeid", "" ).trim(); + uuid = options; + } + + if ( player != null ) { + + if ( show ) { + Output.get().logInfo( "&3Sorry 'show' is not yet implemented. " + + "Please ping Blue on discord. "); + } + + Location loc = player.getLocation(); + SpigotEntityType seType = new SpigotEntityType( XEntityType.ARMOR_STAND ); + + List entities = player.getNearbyEntities(radius, seType); + + DecimalFormat iFmt = Prison.getDecimalFormatStaticInt(); + DecimalFormat dFmt = Prison.getDecimalFormatStatic( "#,##0.0"); + + for (Entity entity : entities) { + SpigotEntity sEntity = (SpigotEntity) entity; + + Location l = entity.getLocation(); + + String id = entity.getUniqueId().toString().substring(30); + + int ticks = entity.getTicksLived(); + double times = ticks / 20.0; + String sfx = "secs"; + if ( times > 60 ) { + times /= 60; + sfx = "mins"; + } + if ( times > 60 ) { + times /= 60; + sfx = "hrs"; + } + + Bounds bounds = new Bounds( loc, l ); + + String status = ""; + + // actions: + if ( show ) { +// sEntity.getWrapper(). + } + if ( list ) { + // Do nothing: + } + else if ( removeAll || + removeId && id.equalsIgnoreCase( uuid ) + ) { + sEntity.remove(); + status = "&a** removed **"; + } + + String msg = String.format( + "&3ArmorStand: distance &7%4s &3id: &7%s &3x:%4s y:%4s z: %4s age: %s %s %s", + iFmt.format( bounds.getDistance3d() ), + id, + iFmt.format( l.getBlockX() ), + iFmt.format( l.getBlockY() ), + iFmt.format( l.getBlockZ() ), + dFmt.format( times ), + sfx, + status + ); + + sender.sendMessage( msg ); + } + + +// Location EntityArea = new Location(Bukkit.getWorld("world"),125,71,105); +// World world = Bukkit.getServer().getWorld("world"); +// List entList = world.getEntities(); +// +// for(Entity current : entList){ +// if(current instanceof Item){ +// current.remove(); +// } +// } + + } + + } + + + } + + @Command(identifier = "prison utils bombs", description = "Activates a mine bomb for a given player at a specific location. " + "The attributes of the bomb can be controlled with this command, such " + From 9750bc56d52e6bd2c6ae782080838e54d64ddf06 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 1 Jul 2024 03:00:15 -0400 Subject: [PATCH 041/323] Prison Entity support added! This is a major change to prison. Support for bukkit Entities has been added, which had to be worked in between the SpigotCommandSender and the players. This is a significant change since it does allow more complex support for other features, such as newer and enhanced support for mine bomb animations, which uses armour stands, which are entities. This will allow the animations to be moved to the core and be associated with the mine bomb package. --- .../prison/spigot/game/SpigotEntity.java | 282 ++++++++++++++++++ .../prison/spigot/game/SpigotEntityType.java | 49 +++ 2 files changed, 331 insertions(+) create mode 100644 prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotEntity.java create mode 100644 prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotEntityType.java diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotEntity.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotEntity.java new file mode 100644 index 000000000..13f42d3c2 --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotEntity.java @@ -0,0 +1,282 @@ +package tech.mcprison.prison.spigot.game; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import com.cryptomorin.xseries.XEntityType; + +import tech.mcprison.prison.internal.Entity; +import tech.mcprison.prison.internal.EntityType; +import tech.mcprison.prison.internal.World; +import tech.mcprison.prison.util.Location; +import tech.mcprison.prison.util.Vector; + +public class SpigotEntity + extends SpigotCommandSender + implements Entity { + + private org.bukkit.entity.Entity bukkitEntity; + + public SpigotEntity(org.bukkit.entity.Entity entity ) { + super( entity ); + + this.bukkitEntity = entity; + } + + + @Override + public UUID getUniqueId() { + return getBukkitEntity().getUniqueId(); + } + + @Override + public String getCustomName() { + return getBukkitEntity().getCustomName(); + } + + @Override + public int getEntityId() { + return getBukkitEntity().getEntityId(); + } + + @Override + public boolean eject() { + return getBukkitEntity().eject(); + } + + @Override + public Location getLocation() { + return new SpigotLocation( getBukkitEntity().getLocation() ); + } + + @Override + public Location getLocation(Location loc) { + return + new SpigotLocation( + getBukkitEntity().getLocation( ((SpigotLocation) loc).getBukkitLocation() )); + } + + @Override + public float getFallDistance() { + return getBukkitEntity().getFallDistance(); + } + + @Override + public int getFireTicks() { + return getBukkitEntity().getFireTicks(); + } + + @Override + public int getMaxFireTicks() { + return getBukkitEntity().getMaxFireTicks(); + } + + /** + * The parameter of radius is actually a cubic-radius, + * where the r is added to the location to produce a cube around the + * Entity or Player. + * + * @param r Radius around the Entity or Player + * @param eType + * @return + */ + public List getNearbyEntities( int r, EntityType eType ) { + Location loc = getLocation(); + List bEntities = getBukkitEntity() + .getNearbyEntities( loc.getX() + r, loc.getY() + r, loc.getZ() + r); + return convertEntities( bEntities, (SpigotEntityType) eType ); + } + + @Override + public List getNearbyEntities(double x, double y, double z) { + List bEntities = getBukkitEntity().getNearbyEntities(x, y, z); + return convertEntities( bEntities, null ); + } + + /** + * Converts all of the bukkit entities in to the SpigotEntityType, and if + * a SpigotEntityType is provided, it will also filter the results. + * + * @param bEntities + * @param seType + * @return + */ + private List convertEntities( + List bEntities, + SpigotEntityType seType ) { + List sEntities = new ArrayList<>(); + for (org.bukkit.entity.Entity entity : bEntities) { + + if ( seType == null || + seType.getxEType() == XEntityType.of(entity) ) { + + sEntities.add( new SpigotEntity( entity )); + } + } + return sEntities; + } + + + + @SuppressWarnings("deprecation") + @Override + public Entity getPassenger() { + return new SpigotEntity( getBukkitEntity().getPassenger() ); + } + + @Override + public int getTicksLived() { + return getBukkitEntity().getTicksLived(); + } + + @Override + public EntityType getType() { + + EntityType eType = new SpigotEntityType( getBukkitEntity().getType() ); + return eType; + } + + @Override + public Entity getVehicle() { + return new SpigotEntity( getBukkitEntity().getVehicle() ); + } + + @Override + public Vector getVelocity() { + + org.bukkit.util.Vector bVel = getBukkitEntity().getVelocity(); + Vector vec = new Vector( bVel.getX(), bVel.getY(), bVel.getZ() ); + + return vec; + } + + @Override + public World getWorld() { + return new SpigotWorld( getBukkitEntity().getWorld() ); + } + + @Override + public boolean isCustomNameVisible() { + return getBukkitEntity().isCustomNameVisible(); + } + + @Override + public void setCustomName(String name) { + getBukkitEntity().setCustomName(name); + } + + @Override + public void setCustomNameVisible(boolean flag) { + getBukkitEntity().setCustomNameVisible(flag); + } + + @Override + public boolean isDead() { + return getBukkitEntity().isDead(); + } + + @Override + public boolean isEmpty() { + return getBukkitEntity().isEmpty(); + } + + @Override + public boolean isInsideVehicle() { + return getBukkitEntity().isInsideVehicle(); + } + + @Override + public boolean isOnGround() { + return getBukkitEntity().isOnGround(); + } + + @Override + public boolean isValid() { + return getBukkitEntity().isValid(); + } + + @Override + public boolean leaveVehicle() { + return getBukkitEntity().leaveVehicle(); + } + + @Override + public void remove() { + getBukkitEntity().remove(); + } + + @Override + public void setFallDistance(float distance) { + getBukkitEntity().setFallDistance(distance); + } + + @Override + public void setFireTicks(int ticks) { + getBukkitEntity().setFireTicks(ticks); + } + + @SuppressWarnings("deprecation") + @Override + public boolean setPassenger(Entity passenger) { + return getBukkitEntity().setPassenger( ((SpigotEntity) passenger).getBukkitEntity() ); + } + + @Override + public void setTicksLived(int value) { + getBukkitEntity().setTicksLived(value); + } + + @Override + public void setVelocity(Vector velocity) { + + org.bukkit.util.Vector bVec = + new org.bukkit.util.Vector( + velocity.getX(), velocity.getY(), velocity.getZ() ); + + getBukkitEntity().setVelocity( bVec ); + } + + @Override + public boolean teleport(Entity destination) { + return getBukkitEntity().teleport( ((SpigotEntity) destination).getBukkitEntity() ); + } + + @Override + public boolean teleport(Location location) { + + org.bukkit.World world = ((SpigotWorld) location.getWorld()).getWrapper(); + org.bukkit.Location loc = new org.bukkit.Location( world, + location.getX(), location.getY(), location.getZ(), + location.getYaw(), location.getPitch()); + return getBukkitEntity().teleport( loc ); + } + + public org.bukkit.entity.Entity getBukkitEntity() { + return bukkitEntity; + } + + + @Override + public String getName() { + return bukkitEntity.getName(); + } + + + @Override + public boolean isPlayer() { + return false; + } + + + +// @Override +// public boolean doesSupportColors() { +// return false; +// } + + + + + +} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotEntityType.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotEntityType.java new file mode 100644 index 000000000..0216facea --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotEntityType.java @@ -0,0 +1,49 @@ +package tech.mcprison.prison.spigot.game; + +import com.cryptomorin.xseries.XEntityType; + +import tech.mcprison.prison.internal.EntityType; + +public class SpigotEntityType + extends EntityType { + + private org.bukkit.entity.EntityType bEntityType; + private XEntityType xEType; + + public SpigotEntityType( String entityType ) { + super( entityType ); + + } + public SpigotEntityType( org.bukkit.entity.EntityType bEntityType ) { + super( "" ); + + this.bEntityType = bEntityType; + + XEntityType xEType = XEntityType.of( bEntityType ); + this.xEType = xEType; + + setEntityType( xEType.name() ); + } + public SpigotEntityType( XEntityType xEType ) { + super( xEType.name() ); + + this.xEType = xEType; + + this.bEntityType = xEType.get(); + } + + public org.bukkit.entity.EntityType getbEntityType() { + return bEntityType; + } + public void setbEntityType(org.bukkit.entity.EntityType bEntityType) { + this.bEntityType = bEntityType; + } + + public XEntityType getxEType() { + return xEType; + } + public void setxEType(XEntityType xEType) { + this.xEType = xEType; + } + +} From 47447699c7523f56e74aeacb06af8fe5e76745d4 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 3 Jul 2024 02:15:00 -0400 Subject: [PATCH 042/323] RankPlayer: Added new fields to expand what is being stored in the RankPlayer object to store data that is not available when the player is offline. This can provide additional support for players when they are offline. --- docs/changelog_v3.3.x.md | 6 +- .../prison/ranks/data/RankPlayer.java | 74 ++++++++++ .../prison/ranks/data/RankPlayerFactory.java | 138 +++++++++++++++++- 3 files changed, 211 insertions(+), 7 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index d3b618169..e17c66b7e 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.18b 2024-07-01 +# 3.3.0-alpha.18b 2024-07-03 + + +* **RankPlayer: Added new fields to expand what is being stored in the RankPlayer object to store data that is not available when the player is offline.** +This can provide additional support for players when they are offline. * **Mine Bombs: New feature to remove stray amour stands.** 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 7f8ceab29..b4735bfdf 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 @@ -134,6 +134,15 @@ public class RankPlayer private long economyCacheUpdateDelayTicks = -1; + + private long lastSaved = -1; + private long lastRefreshed = -1; + + private List permsSnapShot; + + private List sellallMultipliers; + + public RankPlayer() { super(); @@ -147,6 +156,11 @@ public RankPlayer() { this.playerBalances = new TreeMap<>(); + this.permsSnapShot = new ArrayList<>(); + + this.sellallMultipliers = new ArrayList<>(); + + this.filePlayer = null; this.fileCache = null; } @@ -2192,6 +2206,66 @@ private String applySecondaryPlaceholdersCheck( String placeholder, String value public void doNothing() { } + + + public long getLastSaved() { + return lastSaved; + } + public void setLastSaved(long lastSaved) { + this.lastSaved = lastSaved; + } + + + /** + * Notice: This last refreshed timestamp refers to when the permsSnapShot + * and sellallMultipliers were last updated. It maybe be older than the + * last time the players were seen? + * @return + */ + public long getLastRefreshed() { + return lastRefreshed; + } + public void setLastRefreshed(long lastRefreshed) { + this.lastRefreshed = lastRefreshed; + } + + /** + * DO NOT USE! + * + * This is just temporary and unofficial list of permissions + * to be used when the player is offline. These are only accurate + * when they are extracted when the player is online and the player's + * RankPlayer object is saved. + * + * @return + */ + public List getPermsSnapShot() { + return permsSnapShot; + } + public void setPermsSnapShot(List permsSnapShot) { + this.permsSnapShot = permsSnapShot; + } + + /** + * DO NOT USE! + * + * This is just temporary and unofficial list of sellall multipliers + * to be used when the player is offline. These are only accurate + * when they are extracted when the player is online and the player's + * RankPlayer object is saved. + * + * @return + */ + public List getSellallMultipliers() { + return sellallMultipliers; + } + public void setSellallMultipliers(List sellallMultipliers) { + this.sellallMultipliers = sellallMultipliers; + } + + + + // public long getRankScoreCooldown() { // return rankScoreCooldown; // } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactory.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactory.java index cb0fecf66..e4f4e84d4 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactory.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactory.java @@ -1,15 +1,19 @@ package tech.mcprison.prison.ranks.data; import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; +import java.util.TreeMap; import java.util.UUID; import com.google.gson.internal.LinkedTreeMap; import tech.mcprison.prison.Prison; import tech.mcprison.prison.cache.PlayerCachePlayerData; +import tech.mcprison.prison.file.JsonFileIO; +import tech.mcprison.prison.internal.Player; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.ranks.FirstJoinHandlerMessages; import tech.mcprison.prison.ranks.PrisonRanks; @@ -21,13 +25,20 @@ public class RankPlayerFactory { + JsonFileIO jfIO = new JsonFileIO(); @SuppressWarnings( "unchecked" ) public RankPlayer createRankPlayer(Document document) { RankPlayer rankPlayer = null; - UUID uuid = UUID.fromString((String) document.get("uid")); + String uuidStr = document.containsKey("uid") ? + (String) document.get("uid") : + document.containsKey("uuid") ? + (String) document.get("uuid") : + null; + + UUID uuid = UUID.fromString( uuidStr ); rankPlayer = new RankPlayer( uuid ); @@ -39,13 +50,26 @@ public RankPlayer createRankPlayer(Document document) { // LinkedTreeMap blocksMinedLocal = // (LinkedTreeMap) document.get("blocksMined"); - Object namesListObject = document.get( "names" ); for (String key : ranksLocal.keySet()) { - int rankId = ConversionUtil.doubleToInt(ranksLocal.get(key)); - rankPlayer.getRanksRefs().put(key, rankId ); + Object rankObj = ranksLocal.get(key); + + if ( rankObj instanceof Double ) { + int rankId = ConversionUtil.doubleToInt( rankObj ); + rankPlayer.getRanksRefs().put(key, rankId ); + } + else { + // It's a json object: + // We only need to get the rankId from the json String, but the other fields are there + // for human readability. + String json = rankObj.toString(); + RankPlayerFactoryDataRank rData = jfIO.fromString( json, RankPlayerFactoryDataRank.class ); + if ( rData != null ) { + rankPlayer.getRanksRefs().put( key, rData.getRankId() ); + } + } } @@ -66,6 +90,9 @@ public RankPlayer createRankPlayer(Document document) { // rankPlayer.getBlocksMined().put(key, ConversionUtil.doubleToInt(blocksMinedLocal.get(key))); // } // } + + + Object namesListObject = document.get( "names" ); if ( namesListObject != null ) { @@ -103,7 +130,37 @@ public RankPlayer createRankPlayer(Document document) { if ( document.get("lastSeenDate") != null ) { - rankPlayer.setTotalBlocksTemp( getLong( rankPlayer.getName(), "lastSeenDate", document ) ); + rankPlayer.setLastSeenDateTemp( getLong( rankPlayer.getName(), "lastSeenDate", document ) ); + } + + + if ( document.get("lastSaved") != null ) { + rankPlayer.setLastSaved( getLong( rankPlayer.getName(), "lastSaved", document ) ); + } + + + if ( document.get("lastRefreshed") != null ) { + rankPlayer.setLastRefreshed( getLong( rankPlayer.getName(), "lastRefreshed", document ) ); + } + + + + + + // The new field permsSnapShot will be a list of all of the player's perms, captured + // at major moments when they are online. Since perms are not available offline, + // this will provide a "rough" listing of what they maybe. Its beyond the scope of + // this snap shot to ensure these perms are "current"; if they change after this + // image is taken, then that's not our problem. + if ( document.get("permsSnapShot") != null ) { + List perms = (List) document.get("permsSnapShot"); + rankPlayer.setPermsSnapShot( perms ); + } + + + if ( document.get("sellallMultipliers") != null ) { + List mults = (List) document.get("sellallMultipliers"); + rankPlayer.setSellallMultipliers( mults ); } @@ -128,13 +185,32 @@ else if ( obj instanceof Double ) { } public static Document toDocument( RankPlayer rankPlayer ) { + JsonFileIO jfIO = new JsonFileIO(); + // Update some stats from the playerCache: PlayerCachePlayerData cacheData = rankPlayer.getPlayerCache().getOnlinePlayerCached(rankPlayer); rankPlayer.updateTotalLastValues( cacheData , false); Document ret = new Document(); ret.put("uid", rankPlayer.getUUID()); - ret.put("ranks", rankPlayer.getRanksRefs() ); + + + + Set ladders = rankPlayer.getLadderRanks().keySet(); + TreeMap playerRanks = new TreeMap<>(); + for (RankLadder ladder : ladders) { + PlayerRank rank = rankPlayer.getLadderRanks().get(ladder); + + RankPlayerFactoryDataRank rData = new RankPlayerFactoryDataRank( + rank.getRank().getName(), ladder.getName(), rank.getRank().getId() ); +// String json = jfIO.toString( rData ); + playerRanks.put( rData.getRankName(), rData.getJsonObject() ); + } + + ret.put("ranks", playerRanks ); +// ret.put("ranks", rankPlayer.getRanksRefs() ); + + // ret.put("prestige", this.prestige); ret.put("names", rankPlayer.getNames()); @@ -145,6 +221,56 @@ public static Document toDocument( RankPlayer rankPlayer ) { ret.put("totalTokens", Long.valueOf( rankPlayer.getTotalTokensTemp() )); ret.put("lastSeenDate", Long.valueOf( rankPlayer.getLastSeenDateTemp() )); + + + Player sPlayer = rankPlayer.getPlatformPlayer(); + + +// // create a timestamp: +// ret.put( "lastSeenDate", Long.valueOf( rankPlayer.getLastSeenDate() )); + + // create a timestamp: + ret.put( "lastSaved", Long.valueOf( System.currentTimeMillis() )); + + + if ( sPlayer != null && sPlayer.isOnline() ) { + ret.put( "lastRefreshed", Long.valueOf( System.currentTimeMillis() )); + } + else { + ret.put( "lastRefreshed", rankPlayer.getLastRefreshed() ); + } + + + // The new field permsSnapShot will be a list of all of the player's perms, captured + // at major moments when they are online. Since perms are not available offline, + // this will provide a "rough" listing of what they maybe. Its beyond the scope of + // this snap shot to ensure these perms are "current"; if they change after this + // image is taken, then that's not our problem. + List perms = new ArrayList<>(); + + + if ( sPlayer != null && sPlayer.isOnline() ) { + // If the player is online, get a fresh list of perms: + perms = sPlayer.getPermissions(); + } + else { + // Otherwise since the player if offline, then save whatever permsSnapShot is already available: + rankPlayer.getPermsSnapShot(); + } + ret.put( "permsSnapShot", perms ); + + + List multipliers = new ArrayList<>(); + if ( sPlayer != null && sPlayer.isOnline() ) { + multipliers = sPlayer.getSellAllMultiplierListings(); + } + else { + // Otherwise since offline, save the existing list of multipliers: + multipliers = rankPlayer.getSellallMultipliers(); + } + ret.put("sellallMultipliers", multipliers); + + // ret.put("blocksMined", rankPlayer.getBlocksMined() ); return ret; From 029a184400b24b02048d0cf58df9b8f5701134ef Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 3 Jul 2024 02:26:04 -0400 Subject: [PATCH 043/323] RankPlayer: Added new fields to expand what is being stored in the RankPlayer object to store data that is not available when the player is offline. This can provide additional support for players when they are offline. --- .../ranks/data/RankPlayerFactoryDataRank.java | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactoryDataRank.java diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactoryDataRank.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactoryDataRank.java new file mode 100644 index 000000000..464461171 --- /dev/null +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactoryDataRank.java @@ -0,0 +1,54 @@ +package tech.mcprison.prison.ranks.data; + +import java.util.TreeMap; + +public class RankPlayerFactoryDataRank { + + private String rankName; + private String ladderName; + private int rankId; + + public RankPlayerFactoryDataRank() { + super(); + } + public RankPlayerFactoryDataRank( String rankName, String ladderName, int rankId ) { + super(); + + this.rankName = rankName; + this.ladderName = ladderName; + this.rankId = rankId; + } + + public TreeMap getJsonObject(){ + TreeMap results = new TreeMap<>(); + + results.put("rankName", getRankName()); + results.put("ladderName", getLadderName()); + + results.put("rankId", Integer.valueOf(rankId)); + + return results; + } + + public String getRankName() { + return rankName; + } + public void setRankName(String rankName) { + this.rankName = rankName; + } + + public String getLadderName() { + return ladderName; + } + public void setLadderName(String ladderName) { + this.ladderName = ladderName; + } + + public int getRankId() { + return rankId; + } + public void setRankId(int rankId) { + this.rankId = rankId; + } + +} From 3fba245cb6381794481ee7124073c9586de80094 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 3 Jul 2024 02:36:48 -0400 Subject: [PATCH 044/323] Refactor JsonFileIO to push more of the non-json content to FileIO where it really should be located. --- docs/changelog_v3.3.x.md | 3 + .../tech/mcprison/prison/file/FileIO.java | 337 ++++++++++++++++++ .../tech/mcprison/prison/file/JsonFileIO.java | 333 ----------------- 3 files changed, 340 insertions(+), 333 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index e17c66b7e..c90c1010e 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.18b 2024-07-03 +* **Refactor JsonFileIO to push more of the non-json content to FileIO where it really should be located.** + + * **RankPlayer: Added new fields to expand what is being stored in the RankPlayer object to store data that is not available when the player is offline.** This can provide additional support for players when they are offline. diff --git a/prison-core/src/main/java/tech/mcprison/prison/file/FileIO.java b/prison-core/src/main/java/tech/mcprison/prison/file/FileIO.java index 3975f1b0c..ce02263dd 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/file/FileIO.java +++ b/prison-core/src/main/java/tech/mcprison/prison/file/FileIO.java @@ -1,18 +1,22 @@ package tech.mcprison.prison.file; import java.io.File; +import java.io.FileFilter; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.StandardOpenOption; import java.text.SimpleDateFormat; +import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; import tech.mcprison.prison.Prison; +import tech.mcprison.prison.backups.PrisonSystemSettings; import tech.mcprison.prison.error.Error; import tech.mcprison.prison.error.ErrorManager; +import tech.mcprison.prison.internal.Player; import tech.mcprison.prison.modules.ModuleStatus; import tech.mcprison.prison.output.Output; @@ -20,6 +24,17 @@ public abstract class FileIO extends FileVirtualDelete { + public static final String FILE_SUFFIX_JSON = ".json"; + public static final String FILE_PREFIX_BACKUP = ".backup_"; + public static final String FILE_SUFFIX_BACKUP = ".bu"; + public static final String FILE_SUFFIX_TEMP = ".temp"; + public static final String FILE_SUFFIX_TXT = ".txt"; + public static final String FILE_TIMESTAMP_FORMAT = "_yyyy-MM-dd_HH-mm-ss"; + + public static final String PLAYER_PATH = "data_storage/ranksDb/players/"; + public static final String CACHE_PATH = "data_storage/playerCache/"; + + private final SimpleDateFormat sdf; private final ErrorManager errorManager; @@ -219,6 +234,328 @@ private void logException( String description, File file, IOException e ) } } + + /** + *

This function generate a partial user file name. This is based upon + * the UUID-fragment (first and last parts of the player UUID), + * plus the player's name, and the file suffix, which is '.json'. + * This function does not add any prefix such as 'player_' or + * 'cache_'. + *

+ * + * @param player + * @return + */ + private static String getPlayerFileNameNewVersion( Player player ) { + + String uuidFragment = getFileNamePrefixNew( player ); + + return uuidFragment + "_" + player.getName() + FILE_SUFFIX_JSON; + } + + /** + *

This generates the fragment UUID that is used within file names. + * This is based upon the first 8 UUID digits, plus the hyphen. Followed + * by the last segment of the UUID, which starts at character 25. + *

+ * + *

This uses the start and end of the UUID because bedrock players + * only have zeros for the first part of the UUID, so the ending must + * be included too. + *

+ * + *

Examples: + *

+ * '22cacd8c-d0ff-4dd7-a8ba-2a6a8b46be92' + * '' + * + * @param player + * @return + */ + private static String getFileNamePrefixNew( Player player ) { + String uuid = player.getUUID().toString(); + return uuid.substring( 0, 9 ) + + uuid.substring( 25 ); + } + + /** + *

This function extracts the UUID fragment from player file names. + *

+ * + * @param filename + * @return + */ + public static String getFileNameUUIDFragment( String filename ) { + String uuid = null; + + if ( filename != null && filename.trim().length() > 0 ) { + + String uuidTmp = filename.replace("cache_", "").replace("player_", ""); + + uuid = uuidTmp.indexOf("_") > 0 ? + uuidTmp.substring(0, uuidTmp.indexOf("_")) + : uuidTmp; + } + return uuid; + +// String uuid = player.getUUID().toString(); +// return uuid.substring( 0, 9 ) + +// uuid.substring( 25 ); + } + +// /** +// *

This is a helper function to ensure that the given file name is +// * always generated correctly and consistently. +// *

+// * +// * @return "player_" plus the least significant bits of the UID +// */ +// public static String filenamePlayer( Player player ) +// { +// boolean useNewFormat = useFriendlyUserFileNames(); +// +// return useNewFormat ? filenamePlayerNew( player ) : filenamePlayerOld( player ); +// } + +// public static String filenameCache( Player player ) +// { +// boolean useNewFormat = useFriendlyUserFileNames(); +// +// return useNewFormat ? filenameCacheNew( player ) : filenameCacheOld( player ); +// } + + public String filenamePrefix( String filename, String prefixDeliminator ) { + int idx = filename.lastIndexOf( prefixDeliminator ) + 1; + String prefix = idx > 0 ? filename.substring(0, idx) : null; + return prefix; + } + + /** + * Using the path and file name, this will check to see if any files + * preexist with the given file prefix so if the player changes their + * name, it will still load the correct file. + * + * If no file is found, then it will crate a new File object based + * upon the path and filename. + * + * If existing file are found, there should only be at most one, but + * if there is more than one, then use the first one. + * + * @param path + * @param filename + * @return + */ + public File checkFile( File path, String filename, String prefixDeliminator ) { + + String prefix = filenamePrefix( filename, prefixDeliminator ); + + List files = getFilesFromPrefix( prefix, path ); + + return files.size() > 0 ? files.get(0) : new File( path, filename ); + } + + public static File filePlayer( Player player ) { + FileIO fIO = new FileIO() {}; + return fIO.checkFiles( filenamePlayerNew( player ), filenamePlayerOld( player ), PLAYER_PATH ); + } + + public static File fileCache( Player player ) { + FileIO fIO = new FileIO() {}; + return fIO.checkFiles( filenameCacheNew( player ), filenameCacheOld( player ), CACHE_PATH ); + } + + private File checkFiles( String newFileName, String oldFileName, String pathName ) + { + File results = null; + + File path = new File( Prison.get().getDataFolder(), pathName ); + + File newPlayerFile = checkFile( path, newFileName, "_" ); + + if ( newPlayerFile.exists() ) { + results = newPlayerFile; + } + else { + File oldPlayerFile = checkFile( path, oldFileName, "." ); + + if ( oldPlayerFile.exists() ) { + results = oldPlayerFile; + } + } + + if ( results == null ) { + // Did not find a new format file, or an old file format, so use the new format: + results = newPlayerFile; + } + + // If the file chosen is not equal to the newFileName, then rename it: + else if ( !newFileName.equals(results.getName()) ) { + File newFile = new File( path, newFileName ); + results.renameTo(newFile); + + // Rename does not change the original file path in results so have to reassign it: + results = newFile; + } + + return results; + } + + + /** + *

This function will check two things. First will be the config settings within + * 'config.yml' to see if the new format is enabled. Secondly, it checks to see if + * the PrisonSystemSettings has recorded if the conversion has taken place. + * Both have to be true in order for this function to return a value of true., + *

+ * + * @return + */ + public static boolean useFriendlyUserFileNames() { + + return PrisonSystemSettings.useFriendlyUserFileNames(); + } + + /** + * Do not use. Use 'filenameCache( player )'. + * + * @param player + * @return + */ + public static String filenameCacheNew( Player player ) { + + return "cache_" + getPlayerFileNameNewVersion( player ); + } + /** + * Do not use. Use 'filenameCache( player )'. + * + * @param player + * @return + */ + public static String filenameCacheOld( Player player ) { + + return getPlayerFileNameShortVersion( player ); + } + + /** + * Do not use. Use 'filenamePlayer( player )'. + * + * @param player + * @return + */ + public static String filenamePlayerNew( Player player ) + { + return "player_" + getPlayerFileNameNewVersion( player ); + } + /** + * Do not use. Use 'filenamePlayer( player )'. + * + * @param player + * @return + */ + public static String filenamePlayerOld( Player player ) + { + return "player_" + player.getUUID().getLeastSignificantBits() + FILE_SUFFIX_JSON; + } + + + /** + *

Do not use. This version is not compatible with bedrock players + * because all bedrock UUIDs are just zeros when using this formmat. + * The newer format also includes the trailing + * + *

This constructs a player file named based upon the UUID followed + * by the player's name. This format is used so it's easier to identify + * the correct player. + *

+ * + *

The format should be UUID-PlayerName.json. The UUID is a shortened + * format, which should still produce a unique id. The name, when read, + * is based upon the UUID and not the player's name, which may change. + * This format includes the player's name to make it easier to identify + * who's record is whom's. + *

+ * + * @return + */ + @Deprecated + public static String getPlayerFileNameShortVersion( Player player ) { + + String UUIDString = player.getUUID().toString(); + String uuidFragment = getFileNamePrefixObsolete( UUIDString ); + + return uuidFragment + "_" + player.getName() + FILE_SUFFIX_JSON; + } + + /** + *

Do not use. This does not support bedrock players because + * the prefix of bedrock UUIDs is all zeros. + *

+ * + *

This function returns the first 13 characters of the supplied + * file name, or UUID String. The hyphen is around the 12 or 13th position, + * so it may or may not include it. + *

+ * + * @param playerFileName + * @return + */ + @Deprecated + private static String getFileNamePrefixObsolete( String UUIDString ) { + return UUIDString.substring( 0, 14 ); + } + + + public List getFilesFromPrefix( String filePrefix, File path ) { + List results = new ArrayList<>(); + + FileFilter fFilter = getFilePrefixFilter( filePrefix ); + + + File[] collectionFiles = path.listFiles( fFilter ); + for (File file : collectionFiles ) { + results.add(file); + } + + return results; + } + + + public FileFilter getFilePrefixFilter( String filePrefix ) { + + FileFilter fileFilter = (file) -> { + + String fname = file.getName(); + boolean isTemp = fname.startsWith( FILE_PREFIX_BACKUP ) || + fname.endsWith( FILE_SUFFIX_BACKUP ) || + fname.endsWith( FILE_SUFFIX_TEMP ) || + fname.endsWith( FILE_SUFFIX_TXT ); + + return + fname.toLowerCase().startsWith( filePrefix.toLowerCase() ) && + !file.isDirectory() && !isTemp && + fname.endsWith( FILE_SUFFIX_JSON ); + }; + + return fileFilter; + } + + public static FileFilter getPrisonFileFilter() { + + FileFilter fileFilter = (file) -> { + + String fname = file.getName(); + boolean isTemp = fname.startsWith( FILE_PREFIX_BACKUP ) || + fname.endsWith( FILE_SUFFIX_BACKUP ) || + fname.endsWith( FILE_SUFFIX_TEMP ) || + fname.endsWith( FILE_SUFFIX_TXT ); + + return !file.isDirectory() && !isTemp && + fname.endsWith( FILE_SUFFIX_JSON ); + }; + + return fileFilter; + } + private String getTimestampFormat() { return sdf.format( new Date() ); 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 52a38702b..a12790a9b 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 @@ -1,32 +1,17 @@ package tech.mcprison.prison.file; import java.io.File; -import java.io.FileFilter; -import java.util.ArrayList; -import java.util.List; import com.google.gson.Gson; import com.google.gson.GsonBuilder; -import tech.mcprison.prison.Prison; -import tech.mcprison.prison.backups.PrisonSystemSettings; import tech.mcprison.prison.error.ErrorManager; -import tech.mcprison.prison.internal.Player; import tech.mcprison.prison.modules.ModuleStatus; import tech.mcprison.prison.output.Output; public class JsonFileIO extends FileIO { - public static final String FILE_SUFFIX_JSON = ".json"; - public static final String FILE_PREFIX_BACKUP = ".backup_"; - public static final String FILE_SUFFIX_BACKUP = ".bu"; - public static final String FILE_SUFFIX_TEMP = ".temp"; - public static final String FILE_SUFFIX_TXT = ".txt"; - public static final String FILE_TIMESTAMP_FORMAT = "_yyyy-MM-dd_HH-mm-ss"; - - public static final String PLAYER_PATH = "data_storage/ranksDb/players/"; - public static final String CACHE_PATH = "data_storage/playerCache/"; private final Gson gson; @@ -60,275 +45,7 @@ public Gson getGsonExposed() .create(); } - /** - *

This function generate a partial user file name. This is based upon - * the UUID-fragment (first and last parts of the player UUID), - * plus the player's name, and the file suffix, which is '.json'. - * This function does not add any prefix such as 'player_' or - * 'cache_'. - *

- * - * @param player - * @return - */ - private static String getPlayerFileNameNewVersion( Player player ) { - - String uuidFragment = getFileNamePrefixNew( player ); - - return uuidFragment + "_" + player.getName() + FILE_SUFFIX_JSON; - } - - /** - *

This generates the fragment UUID that is used within file names. - * This is based upon the first 8 UUID digits, plus the hyphen. Followed - * by the last segment of the UUID, which starts at character 25. - *

- * - *

This uses the start and end of the UUID because bedrock players - * only have zeros for the first part of the UUID, so the ending must - * be included too. - *

- * - *

Examples: - *

- * '22cacd8c-d0ff-4dd7-a8ba-2a6a8b46be92' - * '' - * - * @param player - * @return - */ - private static String getFileNamePrefixNew( Player player ) { - String uuid = player.getUUID().toString(); - return uuid.substring( 0, 9 ) + - uuid.substring( 25 ); - } - - /** - *

This function extracts the UUID fragment from player file names. - *

- * - * @param filename - * @return - */ - public static String getFileNameUUIDFragment( String filename ) { - String uuid = null; - - if ( filename != null && filename.trim().length() > 0 ) { - - String uuidTmp = filename.replace("cache_", "").replace("player_", ""); - - uuid = uuidTmp.indexOf("_") > 0 ? - uuidTmp.substring(0, uuidTmp.indexOf("_")) - : uuidTmp; - } - return uuid; - -// String uuid = player.getUUID().toString(); -// return uuid.substring( 0, 9 ) + -// uuid.substring( 25 ); - } - -// /** -// *

This is a helper function to ensure that the given file name is -// * always generated correctly and consistently. -// *

-// * -// * @return "player_" plus the least significant bits of the UID -// */ -// public static String filenamePlayer( Player player ) -// { -// boolean useNewFormat = useFriendlyUserFileNames(); -// -// return useNewFormat ? filenamePlayerNew( player ) : filenamePlayerOld( player ); -// } - -// public static String filenameCache( Player player ) -// { -// boolean useNewFormat = useFriendlyUserFileNames(); -// -// return useNewFormat ? filenameCacheNew( player ) : filenameCacheOld( player ); -// } - - public String filenamePrefix( String filename, String prefixDeliminator ) { - int idx = filename.lastIndexOf( prefixDeliminator ) + 1; - String prefix = idx > 0 ? filename.substring(0, idx) : null; - return prefix; - } - - /** - * Using the path and file name, this will check to see if any files - * preexist with the given file prefix so if the player changes their - * name, it will still load the correct file. - * - * If no file is found, then it will crate a new File object based - * upon the path and filename. - * - * If existing file are found, there should only be at most one, but - * if there is more than one, then use the first one. - * - * @param path - * @param filename - * @return - */ - public File checkFile( File path, String filename, String prefixDeliminator ) { - - String prefix = filenamePrefix( filename, prefixDeliminator ); - - List files = getFilesFromPrefix( prefix, path ); - - return files.size() > 0 ? files.get(0) : new File( path, filename ); - } - - public static File filePlayer( Player player ) { - JsonFileIO jfIO = new JsonFileIO(); - return jfIO.checkFiles( filenamePlayerNew( player ), filenamePlayerOld( player ), PLAYER_PATH ); - } - - public static File fileCache( Player player ) { - JsonFileIO jfIO = new JsonFileIO(); - return jfIO.checkFiles( filenameCacheNew( player ), filenameCacheOld( player ), CACHE_PATH ); - } - - private File checkFiles( String newFileName, String oldFileName, String pathName ) - { - File results = null; - - File path = new File( Prison.get().getDataFolder(), pathName ); - - File newPlayerFile = checkFile( path, newFileName, "_" ); - - if ( newPlayerFile.exists() ) { - results = newPlayerFile; - } - else { - File oldPlayerFile = checkFile( path, oldFileName, "." ); - - if ( oldPlayerFile.exists() ) { - results = oldPlayerFile; - } - } - - if ( results == null ) { - // Did not find a new format file, or an old file format, so use the new format: - results = newPlayerFile; - } - - // If the file chosen is not equal to the newFileName, then rename it: - else if ( !newFileName.equals(results.getName()) ) { - File newFile = new File( path, newFileName ); - results.renameTo(newFile); - - // Rename does not change the original file path in results so have to reassign it: - results = newFile; - } - return results; - } - - - /** - *

This function will check two things. First will be the config settings within - * 'config.yml' to see if the new format is enabled. Secondly, it checks to see if - * the PrisonSystemSettings has recorded if the conversion has taken place. - * Both have to be true in order for this function to return a value of true., - *

- * - * @return - */ - public static boolean useFriendlyUserFileNames() { - - return PrisonSystemSettings.useFriendlyUserFileNames(); - } - - /** - * Do not use. Use 'filenameCache( player )'. - * - * @param player - * @return - */ - public static String filenameCacheNew( Player player ) { - - return "cache_" + getPlayerFileNameNewVersion( player ); - } - /** - * Do not use. Use 'filenameCache( player )'. - * - * @param player - * @return - */ - public static String filenameCacheOld( Player player ) { - - return getPlayerFileNameShortVersion( player ); - } - - /** - * Do not use. Use 'filenamePlayer( player )'. - * - * @param player - * @return - */ - public static String filenamePlayerNew( Player player ) - { - return "player_" + getPlayerFileNameNewVersion( player ); - } - /** - * Do not use. Use 'filenamePlayer( player )'. - * - * @param player - * @return - */ - public static String filenamePlayerOld( Player player ) - { - return "player_" + player.getUUID().getLeastSignificantBits() + FILE_SUFFIX_JSON; - } - - - /** - *

Do not use. This version is not compatible with bedrock players - * because all bedrock UUIDs are just zeros when using this formmat. - * The newer format also includes the trailing - * - *

This constructs a player file named based upon the UUID followed - * by the player's name. This format is used so it's easier to identify - * the correct player. - *

- * - *

The format should be UUID-PlayerName.json. The UUID is a shortened - * format, which should still produce a unique id. The name, when read, - * is based upon the UUID and not the player's name, which may change. - * This format includes the player's name to make it easier to identify - * who's record is whom's. - *

- * - * @return - */ - @Deprecated - public static String getPlayerFileNameShortVersion( Player player ) { - - String UUIDString = player.getUUID().toString(); - String uuidFragment = getFileNamePrefixObsolete( UUIDString ); - - return uuidFragment + "_" + player.getName() + FILE_SUFFIX_JSON; - } - - /** - *

Do not use. This does not support bedrock players because - * the prefix of bedrock UUIDs is all zeros. - *

- * - *

This function returns the first 13 characters of the supplied - * file name, or UUID String. The hyphen is around the 12 or 13th position, - * so it may or may not include it. - *

- * - * @param playerFileName - * @return - */ - @Deprecated - private static String getFileNamePrefixObsolete( String UUIDString ) { - return UUIDString.substring( 0, 14 ); - } - public String toString( Object obj ) { String json = getGson().toJson( obj ); @@ -346,57 +63,7 @@ public T fromString( String json, Class klass ) { } - - public List getFilesFromPrefix( String filePrefix, File path ) { - List results = new ArrayList<>(); - - FileFilter fFilter = getFilePrefixFilter( filePrefix ); - - - File[] collectionFiles = path.listFiles( fFilter ); - for (File file : collectionFiles ) { - results.add(file); - } - return results; - } - - - public FileFilter getFilePrefixFilter( String filePrefix ) { - - FileFilter fileFilter = (file) -> { - - String fname = file.getName(); - boolean isTemp = fname.startsWith( FILE_PREFIX_BACKUP ) || - fname.endsWith( FILE_SUFFIX_BACKUP ) || - fname.endsWith( FILE_SUFFIX_TEMP ) || - fname.endsWith( FILE_SUFFIX_TXT ); - - return - fname.toLowerCase().startsWith( filePrefix.toLowerCase() ) && - !file.isDirectory() && !isTemp && - fname.endsWith( FILE_SUFFIX_JSON ); - }; - - return fileFilter; - } - - public static FileFilter getPrisonFileFilter() { - - FileFilter fileFilter = (file) -> { - - String fname = file.getName(); - boolean isTemp = fname.startsWith( FILE_PREFIX_BACKUP ) || - fname.endsWith( FILE_SUFFIX_BACKUP ) || - fname.endsWith( FILE_SUFFIX_TEMP ) || - fname.endsWith( FILE_SUFFIX_TXT ); - - return !file.isDirectory() && !isTemp && - fname.endsWith( FILE_SUFFIX_JSON ); - }; - - return fileFilter; - } /** * This function will save a file as a JSON format. It will first save it as a From c10a9a1784f483922504f1e91180ac11ef247eaa Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 3 Jul 2024 02:46:40 -0400 Subject: [PATCH 045/323] Sellall: when sellall message delay is enabled for autosell, changed it to when the player does `/sellall sell` it reports the sale for that transaction instead of waiting until 15 to 20 seconds later. --- docs/changelog_v3.3.x.md | 4 ++++ .../prison/spigot/commands/PrisonSpigotSellAllCommands.java | 6 ++++-- .../tech/mcprison/prison/spigot/sellall/SellAllUtil.java | 5 ++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index c90c1010e..7d26d863a 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.18b 2024-07-03 +* **Sellall: when sellall message delay is enabled for autosell, changed it to when the player does `/sellall sell` it reports the sale for that transaction instead of waiting until 15 to 20 seconds later.** + + + * **Refactor JsonFileIO to push more of the non-json content to FileIO where it really should be located.** 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 fda4f23e3..e4954cfac 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 @@ -334,8 +334,10 @@ else if (p == null){ } boolean notifications = (notification != null && "silent".equalsIgnoreCase( notification )); - - sellAllUtil.sellAllSell(p, false, notifications, true, true, false, true); + boolean delayNotifications = false; + boolean delayNotificationsEarnings = false; + + sellAllUtil.sellAllSell(p, false, notifications, true, delayNotifications, delayNotificationsEarnings, true); SpigotPlayer sPlayer = new SpigotPlayer( p ); PlayerAutoRankupTask.autoSubmitPlayerRankupTask( sPlayer, null ); 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 8634f98b0..d0bccebe9 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 @@ -2773,7 +2773,10 @@ public double sellAllSell(Player p, SpigotItemStack itemStack, if (!isPlayerWaitingAutoSellNotification(p)){ // Initialize && Force delayed notifications, even if delayed is disabled: autoSellEarningsNotificationWaiting.put(p, 0.00); - Bukkit.getScheduler().scheduleSyncDelayedTask(SpigotPrison.getInstance(), () -> removeFromAutoSellDelayAndNotify(p), 20L * defaultAutoSellEarningNotificationDelay); + + Bukkit.getScheduler().scheduleSyncDelayedTask( + SpigotPrison.getInstance(), () -> + removeFromAutoSellDelayAndNotify(p), 20L * defaultAutoSellEarningNotificationDelay); } From ebb99e53cfe1997e63a693093788cea0d249ad25 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 3 Jul 2024 20:14:23 -0400 Subject: [PATCH 046/323] Prison semantic version: Moved the code of prison's semantic version tools to the prison-core module. This was needed to be used within the core, so it's movement and the elimination of dependencies on spiget was beneficial. --- .../util/BluesSemanticVersionComparator.java | 168 +++++++++++++ .../util}/BluesSemanticVersionData.java | 2 +- .../util}/BluesSemanticVersionDataTest.java | 17 +- .../BluesSpigetSemVerComparatorTest.java | 64 ++--- .../prison/spigot/SpigotPlatform.java | 10 +- .../autofeatures/AutoManagerFeatures.java | 6 +- .../block/OnBlockBreakExternalEvents.java | 4 +- .../spigot/compat/SpigotCompatibility.java | 6 +- .../spigot/customblock/CustomItems.java | 4 +- .../spigot/economies/VaultEconomyWrapper.java | 4 +- .../slime/SlimeBlockFunEventListener.java | 2 +- .../spiget/BluesSpigetSemVerComparator.java | 236 +++++++++--------- .../spigot/utils/PrisonUtilsMineBombs.java | 8 +- .../utils/PrisonUtilsMineBombsTasks.java | 6 +- 14 files changed, 356 insertions(+), 181 deletions(-) create mode 100644 prison-core/src/main/java/tech/mcprison/prison/util/BluesSemanticVersionComparator.java rename {prison-spigot/src/main/java/tech/mcprison/prison/spigot/spiget => prison-core/src/main/java/tech/mcprison/prison/util}/BluesSemanticVersionData.java (99%) rename {prison-spigot/src/test/java/tech/mcprison/prison/spigot/spiget => prison-core/src/test/java/tech/mcprison/prison/util}/BluesSemanticVersionDataTest.java (89%) rename {prison-spigot/src/test/java/tech/mcprison/prison/spigot/spiget => prison-core/src/test/java/tech/mcprison/prison/util}/BluesSpigetSemVerComparatorTest.java (54%) diff --git a/prison-core/src/main/java/tech/mcprison/prison/util/BluesSemanticVersionComparator.java b/prison-core/src/main/java/tech/mcprison/prison/util/BluesSemanticVersionComparator.java new file mode 100644 index 000000000..05f74aa5b --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/util/BluesSemanticVersionComparator.java @@ -0,0 +1,168 @@ +package tech.mcprison.prison.util; + +import tech.mcprison.prison.Prison; + +//import org.bukkit.Bukkit; +//import org.inventivetalent.update.spiget.comparator.VersionComparator; + +/** + *

This class provides a real comparator for semantic versioning + * for spiget. This addresses issues seen with incorrect notifications. + * Extensive unit tests back the correct functionality of this code base. + *

+ * + *

Spiget's versions have totally failed on so many levels that they + * should not imply it has anything to do with semVer at all. + * The inherent problems with the solutions provided by spiget, is that they may work + * some of the time, but then fail once certain incorrect assumptions about semVers + * are realized. Intermittent failures are to be expected. For example, if someone + * is using version 2.3.11 and 2.4.0 is released, spiget's SEM_VER + * comparator will think the older version is newer than the current release. + * Why does that fail? Because they just remove the periods and take the remainder + * characters and then parse them all as one integer, then they compare integers. The + * context of major, minor, and patch is completely lost, plus it does not factor + * in prerelease tagging as semVer supports. + *

+ * + *

To provide a product that actually works with real semVers, the website + * https://semver.org/ was used as the + * "standard" to base this functionality upon, and to which our tests are + * measured against. + *

+ * + *

The result of the new architecture is a solution that ends up being very + * simple for this class. + *

+ * + * @author RoyalBlueRanger 2020-01-28 + * @return + */ +public class BluesSemanticVersionComparator +// extends VersionComparator + { + + public boolean isNewer(String currentVersion, String checkVersion) { + return performComparisons( currentVersion, checkVersion); + } + + /** + *

This function will take two String values and convert both to a + * SemanticVersioningData objects, that in turn, will parse the string + * and encapsulate the full representation as an object. Since this object + * implements comparable, its then as simple as comparing the new semVer to the + * current semVer to find out if it is actually newer. + *

+ * + *

The semantic versions must be valid. At a minimum they have to + * have a format such as 1.0.0. If one is invalid, then compareTo will + * favor the valid semVer. If both are invalid then compareTo will return + * a negative -1000, which will equate to false result. + *

+ * + * @param currentVersion A String value representing the current semVer + * @param checkVersion A String value representing the checked semVer + * @return True if the checkVersion is a higher semVer than the current version + */ + public boolean performComparisons( String currentVersion, String checkVersion ) { + + BluesSemanticVersionData currentSemVer = new BluesSemanticVersionData(currentVersion); + BluesSemanticVersionData checkSemVer = new BluesSemanticVersionData(checkVersion); + + return (checkSemVer.compareTo( currentSemVer ) > 0); + } + + /** + *

Example how to use: + *

+ * + *
+	 * String ver = Bukkit.getVersion().trim();
+	 * ver = ver.substring( ver.indexOf("(MC: ") + 5, ver.length() -1 );
+	 * if ( new BluesSpigetSemVerComparator().compareTo(ver, "1.9.0") ) {
+	 *     // if mc version is less than 1.9.0
+	 * }
+	 * 
+ * + * @param currentVersion + * @param checkVersion + * @return + */ + public int compareTo( String currentVersion, String checkVersion ) { + + BluesSemanticVersionData currentSemVer = new BluesSemanticVersionData(currentVersion); + BluesSemanticVersionData checkSemVer = new BluesSemanticVersionData(checkVersion); + + return currentSemVer.compareTo( checkSemVer ); + } + + /** + *

This uses the minecraft version of the server to compare to the provided version. + *

+ * + *

Samples of what a bukkit, spigot, and paper version would look like. Notice + * they all have the version at the end between (MC: and ). + *

+ * + *
    + *
  • Spigot 1.8.8: git-Spigot-21fe707-e1ebe52 (MC: 1.8.8)
  • + *
  • Spigot 1.10.2: git-Spigot-de459a2-51263e9 (MC: 1.10.2)
  • + *
  • Spigot 1.12.2: git-Spigot-79a30d7-acbc348 (MC: 1.12.2)
  • + *
  • Spigot 1.15.2: git-Spigot-2040c4c-893ad93 (MC: 1.15.2)
  • + *
  • Paper 1.10.2: git-Paper-916.2 (MC: 1.10.2)
  • + *
  • Paper 1.14.2: git-Paper-234 (MC: 1.14.4)
  • + *
+ * + * *

Example how to use: + *

+ * + *
+	 * if ( new BluesSpigetSemVerComparator().compareMCVersionTo("1.9.0") < 0 ) {
+	 *     // if mc version is less than 1.9.0
+	 * }
+	 * 
+ * + * @param checkVersion + * @return + */ + public int compareMCVersionTo( String checkVersion ) { + int results = -1; + String currentVersion = getBukkitVersion(); + if ( currentVersion != null ) { + + results = compareTo( currentVersion, checkVersion ); + } + return results; + } + + public String getBukkitVersion() { + // Minecraft version: git-Paper-21 (MC: 1.15) + + return getBukkitVersion( getBukkitVersionRaw() ); + } + + + private String getBukkitVersionRaw() { + return Prison.get().getMinecraftVersion(); +// return Bukkit.getVersion(); + } + + public String getBukkitVersion( String currentVersion ) { + String results = null; + + if ( currentVersion != null ) { + currentVersion = currentVersion.trim().toLowerCase(); + int i = currentVersion.indexOf("(mc:"); + int len = currentVersion.length(); + if ( i >= 0 && (i+4 < len)) { + results = currentVersion.substring( i + 4, len - 1 ).trim(); + } + } + +// if ( results != null && "1.17".equals( results ) ) { +// results = "1.17.0"; +// } + + return results; + } + +} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/spiget/BluesSemanticVersionData.java b/prison-core/src/main/java/tech/mcprison/prison/util/BluesSemanticVersionData.java similarity index 99% rename from prison-spigot/src/main/java/tech/mcprison/prison/spigot/spiget/BluesSemanticVersionData.java rename to prison-core/src/main/java/tech/mcprison/prison/util/BluesSemanticVersionData.java index 87e06f588..510b3cd00 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/spiget/BluesSemanticVersionData.java +++ b/prison-core/src/main/java/tech/mcprison/prison/util/BluesSemanticVersionData.java @@ -1,4 +1,4 @@ -package tech.mcprison.prison.spigot.spiget; +package tech.mcprison.prison.util; import java.util.ArrayList; import java.util.List; diff --git a/prison-spigot/src/test/java/tech/mcprison/prison/spigot/spiget/BluesSemanticVersionDataTest.java b/prison-core/src/test/java/tech/mcprison/prison/util/BluesSemanticVersionDataTest.java similarity index 89% rename from prison-spigot/src/test/java/tech/mcprison/prison/spigot/spiget/BluesSemanticVersionDataTest.java rename to prison-core/src/test/java/tech/mcprison/prison/util/BluesSemanticVersionDataTest.java index 863e44d1b..28742b639 100644 --- a/prison-spigot/src/test/java/tech/mcprison/prison/spigot/spiget/BluesSemanticVersionDataTest.java +++ b/prison-core/src/test/java/tech/mcprison/prison/util/BluesSemanticVersionDataTest.java @@ -1,4 +1,4 @@ -package tech.mcprison.prison.spigot.spiget; +package tech.mcprison.prison.util; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -8,6 +8,9 @@ import org.junit.Test; +import tech.mcprison.prison.util.BluesSemanticVersionComparator; +import tech.mcprison.prison.util.BluesSemanticVersionData; + public class BluesSemanticVersionDataTest { @@ -160,12 +163,12 @@ public void test() // Test the compareTo function: - assertTrue( new BluesSpigetSemVerComparator().compareTo( "1.8.0", "1.9.0" ) < 0 ); - assertTrue( new BluesSpigetSemVerComparator().compareTo( "1.8.8", "1.9.0" ) < 0 ); - assertFalse( new BluesSpigetSemVerComparator().compareTo( "1.9.0", "1.9.0" ) < 0 ); - assertFalse( new BluesSpigetSemVerComparator().compareTo( "1.15.2", "1.9.0" ) < 0 ); - assertTrue( new BluesSpigetSemVerComparator().compareTo( "1.9.0", "1.9.0" ) == 0 ); - assertTrue( new BluesSpigetSemVerComparator().compareTo( "1.15.2", "1.9.0" ) > 0 ); + assertTrue( new BluesSemanticVersionComparator().compareTo( "1.8.0", "1.9.0" ) < 0 ); + assertTrue( new BluesSemanticVersionComparator().compareTo( "1.8.8", "1.9.0" ) < 0 ); + assertFalse( new BluesSemanticVersionComparator().compareTo( "1.9.0", "1.9.0" ) < 0 ); + assertFalse( new BluesSemanticVersionComparator().compareTo( "1.15.2", "1.9.0" ) < 0 ); + assertTrue( new BluesSemanticVersionComparator().compareTo( "1.9.0", "1.9.0" ) == 0 ); + assertTrue( new BluesSemanticVersionComparator().compareTo( "1.15.2", "1.9.0" ) > 0 ); // The following "should" assert to a value of true. diff --git a/prison-spigot/src/test/java/tech/mcprison/prison/spigot/spiget/BluesSpigetSemVerComparatorTest.java b/prison-core/src/test/java/tech/mcprison/prison/util/BluesSpigetSemVerComparatorTest.java similarity index 54% rename from prison-spigot/src/test/java/tech/mcprison/prison/spigot/spiget/BluesSpigetSemVerComparatorTest.java rename to prison-core/src/test/java/tech/mcprison/prison/util/BluesSpigetSemVerComparatorTest.java index c0c02627d..87c2d612d 100644 --- a/prison-spigot/src/test/java/tech/mcprison/prison/spigot/spiget/BluesSpigetSemVerComparatorTest.java +++ b/prison-core/src/test/java/tech/mcprison/prison/util/BluesSpigetSemVerComparatorTest.java @@ -1,4 +1,4 @@ -package tech.mcprison.prison.spigot.spiget; +package tech.mcprison.prison.util; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -13,23 +13,23 @@ public class BluesSpigetSemVerComparatorTest @Test public void test() { - BluesSpigetSemVerComparator bssvc = new BluesSpigetSemVerComparator(); + BluesSemanticVersionComparator bsvc = new BluesSemanticVersionComparator(); // Test a few comparisons that should work easily: // Two valid semVers, but at same version should return a false: - assertFalse( bssvc.performComparisons( "1.0.1", "1.0.1" ) ); + assertFalse( bsvc.performComparisons( "1.0.1", "1.0.1" ) ); - assertFalse( bssvc.performComparisons( "1.0.2", "1.0.1" ) ); + assertFalse( bsvc.performComparisons( "1.0.2", "1.0.1" ) ); // Newer version available, should return true: - assertTrue( bssvc.performComparisons( "1.0.1", "1.0.2" ) ); + assertTrue( bsvc.performComparisons( "1.0.1", "1.0.2" ) ); // Newer version available, should return true: - assertTrue( bssvc.performComparisons( "1.4.1", "1.5.0" ) ); + assertTrue( bsvc.performComparisons( "1.4.1", "1.5.0" ) ); // Newer version available, should return true: - assertTrue( bssvc.performComparisons( "1.4.61", "1.5.0" ) ); + assertTrue( bsvc.performComparisons( "1.4.61", "1.5.0" ) ); @@ -38,27 +38,27 @@ public void test() // First test a SINGLE digit number: no decimals: // Neither are valid semVersion so should return false: - assertFalse( bssvc.performComparisons( "1", "1" ) ); + assertFalse( bsvc.performComparisons( "1", "1" ) ); // Neither are valid semVersion so should return false: - assertFalse( bssvc.performComparisons( "0", "1" ) ); + assertFalse( bsvc.performComparisons( "0", "1" ) ); // Test for a larger gap: - assertFalse( bssvc.performComparisons( "1", "7" ) ); + assertFalse( bsvc.performComparisons( "1", "7" ) ); // Test for one of them being a double digit: - assertFalse( bssvc.performComparisons( "1", "17" ) ); + assertFalse( bsvc.performComparisons( "1", "17" ) ); // Test for one of them being a double digit, but older version's digit a non-one: - assertFalse( bssvc.performComparisons( "8", "17" ) ); + assertFalse( bsvc.performComparisons( "8", "17" ) ); // These should all be false since they are all equal: - assertFalse( bssvc.performComparisons( "1.0", "1.0" ) ); - assertFalse( bssvc.performComparisons( "1.0.1", "1.0.1" ) ); + assertFalse( bsvc.performComparisons( "1.0", "1.0" ) ); + assertFalse( bsvc.performComparisons( "1.0.1", "1.0.1" ) ); // The following is an invalid semVer so it should return a false: - assertFalse( bssvc.performComparisons( "2.37.902.181.0.2.4", "2.37.902.181.0.2.4" ) ); - assertFalse( bssvc.performComparisons( "2.37.902.181.0.2.4", "2.37.902.181.0.2.5" ) ); + assertFalse( bsvc.performComparisons( "2.37.902.181.0.2.4", "2.37.902.181.0.2.4" ) ); + assertFalse( bsvc.performComparisons( "2.37.902.181.0.2.4", "2.37.902.181.0.2.5" ) ); // This should be false, where current is newer than "new". @@ -66,62 +66,62 @@ public void test() // what has been published: // equals... so should be false: - assertFalse( bssvc.performComparisons( "2.37.902-alpha.181-beta.0+build2.5", + assertFalse( bsvc.performComparisons( "2.37.902-alpha.181-beta.0+build2.5", "2.37.902-alpha.181-beta.0+build2.5" ) ); // buildmeta should be ignored so does not matter. Should be false: - assertFalse( bssvc.performComparisons( "2.37.902-alpha.181-beta.0+build2.5", + assertFalse( bsvc.performComparisons( "2.37.902-alpha.181-beta.0+build2.5", "2.37.902-alpha.181-beta.0+build2.7.34" ) ); // should be true: - assertTrue( bssvc.performComparisons( "2.37.902-alpha.181-beta.0+build2.5", + assertTrue( bsvc.performComparisons( "2.37.902-alpha.181-beta.0+build2.5", "2.37.902-alpha.181-beta.1+build2.7.34" ) ); // Newer version has invalid semVer, but its corrected to be valid: return true: - assertTrue( bssvc.performComparisons( "1.2.3", "1.3" ) ); + assertTrue( bsvc.performComparisons( "1.2.3", "1.3" ) ); // Current version has invalid semVer, but newer has valid. Always true: - assertTrue( bssvc.performComparisons( "1.2", "1.2.1" ) ); + assertTrue( bsvc.performComparisons( "1.2", "1.2.1" ) ); // 1.501 is valid so this test will fail since 1.2.1 is less: - assertFalse( bssvc.performComparisons( "1.501", "1.2.1" ) ); - assertTrue( bssvc.performComparisons( "9999901", "1.2.1" ) ); + assertFalse( bsvc.performComparisons( "1.501", "1.2.1" ) ); + assertTrue( bsvc.performComparisons( "9999901", "1.2.1" ) ); // Test situations with prerelease tagging: // First test that these are equal and returns a value of false: - assertFalse( bssvc.performComparisons( "1.2.3-alpha.1", + assertFalse( bsvc.performComparisons( "1.2.3-alpha.1", "1.2.3-alpha.1" ) ); // Newer has alpha.2 and should return true: - assertTrue( bssvc.performComparisons( "1.2.3-alpha.1", + assertTrue( bsvc.performComparisons( "1.2.3-alpha.1", "1.2.3-alpha.2" ) ); // current has alpha.2 and should return false: - assertFalse( bssvc.performComparisons( "1.2.3-alpha.2", + assertFalse( bsvc.performComparisons( "1.2.3-alpha.2", "1.2.3-alpha.1" ) ); // Current has alpha.1 and newer has full release, should return true: - assertTrue( bssvc.performComparisons( "1.2.3-alpha.1", + assertTrue( bsvc.performComparisons( "1.2.3-alpha.1", "1.2.3" ) ); // Newer has alpha.1 and should return false since full release is ranked // higher than prerelease: - assertFalse( bssvc.performComparisons( "1.2.3", + assertFalse( bsvc.performComparisons( "1.2.3", "1.2.3-alpha.1" ) ); - assertTrue( bssvc.performComparisons( "1.16.5", "1.17" ) ); - assertTrue( bssvc.performComparisons( "1.16.5", "1.17.0" ) ); + assertTrue( bsvc.performComparisons( "1.16.5", "1.17" ) ); + assertTrue( bsvc.performComparisons( "1.16.5", "1.17.0" ) ); } @Test public void test02() { - BluesSpigetSemVerComparator bssvc = new BluesSpigetSemVerComparator(); + BluesSemanticVersionComparator bsvc = new BluesSemanticVersionComparator(); String paperTest = "Minecraft version: git-Paper-21 (MC: 1.15)"; - assertEquals( "1.15", bssvc.getBukkitVersion( paperTest ) ); + assertEquals( "1.15", bsvc.getBukkitVersion( paperTest ) ); } } 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 9d0492ce4..85e526e99 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 @@ -67,8 +67,8 @@ import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; import tech.mcprison.prison.autofeatures.AutoFeaturesWrapper; import tech.mcprison.prison.backpacks.BackpackEnums.BackpackType; -import tech.mcprison.prison.bombs.MineBombEffectsData; import tech.mcprison.prison.backpacks.PlayerBackpack; +import tech.mcprison.prison.bombs.MineBombEffectsData; import tech.mcprison.prison.chat.FancyMessage; import tech.mcprison.prison.commands.PluginCommand; import tech.mcprison.prison.convert.ConversionManager; @@ -141,12 +141,12 @@ import tech.mcprison.prison.spigot.scoreboard.SpigotScoreboardManager; import tech.mcprison.prison.spigot.sellall.SellAllBlockData; import tech.mcprison.prison.spigot.sellall.SellAllUtil; -import tech.mcprison.prison.spigot.spiget.BluesSpigetSemVerComparator; import tech.mcprison.prison.spigot.util.ActionBarUtil; import tech.mcprison.prison.spigot.util.SpigotYamlFileIO; import tech.mcprison.prison.spigot.utils.PrisonUtilsMineBombs; import tech.mcprison.prison.spigot.utils.tasks.PlayerAutoRankupTask; import tech.mcprison.prison.store.Storage; +import tech.mcprison.prison.util.BluesSemanticVersionComparator; import tech.mcprison.prison.util.Bounds.Edges; import tech.mcprison.prison.util.Location; import tech.mcprison.prison.util.PrisonJarReporter; @@ -948,7 +948,7 @@ public SpigotPlaceholders getPlaceholders() { public YamlFileIO getYamlFileIO( File yamlFile ) { boolean supportsDropsCanceling = - ( new BluesSpigetSemVerComparator().compareMCVersionTo("1.12.0") >= 0 ); + ( new BluesSemanticVersionComparator().compareMCVersionTo("1.12.0") >= 0 ); return new SpigotYamlFileIO( yamlFile, supportsDropsCanceling ); @@ -2894,7 +2894,7 @@ public String dumpEventListenersPlayerChatEvents() { sb.append( eventDisplay.toStringBuilder() ); } - if ( new BluesSpigetSemVerComparator().compareMCVersionTo("1.17.0") < 0 ) { + if ( new BluesSemanticVersionComparator().compareMCVersionTo("1.17.0") < 0 ) { eventDisplay = dumpEventListenersChatDisplay( "PlayerChatEvent", @@ -3282,7 +3282,7 @@ public void setActionBar( Player player, String actionBar ) { @Override public int compareServerVerisonTo( String comparisonVersion ) { - return new BluesSpigetSemVerComparator().compareMCVersionTo( comparisonVersion ); + return new BluesSemanticVersionComparator().compareMCVersionTo( comparisonVersion ); } @Override 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 61b90adac..0a924ff4b 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 @@ -50,11 +50,11 @@ import tech.mcprison.prison.spigot.game.SpigotHandlerList; import tech.mcprison.prison.spigot.game.SpigotPlayer; import tech.mcprison.prison.spigot.sellall.SellAllUtil; -import tech.mcprison.prison.spigot.spiget.BluesSpigetSemVerComparator; import tech.mcprison.prison.spigot.utils.tasks.PlayerAutoRankupTask; import tech.mcprison.prison.tasks.PrisonCommandTaskData; import tech.mcprison.prison.tasks.PrisonCommandTaskData.TaskMode; import tech.mcprison.prison.tasks.PrisonCommandTasks; +import tech.mcprison.prison.util.BluesSemanticVersionComparator; import tech.mcprison.prison.util.Text; /** @@ -1701,12 +1701,12 @@ private void notifyPlayerWithSound( Player player, String message ) { if ( sound == null ) { - if ( new BluesSpigetSemVerComparator().compareMCVersionTo( "1.9.0" ) < 0 ) { + if ( new BluesSemanticVersionComparator().compareMCVersionTo( "1.9.0" ) < 0 ) { // 1.8.x sound = getSound("NOTE_PLING"); } - else if ( new BluesSpigetSemVerComparator().compareMCVersionTo( "1.13.0" ) < 0 ) { + else if ( new BluesSemanticVersionComparator().compareMCVersionTo( "1.13.0" ) < 0 ) { // 1.9.x through 1.12.x sound = getSound("BLOCK_NOTE_PLING"); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakExternalEvents.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakExternalEvents.java index 5bed7545c..47e81d68c 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakExternalEvents.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakExternalEvents.java @@ -11,7 +11,7 @@ import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig; import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; import tech.mcprison.prison.autofeatures.AutoFeaturesWrapper; -import tech.mcprison.prison.spigot.spiget.BluesSpigetSemVerComparator; +import tech.mcprison.prison.util.BluesSemanticVersionComparator; public class OnBlockBreakExternalEvents { @@ -41,7 +41,7 @@ private OnBlockBreakExternalEvents() { super(); // if mc version is greater than or equal to 1.13.0. - if ( new BluesSpigetSemVerComparator().compareMCVersionTo("1.13.0") >= 0 ) { + if ( new BluesSemanticVersionComparator().compareMCVersionTo("1.13.0") >= 0 ) { this.isDropItemsSupported = true; } 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 ce98af5fa..f0e217d0c 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 @@ -1,8 +1,8 @@ package tech.mcprison.prison.spigot.compat; import tech.mcprison.prison.output.Output; -import tech.mcprison.prison.spigot.spiget.BluesSemanticVersionData; -import tech.mcprison.prison.spigot.spiget.BluesSpigetSemVerComparator; +import tech.mcprison.prison.util.BluesSemanticVersionComparator; +import tech.mcprison.prison.util.BluesSemanticVersionData; public class SpigotCompatibility { @@ -23,7 +23,7 @@ private static synchronized void setup() { Compatibility results = null; - String bukkitVersion = new BluesSpigetSemVerComparator().getBukkitVersion(); + String bukkitVersion = new BluesSemanticVersionComparator().getBukkitVersion(); if ( bukkitVersion == null ) { diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/customblock/CustomItems.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/customblock/CustomItems.java index 63debc9c5..4fb341ebf 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/customblock/CustomItems.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/customblock/CustomItems.java @@ -15,7 +15,7 @@ import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.block.SpigotItemStack; import tech.mcprison.prison.spigot.game.SpigotPlayer; -import tech.mcprison.prison.spigot.spiget.BluesSpigetSemVerComparator; +import tech.mcprison.prison.util.BluesSemanticVersionComparator; import tech.mcprison.prison.util.Location; /** @@ -35,7 +35,7 @@ public CustomItems() { @Override public void integrate() { - BluesSpigetSemVerComparator semVer = new BluesSpigetSemVerComparator(); + BluesSemanticVersionComparator semVer = new BluesSemanticVersionComparator(); if ( isRegistered()) { try { diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/VaultEconomyWrapper.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/VaultEconomyWrapper.java index 540a96036..63f859400 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/VaultEconomyWrapper.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/VaultEconomyWrapper.java @@ -12,7 +12,7 @@ import tech.mcprison.prison.internal.Player; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.spigot.SpigotUtil; -import tech.mcprison.prison.spigot.spiget.BluesSpigetSemVerComparator; +import tech.mcprison.prison.util.BluesSemanticVersionComparator; /** *

Prison does not support banks since the only way to identify a bank is through @@ -52,7 +52,7 @@ public VaultEconomyWrapper(String providerName ) { Bukkit.getPluginManager().getPlugin( getProviderName() ) .getDescription().getVersion(); - this.preV1dot4 = ( new BluesSpigetSemVerComparator().compareTo( getVaultVersion(), + this.preV1dot4 = ( new BluesSemanticVersionComparator().compareTo( getVaultVersion(), "1.4.0" ) < 0 ); // Output.get().logInfo( "### VaultEconomyWrapper : vaultVersion = " + getVaultVersion() + 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 7045a84d4..7a1f66a0d 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 @@ -21,7 +21,7 @@ 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; +import tech.mcprison.prison.util.BluesSemanticVersionData; public class SlimeBlockFunEventListener implements Listener { diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/spiget/BluesSpigetSemVerComparator.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/spiget/BluesSpigetSemVerComparator.java index 000e53522..c2b235d9b 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/spiget/BluesSpigetSemVerComparator.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/spiget/BluesSpigetSemVerComparator.java @@ -1,8 +1,9 @@ package tech.mcprison.prison.spigot.spiget; -import org.bukkit.Bukkit; import org.inventivetalent.update.spiget.comparator.VersionComparator; +import tech.mcprison.prison.util.BluesSemanticVersionComparator; + /** *

This class provides a real comparator for semantic versioning * for spiget. This addresses issues seen with incorrect notifications. @@ -40,124 +41,127 @@ public class BluesSpigetSemVerComparator @Override public boolean isNewer(String currentVersion, String checkVersion) { - return performComparisons( currentVersion, checkVersion); - } - - /** - *

This function will take two String values and convert both to a - * SemanticVersioningData objects, that in turn, will parse the string - * and encapsulate the full representation as an object. Since this object - * implements comparable, its then as simple as comparing the new semVer to the - * current semVer to find out if it is actually newer. - *

- * - *

The semantic versions must be valid. At a minimum they have to - * have a format such as 1.0.0. If one is invalid, then compareTo will - * favor the valid semVer. If both are invalid then compareTo will return - * a negative -1000, which will equate to false result. - *

- * - * @param currentVersion A String value representing the current semVer - * @param checkVersion A String value representing the checked semVer - * @return True if the checkVersion is a higher semVer than the current version - */ - public boolean performComparisons( String currentVersion, String checkVersion ) { - - BluesSemanticVersionData currentSemVer = new BluesSemanticVersionData(currentVersion); - BluesSemanticVersionData checkSemVer = new BluesSemanticVersionData(checkVersion); - - return (checkSemVer.compareTo( currentSemVer ) > 0); - } - - /** - *

Example how to use: - *

- * - *
-	 * String ver = Bukkit.getVersion().trim();
-	 * ver = ver.substring( ver.indexOf("(MC: ") + 5, ver.length() -1 );
-	 * if ( new BluesSpigetSemVerComparator().compareTo(ver, "1.9.0") ) {
-	 *     // if mc version is less than 1.9.0
-	 * }
-	 * 
- * - * @param currentVersion - * @param checkVersion - * @return - */ - public int compareTo( String currentVersion, String checkVersion ) { + BluesSemanticVersionComparator semVer = new BluesSemanticVersionComparator(); - BluesSemanticVersionData currentSemVer = new BluesSemanticVersionData(currentVersion); - BluesSemanticVersionData checkSemVer = new BluesSemanticVersionData(checkVersion); - - return currentSemVer.compareTo( checkSemVer ); - } - - /** - *

This uses the minecraft version of the server to compare to the provided version. - *

- * - *

Samples of what a bukkit, spigot, and paper version would look like. Notice - * they all have the version at the end between (MC: and ). - *

- * - *
    - *
  • Spigot 1.8.8: git-Spigot-21fe707-e1ebe52 (MC: 1.8.8)
  • - *
  • Spigot 1.10.2: git-Spigot-de459a2-51263e9 (MC: 1.10.2)
  • - *
  • Spigot 1.12.2: git-Spigot-79a30d7-acbc348 (MC: 1.12.2)
  • - *
  • Spigot 1.15.2: git-Spigot-2040c4c-893ad93 (MC: 1.15.2)
  • - *
  • Paper 1.10.2: git-Paper-916.2 (MC: 1.10.2)
  • - *
  • Paper 1.14.2: git-Paper-234 (MC: 1.14.4)
  • - *
- * - * *

Example how to use: - *

- * - *
-	 * if ( new BluesSpigetSemVerComparator().compareMCVersionTo("1.9.0") < 0 ) {
-	 *     // if mc version is less than 1.9.0
-	 * }
-	 * 
- * - * @param checkVersion - * @return - */ - public int compareMCVersionTo( String checkVersion ) { - int results = -1; - String currentVersion = getBukkitVersion(); - if ( currentVersion != null ) { - - results = compareTo( currentVersion, checkVersion ); - } - return results; + return semVer.performComparisons(currentVersion, checkVersion); +// return performComparisons( currentVersion, checkVersion); } - public String getBukkitVersion() { - // Minecraft version: git-Paper-21 (MC: 1.15) - - return getBukkitVersion( getBukkitVersionRaw() ); - } - private String getBukkitVersionRaw() { - return Bukkit.getVersion(); - } - - protected String getBukkitVersion( String currentVersion ) { - String results = null; - - if ( currentVersion != null ) { - currentVersion = currentVersion.trim().toLowerCase(); - int i = currentVersion.indexOf("(mc:"); - int len = currentVersion.length(); - if ( i >= 0 && (i+4 < len)) { - results = currentVersion.substring( i + 4, len - 1 ).trim(); - } - } - -// if ( results != null && "1.17".equals( results ) ) { -// results = "1.17.0"; +// /** +// *

This function will take two String values and convert both to a +// * SemanticVersioningData objects, that in turn, will parse the string +// * and encapsulate the full representation as an object. Since this object +// * implements comparable, its then as simple as comparing the new semVer to the +// * current semVer to find out if it is actually newer. +// *

+// * +// *

The semantic versions must be valid. At a minimum they have to +// * have a format such as 1.0.0. If one is invalid, then compareTo will +// * favor the valid semVer. If both are invalid then compareTo will return +// * a negative -1000, which will equate to false result. +// *

+// * +// * @param currentVersion A String value representing the current semVer +// * @param checkVersion A String value representing the checked semVer +// * @return True if the checkVersion is a higher semVer than the current version +// */ +// public boolean performComparisons( String currentVersion, String checkVersion ) { +// +// BluesSemanticVersionData currentSemVer = new BluesSemanticVersionData(currentVersion); +// BluesSemanticVersionData checkSemVer = new BluesSemanticVersionData(checkVersion); +// +// return (checkSemVer.compareTo( currentSemVer ) > 0); +// } +// +// /** +// *

Example how to use: +// *

+// * +// *
+//	 * String ver = Bukkit.getVersion().trim();
+//	 * ver = ver.substring( ver.indexOf("(MC: ") + 5, ver.length() -1 );
+//	 * if ( new BluesSpigetSemVerComparator().compareTo(ver, "1.9.0") ) {
+//	 *     // if mc version is less than 1.9.0
+//	 * }
+//	 * 
+// * +// * @param currentVersion +// * @param checkVersion +// * @return +// */ +// public int compareTo( String currentVersion, String checkVersion ) { +// +// BluesSemanticVersionData currentSemVer = new BluesSemanticVersionData(currentVersion); +// BluesSemanticVersionData checkSemVer = new BluesSemanticVersionData(checkVersion); +// +// return currentSemVer.compareTo( checkSemVer ); +// } +// +// /** +// *

This uses the minecraft version of the server to compare to the provided version. +// *

+// * +// *

Samples of what a bukkit, spigot, and paper version would look like. Notice +// * they all have the version at the end between (MC: and ). +// *

+// * +// *
    +// *
  • Spigot 1.8.8: git-Spigot-21fe707-e1ebe52 (MC: 1.8.8)
  • +// *
  • Spigot 1.10.2: git-Spigot-de459a2-51263e9 (MC: 1.10.2)
  • +// *
  • Spigot 1.12.2: git-Spigot-79a30d7-acbc348 (MC: 1.12.2)
  • +// *
  • Spigot 1.15.2: git-Spigot-2040c4c-893ad93 (MC: 1.15.2)
  • +// *
  • Paper 1.10.2: git-Paper-916.2 (MC: 1.10.2)
  • +// *
  • Paper 1.14.2: git-Paper-234 (MC: 1.14.4)
  • +// *
+// * +// * *

Example how to use: +// *

+// * +// *
+//	 * if ( new BluesSpigetSemVerComparator().compareMCVersionTo("1.9.0") < 0 ) {
+//	 *     // if mc version is less than 1.9.0
+//	 * }
+//	 * 
+// * +// * @param checkVersion +// * @return +// */ +// public int compareMCVersionTo( String checkVersion ) { +// int results = -1; +// String currentVersion = getBukkitVersion(); +// if ( currentVersion != null ) { +// +// results = compareTo( currentVersion, checkVersion ); // } - - return results; - } +// return results; +// } +// +// public String getBukkitVersion() { +// // Minecraft version: git-Paper-21 (MC: 1.15) +// +// return getBukkitVersion( getBukkitVersionRaw() ); +// } +// private String getBukkitVersionRaw() { +// return Bukkit.getVersion(); +// } +// +// protected String getBukkitVersion( String currentVersion ) { +// String results = null; +// +// if ( currentVersion != null ) { +// currentVersion = currentVersion.trim().toLowerCase(); +// int i = currentVersion.indexOf("(mc:"); +// int len = currentVersion.length(); +// if ( i >= 0 && (i+4 < len)) { +// results = currentVersion.substring( i + 4, len - 1 ).trim(); +// } +// } +// +//// if ( results != null && "1.17".equals( results ) ) { +//// results = "1.17.0"; +//// } +// +// return results; +// } } 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 cd441533c..ae552f8ef 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 @@ -47,7 +47,7 @@ import tech.mcprison.prison.spigot.game.SpigotWorld; import tech.mcprison.prison.spigot.inventory.SpigotPlayerInventory; import tech.mcprison.prison.spigot.nbt.PrisonNBTUtil; -import tech.mcprison.prison.spigot.spiget.BluesSpigetSemVerComparator; +import tech.mcprison.prison.util.BluesSemanticVersionComparator; import tech.mcprison.prison.util.Bounds; import tech.mcprison.prison.util.Location; import tech.mcprison.prison.util.Text; @@ -458,7 +458,7 @@ public void utilsMineBombsList( CommandSender sender, // Effect.values() // If running less than MC 1.9.0, ie 1.8.x, then use different code for effects: - boolean is18 = new BluesSpigetSemVerComparator().compareMCVersionTo( "1.9.0" ) < 0 ; + boolean is18 = new BluesSemanticVersionComparator().compareMCVersionTo( "1.9.0" ) < 0 ; if ( is18 ) { for ( Effect p : Effect.values() ) { @@ -1288,7 +1288,7 @@ else if ( mineBombEffect == null ) { // 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 ; + boolean is1_8 = new BluesSemanticVersionComparator().compareMCVersionTo( "1.9.0" ) < 0 ; if ( is1_8 ) { for ( Effect p : Effect.values() ) { @@ -1375,7 +1375,7 @@ else if ( mbObjectType.equalsIgnoreCase( "visuals" ) ) { // 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 ; + boolean is1_8 = new BluesSemanticVersionComparator().compareMCVersionTo( "1.9.0" ) < 0 ; if ( is1_8 ) { for ( Effect p : Effect.values() ) { diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTasks.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTasks.java index a50a06d04..3789d0c58 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTasks.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTasks.java @@ -34,7 +34,7 @@ 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.spiget.BluesSpigetSemVerComparator; +import tech.mcprison.prison.util.BluesSemanticVersionComparator; import tech.mcprison.prison.util.Location; import tech.mcprison.prison.util.Text; @@ -158,7 +158,7 @@ public void submitBombEffects( MineBombData bomb, EffectState effectState, Locat // If running MC 1.9.0 or higher, then can use the glowing feature. Ignore for 1.8.x. - boolean is18 = new BluesSpigetSemVerComparator().compareMCVersionTo( "1.9.0" ) < 0 ; + boolean is18 = new BluesSemanticVersionComparator().compareMCVersionTo( "1.9.0" ) < 0 ; SpigotBlock sBlock = (SpigotBlock) location.getBlockAt(); org.bukkit.Location bLocation = sBlock.getWrapper().getLocation(); @@ -569,7 +569,7 @@ private void initializeArmorStand() { armorStand.setRightArmPose(arm); - if ( new BluesSpigetSemVerComparator().compareMCVersionTo( "1.9.0" ) >= 0 ) { + if ( new BluesSemanticVersionComparator().compareMCVersionTo( "1.9.0" ) >= 0 ) { armorStand.setGlowing( bomb.isGlowing() ); From 2c29285284e6e3e8ee9c4954df2168974a4e9d6d Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 3 Jul 2024 20:30:06 -0400 Subject: [PATCH 047/323] Updated XSeries to v11.2.0 from v11.1.0. Update Papi to v2.11.6 from v2.11.5. --- docs/changelog_v3.3.x.md | 8 ++++++++ gradle/libs.versions.toml | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 7d26d863a..d04ebcb57 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,14 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.18b 2024-07-03 +* **Updated XSeries to v11.2.0 from v11.1.0.** +* **Update Papi to v2.11.6 from v2.11.5.** + + +* **Prison semantic version: Moved the code of prison's semantic version tools to the prison-core module.** +This was needed to be used within the core, so it's movement and the elimination of dependencies on spiget was beneficial. + + * **Sellall: when sellall message delay is enabled for autosell, changed it to when the player does `/sellall sell` it reports the sale for that transaction instead of waiting until 15 to 20 seconds later.** diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 31462e4ef..92c5b07e0 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -34,13 +34,13 @@ commons-lang3 = "3.12.0" groovy = "3.0.9" gson = "2.10.1" spiget = "1.4.6-SNAPSHOT" -xseries = "11.1.0" +xseries = "11.2.0" junit = "4.12" guava = "31.1-jre" spigotApi = "1.13.2-R0.1-SNAPSHOT" nbtApi = "2.13.1" -papi = "2.11.5" +papi = "2.11.6" vault = "1.7.1" luckperms-v4 = "4.4" From 319c4d42d14abb2c4bcb47eb8850e41beca512ef Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 5 Jul 2024 13:39:09 -0400 Subject: [PATCH 048/323] Prison Bomb Animations: Initial setup and switch over to use the new prison bomb animations. Non-functional. This state of development has the animations working, but the bomb's actual explosions are not yet enabled, so this commit is non-functional. It's being committed due to the number of classes changed and for how much is working well too. The animations were pushed back to core so that way it's not more code that is being crammed within the spigot module, which was originally intended to be a light weight layer sitting between the actual prison code, and the platform. The animations are designed so that there can be a number of variations created, and then they would be available to use with the mine bomb configs. --- docs/changelog_v3.3.x.md | 8 +- .../tech/mcprison/prison/bombs/MineBombs.java | 1 + .../animations/BombAnimationInfinity.java | 158 +++++++ .../bombs/animations/BombAnimations.java | 167 ++++++++ .../bombs/animations/BombAnimationsTask.java | 138 +++++++ .../mcprison/prison/internal/ArmorStand.java | 30 ++ .../mcprison/prison/internal/EntityType.java | 2 + .../mcprison/prison/internal/EulerAngle.java | 64 +++ .../tech/mcprison/prison/internal/World.java | 9 + .../tech/mcprison/prison/util/Location.java | 14 + .../java/tech/mcprison/prison/TestWorld.java | 12 + .../prison/ranks/data/RankPlayerFactory.java | 2 - .../prison/spigot/game/SpigotLocation.java | 33 +- .../prison/spigot/game/SpigotWorld.java | 47 +++ .../spigot/game/entity/SpigotArmorStand.java | 91 ++++ .../game/{ => entity}/SpigotEntity.java | 5 +- .../game/{ => entity}/SpigotEntityType.java | 14 +- .../spigot/utils/PrisonUtilsMineBombs.java | 19 +- .../utils/PrisonUtilsMineBombsTasks.java | 389 +++++++++--------- 19 files changed, 998 insertions(+), 205 deletions(-) create mode 100644 prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationInfinity.java create mode 100644 prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java create mode 100644 prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationsTask.java create mode 100644 prison-core/src/main/java/tech/mcprison/prison/internal/ArmorStand.java create mode 100644 prison-core/src/main/java/tech/mcprison/prison/internal/EulerAngle.java create mode 100644 prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotArmorStand.java rename prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/{ => entity}/SpigotEntity.java (96%) rename prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/{ => entity}/SpigotEntityType.java (73%) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index d04ebcb57..965e54999 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.18b 2024-07-03 +# 3.3.0-alpha.18b 2024-07-05 + + +* **Prison Bomb Animations: Initial setup and switch over to use the new prison bomb animations. Non-functional.** +This state of development has the animations working, but the bomb's actual explosions are not yet enabled, so this commit is non-functional. It's being committed due to the number of classes changed and for how much is working well too. +The animations were pushed back to core so that way it's not more code that is being crammed within the spigot module, which was originally intended to be a light weight layer sitting between the actual prison code, and the platform. +The animations are designed so that there can be a number of variations created, and then they would be available to use with the mine bomb configs. * **Updated XSeries to v11.2.0 from v11.1.0.** 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 aad7ce912..6fe590dbb 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 @@ -85,6 +85,7 @@ public enum ExplosionOrientation { public enum AnimationPattern { none, infinity, + infinityEight, bounce, orbital diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationInfinity.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationInfinity.java new file mode 100644 index 000000000..53fa65e1b --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationInfinity.java @@ -0,0 +1,158 @@ +package tech.mcprison.prison.bombs.animations; + +import tech.mcprison.prison.bombs.MineBombData; +import tech.mcprison.prison.internal.ArmorStand; +import tech.mcprison.prison.internal.EulerAngle; +import tech.mcprison.prison.internal.ItemStack; +import tech.mcprison.prison.internal.block.PrisonBlock; +import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.util.BluesSemanticVersionComparator; +import tech.mcprison.prison.util.Location; + +public class BombAnimationInfinity + extends BombAnimations { + + + private double eulerAngleX = 1.0; + private double eulerAngleY = 0; + private double eulerAngleZ = 0; + + private double twoPI; + + private ArmorStand armorStand; + + private float entityYaw; + private float entityPitch; + + private int id; + + + public BombAnimationInfinity( MineBombData bomb, + PrisonBlock sBombBlock, ItemStack item, + BombAnimationsTask task, + float entityYaw, float entityPitch ) { + super( bomb, sBombBlock, item, task ); + + this.entityYaw = entityYaw; + this.entityPitch = entityPitch; + + initialize(); + } + + + + public void initialize() { + + this.twoPI = Math.PI * 2; + + setId( getTask().getAnimators().size() ); + + initializeArmorStand(); + } + + private void initializeArmorStand() { + + Location location = getsBlock().getLocation(); + location.setY( location.getY() + 2.5 ); + + location.setYaw( entityYaw ); + location.setPitch( entityPitch + 90 ); + + + double startingAngle = ( 360d / entityYaw ) * twoPI; + +// eulerAngleX += startingAngle; + + EulerAngle arm = new EulerAngle( eulerAngleX + startingAngle, eulerAngleY + startingAngle, eulerAngleZ + startingAngle ); + + + armorStand = location.spawnArmorStand(); + + if ( armorStand != null ) { + + armorStand.setVisible(false); + armorStand.setRemoveWhenFarAway(false); + armorStand.setItemInHand( getItem() ); + armorStand.setRightArmPose(arm); + + + if ( initializeCustomName() ) { + + //updateArmorStandCustomName(); + armorStand.setCustomName( getTagName() ); + armorStand.setCustomNameVisible(true); + } + else { + + armorStand.setCustomNameVisible(false); + } + + if ( new BluesSemanticVersionComparator().compareMCVersionTo( "1.9.0" ) >= 0 ) { + + armorStand.setGlowing( getBomb().isGlowing() ); + + // setGravity is invalid for spigot 1.8.8: + armorStand.setGravity( getBomb().isGravity() ); + } + } + + if ( Output.get().isDebug() ) { + String msg = String.format( + "### BombAnimationInfinity.initializeArmorStand : id: %s ", + Integer.toString(getId()) + + ); + Output.get().logInfo( msg ); + } + } + + + + + @Override + public void step() + { + + double speed = 0.35; + + eulerAngleX += speed; + eulerAngleY += speed / 3; + eulerAngleZ += speed / 5; + + + EulerAngle arm = new EulerAngle( eulerAngleX, eulerAngleY, eulerAngleZ ); + + armorStand.setRightArmPose(arm); + + + if ( eulerAngleX > twoPI ) { + eulerAngleX -= twoPI; + } + if ( eulerAngleY > twoPI ) { + eulerAngleY -= twoPI; + } + if ( eulerAngleZ > twoPI ) { + eulerAngleZ -= twoPI; + } + + + // Track the time that this has lived: + if ( --terminateOnZeroTicks == 0 || !armorStand.isValid() ) { + + armorStand.remove(); + + cancel(); + } + + updateCustomName(); + + } + + public int getId() { + return id; + } + public void setId(int id) { + this.id = id; + } + +} diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java new file mode 100644 index 000000000..aee0ab9e9 --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java @@ -0,0 +1,167 @@ +package tech.mcprison.prison.bombs.animations; + +import java.text.DecimalFormat; + +import tech.mcprison.prison.Prison; +import tech.mcprison.prison.bombs.MineBombData; +import tech.mcprison.prison.internal.ItemStack; +import tech.mcprison.prison.internal.block.PrisonBlock; +import tech.mcprison.prison.util.Text; + +public abstract class BombAnimations { + + private BombAnimationsTask task; + + private MineBombData bomb; + private PrisonBlock sBlock; + private ItemStack item; + + + private boolean isDyanmicTag = false; + private String tagName; + +// long ageTicks = 0L; + long terminateOnZeroTicks = 0L; + + private DecimalFormat dFmt; + + + public BombAnimations( MineBombData bomb, + PrisonBlock sBombBlock, + ItemStack item, + BombAnimationsTask task ) { + super(); + + // Used for "canceling" the task: + this.task = task; + + this.bomb = bomb; + this.sBlock = sBombBlock; + this.item = item; + +// this.ageTicks = 0; + this.terminateOnZeroTicks = getTaskLifeSpan(); + + this.isDyanmicTag = bomb.getNameTag().contains( "{countdown}" ); + this.tagName = ""; + + this.dFmt = Prison.get().getDecimalFormat( "0.0" ); + + // initialize(); + } + + protected void cancel() { + task.cancel(); + } + + public abstract void initialize(); + + + public abstract void step(); + + + /** + *

This will calculate how long the placed item needs to + * exist before removal, and this task will remove itself. + * While this item is placed, this task will run every 2 + * ticks and will spin the item in 3d space. + *

+ * + *

Removal is based upon the fuseDelayTicks which will take it to + * the explosion, then scanning the final effects to find how long + * the last one will be submitted for. Then add 15 ticks. + *

+ * + *

At this time, not 100% sure if this item or armor stand + * will be used to "place" the effects. Probably not. If it's not + * needed, then this can be removed when the explosions start. + *

+ * + * @return + */ + protected long getTaskLifeSpan() + { + int removeInTicks = bomb.getFuseDelayTicks() + bomb.getItemRemovalDelayTicks(); + return removeInTicks; + } + + + protected boolean initializeCustomName() { + boolean results = false; + + if ( getBomb().getNameTag() != null && + !getBomb().getNameTag().trim().isEmpty() ) { + + String tagName = getBomb().getNameTag(); + if ( tagName.contains( "{name}" ) ) { + tagName = tagName.replace( "{name}", getBomb().getName() ); + } + setTagName( Text.translateAmpColorCodes( tagName ) ); + } + + return results; + } + + protected void updateCustomName() + { + if ( isDyanmicTag ) { + + double countdown = (terminateOnZeroTicks / 20.0d); + String tagName = this.tagName.replace( "{countdown}", dFmt.format( countdown) ); + + setTagName( tagName ); +// armorStand.setCustomName( tagName ); + } + } + + + public BombAnimationsTask getTask() { + return task; + } + public void setTask(BombAnimationsTask task) { + this.task = task; + } + + public MineBombData getBomb() { + return bomb; + } + public void setBomb(MineBombData bomb) { + this.bomb = bomb; + } + + public PrisonBlock getsBlock() { + return sBlock; + } + public void setsBlock(PrisonBlock sBlock) { + this.sBlock = sBlock; + } + + public ItemStack getItem() { + return item; + } + public void setItem(ItemStack item) { + this.item = item; + } + + public boolean isDyanmicTag() { + return isDyanmicTag; + } + public void setDyanmicTag(boolean isDyanmicTag) { + this.isDyanmicTag = isDyanmicTag; + } + + public String getTagName() { + return tagName; + } + public void setTagName(String tagName) { + this.tagName = tagName; + } + + public long getTerminateOnZeroTicks() { + return terminateOnZeroTicks; + } + public void setTerminateOnZeroTicks(long terminateOnZeroTicks) { + this.terminateOnZeroTicks = terminateOnZeroTicks; + } + +} diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationsTask.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationsTask.java new file mode 100644 index 000000000..4d9862b38 --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationsTask.java @@ -0,0 +1,138 @@ +package tech.mcprison.prison.bombs.animations; + +import java.util.ArrayList; +import java.util.List; + +import tech.mcprison.prison.bombs.MineBombData; +import tech.mcprison.prison.bombs.MineBombs.AnimationPattern; +import tech.mcprison.prison.internal.ItemStack; +import tech.mcprison.prison.internal.block.PrisonBlock; +import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.tasks.PrisonRunnable; +import tech.mcprison.prison.tasks.PrisonTaskSubmitter; + +public class BombAnimationsTask + implements PrisonRunnable { + + private int taskId; + + private List animators; + + public BombAnimationsTask() { + super(); + + this.animators = new ArrayList<>(); + } + + + public void animatorFactory( + // AnimationPattern animation, + MineBombData bomb, PrisonBlock pBlock, ItemStack item ) { + + AnimationPattern animation = bomb.getAnimationPattern(); + + + + if ( Output.get().isDebug() ) { + String msg = String.format( + "### BombAnimationsTask.animmatorFactory : AnimationPattern: %s ", + animation.name() + + ); + Output.get().logInfo( msg ); + } + + + switch ( animation ) { + + case bounce: + + break; + + case infinity: + { + float yaw = 0; + float pitch = 0; + + BombAnimationInfinity bai = new BombAnimationInfinity( bomb, + pBlock, item, this, + yaw, pitch ); + + getAnimators().add( bai ); + submitTask(); + } + + break; + + case infinityEight: + { + float yaw = 0; + float pitch = 0; + float yawStep = 360f / 8f; + + for ( int i = 0; i < 8; i++ ) { + BombAnimationInfinity bai = new BombAnimationInfinity( bomb, + pBlock, item, this, + yaw, pitch ); + + getAnimators().add( bai ); + + yaw += yawStep; + } + + submitTask(); + } + + break; + + + case none: + default: + // Do nothing... do not submit task to run. + break; + } + } + + private void submitTask() { + + setTaskId( PrisonTaskSubmitter.runTaskTimer( this, 0L, 1L ) ); + + } + + protected void cancel() { + PrisonTaskSubmitter.cancelTask( getTaskId() ); + } + + + /** + * The animators will override this function. + */ + protected void initialize() { + } + + + @Override + public void run() { + + for ( BombAnimations animator : getAnimators() ) { + animator.step(); + } + + } + + + public int getTaskId() { + return taskId; + } + public void setTaskId(int taskId) { + this.taskId = taskId; + } + + public List getAnimators() { + return animators; + } + public void setAnimators(List animators) { + this.animators = animators; + } + +} diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/ArmorStand.java b/prison-core/src/main/java/tech/mcprison/prison/internal/ArmorStand.java new file mode 100644 index 000000000..6e24cf080 --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/ArmorStand.java @@ -0,0 +1,30 @@ +package tech.mcprison.prison.internal; + +public interface ArmorStand + extends Entity { + + + //public ArmorStand spawn(Location location); + + + public boolean isVisible(); + + public void setVisible( boolean visible ); + + public boolean getRemoveWhenFarAway(); + public void setRemoveWhenFarAway( boolean removeWhenFarAway ); + + public ItemStack getItemInHand(); + public void setItemInHand( ItemStack itemm ); + + + public void setRightArmPose( EulerAngle arm ); + + public boolean isGlowing(); + public void setGlowing( boolean glowing ); + + public boolean hasGravity(); + public void setGravity( boolean gravity ); + + +} diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/EntityType.java b/prison-core/src/main/java/tech/mcprison/prison/internal/EntityType.java index 20b3882d3..e15b4d062 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/EntityType.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/EntityType.java @@ -2,6 +2,8 @@ public class EntityType { + public static final EntityType ENTITY_TYPE_ARMOR_STAND = new EntityType( "ARMOR_STAND" ); + private String entityType; public EntityType( String entityType ) { diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/EulerAngle.java b/prison-core/src/main/java/tech/mcprison/prison/internal/EulerAngle.java new file mode 100644 index 000000000..321b404d3 --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/EulerAngle.java @@ -0,0 +1,64 @@ +package tech.mcprison.prison.internal; + +public class EulerAngle { + + private double x; + private double y; + private double z; + + public EulerAngle( double x, double y, double z ) { + super(); + + this.x = x; + this.y = y; + this.z = z; + } + + public EulerAngle add( double x, double y, double z ) { + EulerAngle ea = new EulerAngle( x + getX(), y + getY(), z + getZ() ); + return ea; + } + + public EulerAngle subtract( double x, double y, double z ) { + EulerAngle ea = new EulerAngle( getX() - x , getY() - y, getZ() - z ); + return ea; + } + + + public double getX() { + return x; + } + public double getY() { + return y; + } + public double getZ() { + return z; + } + + /** + * https://math.oxford.emory.edu/site/cs171/generatingHashCodes/ + */ + public int hashCode() { + int h = 17; + h = 31 * h + ((Double) getX()).hashCode(); + h = 31 * h + ((Double) getY()).hashCode(); + h = 31 * h + ((Double) getZ()).hashCode(); + + return h; + } + + public EulerAngle setX( double x ) { + EulerAngle ea = new EulerAngle( x, getY(), getZ() ); + return ea; + } + public EulerAngle setY( double y ) { + EulerAngle ea = new EulerAngle( getX(), y, getZ() ); + return ea; + } + public EulerAngle setZ( double z ) { + EulerAngle ea = new EulerAngle( getX() , getY(), z ); + return ea; + } + + +} diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/World.java b/prison-core/src/main/java/tech/mcprison/prison/internal/World.java index 36f00a1f0..00dece793 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/World.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/World.java @@ -79,5 +79,14 @@ public void setBlocksSynchronously( List tBlocks, MineResetType resetType, PrisonStatsElapsedTimeNanos nanos ); + + +// public Entity spawnEntity(EntityType entityType); + + public Entity spawnEntity( Location loc, EntityType entityType); + + + public ArmorStand spawnArmorStand( Location location ); + } 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 734a63a81..5aed5fb54 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 @@ -19,6 +19,9 @@ package tech.mcprison.prison.util; import tech.mcprison.prison.Prison; +import tech.mcprison.prison.internal.ArmorStand; +import tech.mcprison.prison.internal.Entity; +import tech.mcprison.prison.internal.EntityType; import tech.mcprison.prison.internal.World; import tech.mcprison.prison.internal.block.Block; import tech.mcprison.prison.internal.block.PrisonBlock; @@ -290,5 +293,16 @@ public Block getBlockAtDelta( int x, int y, int z ) return getWorld().getBlockAt( results ); } + + public Entity spawnEntity( EntityType entityType ) { + return getWorld().spawnEntity( this, entityType ); + } + + public ArmorStand spawnArmorStand() { + return getWorld().spawnArmorStand( this ); + } + + + } diff --git a/prison-core/src/test/java/tech/mcprison/prison/TestWorld.java b/prison-core/src/test/java/tech/mcprison/prison/TestWorld.java index d6944d59e..0be5d85e3 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/TestWorld.java +++ b/prison-core/src/test/java/tech/mcprison/prison/TestWorld.java @@ -21,7 +21,9 @@ import java.util.ArrayList; import java.util.List; +import tech.mcprison.prison.internal.ArmorStand; import tech.mcprison.prison.internal.Entity; +import tech.mcprison.prison.internal.EntityType; import tech.mcprison.prison.internal.Player; import tech.mcprison.prison.internal.PrisonStatsElapsedTimeNanos; import tech.mcprison.prison.internal.World; @@ -83,5 +85,15 @@ public List getEntities() { return new ArrayList<>(); } + @Override + public Entity spawnEntity( Location location, EntityType entityType ) { + return null; + } + + @Override + public ArmorStand spawnArmorStand(Location location) { + return null; + } + } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactory.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactory.java index e4f4e84d4..e38268999 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactory.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactory.java @@ -185,8 +185,6 @@ else if ( obj instanceof Double ) { } public static Document toDocument( RankPlayer rankPlayer ) { - JsonFileIO jfIO = new JsonFileIO(); - // Update some stats from the playerCache: PlayerCachePlayerData cacheData = rankPlayer.getPlayerCache().getOnlinePlayerCached(rankPlayer); rankPlayer.updateTotalLastValues( cacheData , false); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotLocation.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotLocation.java index 3768d291b..6eaa9cb97 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotLocation.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotLocation.java @@ -1,5 +1,7 @@ package tech.mcprison.prison.spigot.game; +import org.bukkit.Bukkit; + import tech.mcprison.prison.spigot.SpigotUtil; import tech.mcprison.prison.util.Location; @@ -8,6 +10,10 @@ public class SpigotLocation private org.bukkit.Location bukkitLocation; + public SpigotLocation( Location location ) { + super( location ); + } + public SpigotLocation( org.bukkit.Location bukkitLocation ) { super( SpigotUtil.bukkitLocationToPrison( bukkitLocation ) ); @@ -15,9 +21,32 @@ public SpigotLocation( org.bukkit.Location bukkitLocation ) { } public org.bukkit.Location getBukkitLocation() { + + if ( bukkitLocation == null ) { + bukkitLocation = createBukkitLocation(); + } + return bukkitLocation; } - public void setBukkitLocation(org.bukkit.Location bukkitLocation) { - this.bukkitLocation = bukkitLocation; + + private org.bukkit.Location createBukkitLocation() { + + org.bukkit.World world = Bukkit.getWorld( getWorld().getName() ); + + org.bukkit.Location bLocation = new org.bukkit.Location(world, getBlockX(), getBlockY(), getBlockZ() ); + + bLocation.setYaw(getYaw()); + + bLocation.setPitch(getPitch()); + + return bLocation; + } + +// public void setBukkitLocation(org.bukkit.Location bukkitLocation) { +// this.bukkitLocation = bukkitLocation; +// } + + public org.bukkit.World getBukkitWorld() { + return getBukkitLocation().getWorld(); } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotWorld.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotWorld.java index a8b36100a..6f55b4867 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotWorld.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotWorld.java @@ -27,6 +27,7 @@ import com.cryptomorin.xseries.XEntityType; +import tech.mcprison.prison.internal.ArmorStand; import tech.mcprison.prison.internal.Entity; import tech.mcprison.prison.internal.EntityType; import tech.mcprison.prison.internal.ItemStack; @@ -43,6 +44,9 @@ import tech.mcprison.prison.spigot.block.SpigotBlockSetSynchronously; import tech.mcprison.prison.spigot.block.SpigotItemStack; import tech.mcprison.prison.spigot.compat.SpigotCompatibility; +import tech.mcprison.prison.spigot.game.entity.SpigotArmorStand; +import tech.mcprison.prison.spigot.game.entity.SpigotEntity; +import tech.mcprison.prison.spigot.game.entity.SpigotEntityType; import tech.mcprison.prison.util.Location; /** @@ -261,6 +265,49 @@ public org.bukkit.World getWrapper() { return bukkitWorld; } + @Override + public Entity spawnEntity( Location location, EntityType entityType) { + + SpigotLocation sLocation = + ( location instanceof SpigotLocation ? + (SpigotLocation) location : + new SpigotLocation( location )); + + SpigotEntityType sEtityType = SpigotEntityType.getSpigotEntityType( entityType ); + + org.bukkit.entity.Entity bEntity = + ((SpigotWorld) sLocation.getWorld()).getWrapper().spawnEntity( + sLocation.getBukkitLocation(), sEtityType.getbEntityType() ); + + return new SpigotEntity( bEntity ); + } + + @Override + public ArmorStand spawnArmorStand( Location location ) { + Entity e = spawnEntity( location, SpigotEntityType.ENTITY_TYPE_ARMOR_STAND ); + SpigotEntity sEntity = (SpigotEntity) e; + + org.bukkit.entity.ArmorStand armorStand = (org.bukkit.entity.ArmorStand) sEntity.getBukkitEntity(); + SpigotArmorStand sArmorStand = new SpigotArmorStand( armorStand ); + + return sArmorStand; + } + + /** + * This creates a new instance of a SpigotWorld object based upon the world's name. + * This uses the 'org.bukkit.World.getWorld( worldName );' to return a bukkit world, + * then wrap it in a SpigotWorld object. + * + * @param worldName + * @return + */ + public static SpigotWorld getWorld(String worldName) { + + org.bukkit.World world = Bukkit.getWorld( worldName ); + + return new SpigotWorld( world ); + } + diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotArmorStand.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotArmorStand.java new file mode 100644 index 000000000..8c7a2fa84 --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotArmorStand.java @@ -0,0 +1,91 @@ +package tech.mcprison.prison.spigot.game.entity; + +import tech.mcprison.prison.internal.EulerAngle; +import tech.mcprison.prison.internal.ItemStack; +import tech.mcprison.prison.spigot.block.SpigotItemStack; + +public class SpigotArmorStand + extends SpigotEntity + implements tech.mcprison.prison.internal.ArmorStand +{ + + private org.bukkit.entity.ArmorStand bArmorStand; + + public SpigotArmorStand( org.bukkit.entity.ArmorStand bArmorStand ) { + super( bArmorStand ); + + this.bArmorStand = bArmorStand; + } + +// public static ArmorStand spawn( tech.mcprison.prison.util.Location location ) { +// tech.mcprison.prison.internal.Entity e = location.spawnEntity( SpigotEntityType.ENTITY_TYPE_ARMOR_STAND ); +// SpigotEntity sEntity = (SpigotEntity) e; +// +// org.bukkit.entity.ArmorStand armorStand = (org.bukkit.entity.ArmorStand) sEntity.getBukkitEntity(); +// SpigotArmorStand sArmorStand = new SpigotArmorStand( armorStand ); +// +// return sArmorStand; +// } + + @Override + public boolean isVisible() { + return bArmorStand.isVisible(); + } + + @Override + public void setVisible(boolean visible) { + bArmorStand.setVisible(visible); + } + + @Override + public boolean getRemoveWhenFarAway() { + return bArmorStand.getRemoveWhenFarAway(); + } + + @Override + public void setRemoveWhenFarAway(boolean removeWhenFarAway) { + bArmorStand.setRemoveWhenFarAway( removeWhenFarAway ); + } + + @Override + public ItemStack getItemInHand() { + return new SpigotItemStack( bArmorStand.getItemInHand() ); + } + + @Override + public void setItemInHand(ItemStack item) { + SpigotItemStack sItemStack = (SpigotItemStack) item; + bArmorStand.setItemInHand( sItemStack.getBukkitStack() ); + } + + @Override + public void setRightArmPose(EulerAngle arm) { + + org.bukkit.util.EulerAngle eAngle = new org.bukkit.util.EulerAngle( + arm.getX(), arm.getY(), arm.getZ() ); + + bArmorStand.setRightArmPose(eAngle); + } + + @Override + public boolean isGlowing() { + return bArmorStand.isGlowing(); + } + + @Override + public void setGlowing(boolean glowing) { + bArmorStand.setGlowing(glowing); + } + + @Override + public boolean hasGravity() { + return bArmorStand.hasGravity(); + } + + @Override + public void setGravity(boolean gravity) { + bArmorStand.setGravity(gravity); + } + + +} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotEntity.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotEntity.java similarity index 96% rename from prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotEntity.java rename to prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotEntity.java index 13f42d3c2..c04340b98 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotEntity.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotEntity.java @@ -1,4 +1,4 @@ -package tech.mcprison.prison.spigot.game; +package tech.mcprison.prison.spigot.game.entity; import java.util.ArrayList; import java.util.List; @@ -9,6 +9,9 @@ import tech.mcprison.prison.internal.Entity; import tech.mcprison.prison.internal.EntityType; import tech.mcprison.prison.internal.World; +import tech.mcprison.prison.spigot.game.SpigotCommandSender; +import tech.mcprison.prison.spigot.game.SpigotLocation; +import tech.mcprison.prison.spigot.game.SpigotWorld; import tech.mcprison.prison.util.Location; import tech.mcprison.prison.util.Vector; diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotEntityType.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotEntityType.java similarity index 73% rename from prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotEntityType.java rename to prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotEntityType.java index 0216facea..28beb7821 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotEntityType.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotEntityType.java @@ -1,4 +1,4 @@ -package tech.mcprison.prison.spigot.game; +package tech.mcprison.prison.spigot.game.entity; import com.cryptomorin.xseries.XEntityType; @@ -32,6 +32,18 @@ public SpigotEntityType( XEntityType xEType ) { this.bEntityType = xEType.get(); } + public static SpigotEntityType getSpigotEntityType( EntityType entityType ) { + SpigotEntityType results = null; + + XEntityType xEType = XEntityType.of( entityType.getEntityType().toUpperCase() ).orElse( null ); + + if ( xEType != null ) { + results = new SpigotEntityType( xEType ); + } + + return results; + } + public org.bukkit.entity.EntityType getbEntityType() { return bEntityType; } 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 ae552f8ef..764bc6903 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 @@ -26,6 +26,7 @@ import tech.mcprison.prison.bombs.MineBombEffectsData.EffectType; import tech.mcprison.prison.bombs.MineBombs; import tech.mcprison.prison.bombs.MineBombs.ExplosionShape; +import tech.mcprison.prison.bombs.animations.BombAnimationsTask; import tech.mcprison.prison.commands.Arg; import tech.mcprison.prison.commands.Command; import tech.mcprison.prison.commands.Wildcard; @@ -41,10 +42,10 @@ import tech.mcprison.prison.spigot.block.SpigotItemStack; import tech.mcprison.prison.spigot.compat.Compatibility.EquipmentSlot; import tech.mcprison.prison.spigot.compat.SpigotCompatibility; -import tech.mcprison.prison.spigot.game.SpigotEntity; -import tech.mcprison.prison.spigot.game.SpigotEntityType; import tech.mcprison.prison.spigot.game.SpigotPlayer; import tech.mcprison.prison.spigot.game.SpigotWorld; +import tech.mcprison.prison.spigot.game.entity.SpigotEntity; +import tech.mcprison.prison.spigot.game.entity.SpigotEntityType; import tech.mcprison.prison.spigot.inventory.SpigotPlayerInventory; import tech.mcprison.prison.spigot.nbt.PrisonNBTUtil; import tech.mcprison.prison.util.BluesSemanticVersionComparator; @@ -1120,12 +1121,18 @@ else if ( bomb != null ) { + // This setups the animations that are assigned to each bomb type and + // will submit the tasks, unless no animations are chosen. + BombAnimationsTask animationsTask = new BombAnimationsTask(); + + animationsTask.animatorFactory( bomb, bombBlock, itemInHand ); + - @SuppressWarnings( "unused" ) - PlacedMineBombItemTask submitPlacedMineBombItem = - submitPlacedMineBombItemTask( bomb, bombBlock, bombs ); +// @SuppressWarnings( "unused" ) +// PlacedMineBombItemTask submitPlacedMineBombItem = +// submitPlacedMineBombItemTask( bomb, bombBlock, bombs ); // placeMineBombItem( bomb, bombBlock, bombs ); // This places the item so it will float: @@ -1153,7 +1160,7 @@ else if ( bomb != null ) { // Submit the bomb's task to go off: - setoffBombDelayed( sPlayer, bomb, bombBlock ); + //setoffBombDelayed( sPlayer, bomb, bombBlock ); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTasks.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTasks.java index 3789d0c58..db670067d 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTasks.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTasks.java @@ -1,6 +1,5 @@ package tech.mcprison.prison.spigot.utils; -import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -11,22 +10,19 @@ import org.bukkit.Effect; import org.bukkit.Particle; import org.bukkit.enchantments.Enchantment; -import org.bukkit.entity.ArmorStand; import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.scheduler.BukkitTask; -import org.bukkit.util.EulerAngle; import com.cryptomorin.xseries.XMaterial; import com.cryptomorin.xseries.XSound; import com.cryptomorin.xseries.particles.ParticleDisplay; -import tech.mcprison.prison.Prison; import tech.mcprison.prison.bombs.MineBombData; import tech.mcprison.prison.bombs.MineBombEffectsData; import tech.mcprison.prison.bombs.MineBombEffectsData.EffectState; import tech.mcprison.prison.bombs.MineBombs; import tech.mcprison.prison.bombs.MineBombs.ExplosionOrientation; import tech.mcprison.prison.bombs.MineBombs.ExplosionShape; +import tech.mcprison.prison.bombs.animations.BombAnimationsTask; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.api.ExplosiveBlockBreakEvent; @@ -36,7 +32,6 @@ import tech.mcprison.prison.spigot.game.SpigotWorld; import tech.mcprison.prison.util.BluesSemanticVersionComparator; import tech.mcprison.prison.util.Location; -import tech.mcprison.prison.util.Text; public class PrisonUtilsMineBombsTasks extends PrisonUtils @@ -443,201 +438,211 @@ private List calculatBlocksForExplosion( MineBombData bo return results; } - public PlacedMineBombItemTask submitPlacedMineBombItemTask( MineBombData bomb, SpigotBlock sBlock, SpigotItemStack item ) { + public BombAnimationsTask submitPlacedMineBombItemTask( MineBombData bomb, SpigotBlock sBlock, SpigotItemStack item ) { - PlacedMineBombItemTask placedTask = new PlacedMineBombItemTask( bomb, sBlock, item ); - BukkitTask task = placedTask.runTaskTimer( - SpigotPrison.getInstance(), 1, 1 ); - placedTask.setBukkitTask( task ); + // This setups the animations that are assigned to each bomb type and + // will submit the tasks, unless no animations are chosen. + BombAnimationsTask animationsTask = new BombAnimationsTask(); - return placedTask; - } - - public class PlacedMineBombItemTask - extends BukkitRunnable - { - - private MineBombData bomb; - private SpigotBlock sBlock; - private SpigotItemStack item; - - private double eulerAngleX = 1.0; - private double eulerAngleY = 0; - private double eulerAngleZ = 0; - - private double twoPI; - - private ArmorStand armorStand; - private boolean isDyanmicTag = false; - private String tagName; - -// long ageTicks = 0L; - long terminateOnZeroTicks = 0L; - - private BukkitTask bukkitTask; - - private DecimalFormat dFmt; - - public PlacedMineBombItemTask( MineBombData bomb, - SpigotBlock sBombBlock, SpigotItemStack item ) { - super(); - - this.bomb = bomb; - this.sBlock = sBombBlock; - this.item = item; - - - this.twoPI = Math.PI * 2; - -// this.ageTicks = 0; - this.terminateOnZeroTicks = getTaskLifeSpan(); - - this.isDyanmicTag = bomb.getNameTag().contains( "{countdown}" ); - this.tagName = ""; - - this.dFmt = Prison.get().getDecimalFormat( "0.0" ); - - initializeArmorStand(); - } + animationsTask.animatorFactory( bomb, sBlock, item ); + return animationsTask; - /** - *

This will calculate how long the placed item needs to - * exist before removal, and this task will remove itself. - * While this item is placed, this task will run every 2 - * ticks and will spin the item in 3d space. - *

- * - *

Removal is based upon the fuseDelayTicks which will take it to - * the explosion, then scanning the final effects to find how long - * the last one will be submitted for. Then add 15 ticks. - *

- * - *

At this time, not 100% sure if this item or armor stand - * will be used to "place" the effects. Probably not. If it's not - * needed, then this can be removed when the explosions start. - *

- * - * @return - */ - private long getTaskLifeSpan() - { - int removeInTicks = bomb.getFuseDelayTicks() + bomb.getItemRemovalDelayTicks(); - return removeInTicks; - } - - - private void initializeArmorStand() { - - Location location = sBlock.getLocation(); - location.setY( location.getY() + 2.5 ); - - SpigotWorld sWorld = (SpigotWorld) location.getWorld(); - - - EulerAngle arm = new EulerAngle( eulerAngleX, eulerAngleY, eulerAngleZ ); - - armorStand = sWorld.getWrapper().spawn( - sWorld.getBukkitLocation( location ), - ArmorStand.class); - -// int removeInTicks = (int) getTaskLifeSpan(); - - //armorStand.addAttachment( SpigotPrison.getInstance(), removeInTicks ); - - if ( bomb.getNameTag() != null && !bomb.getNameTag().trim().isEmpty() ) { - - String tagName = bomb.getNameTag(); - if ( tagName.contains( "{name}" ) ) { - tagName = tagName.replace( "{name}", bomb.getName() ); - } - this.tagName = Text.translateAmpColorCodes( tagName ); - - //updateArmorStandCustomName(); - armorStand.setCustomName( this.tagName ); - armorStand.setCustomNameVisible(true); - } - else { - - armorStand.setCustomNameVisible(false); - } - armorStand.setVisible(false); - armorStand.setRemoveWhenFarAway(false); - armorStand.setItemInHand( sWorld.getBukkitItemStack( item ) ); - armorStand.setRightArmPose(arm); - - - if ( new BluesSemanticVersionComparator().compareMCVersionTo( "1.9.0" ) >= 0 ) { - - armorStand.setGlowing( bomb.isGlowing() ); - - // setGravity is invalid for spigot 1.8.8: - armorStand.setGravity( bomb.isGravity() ); - } - } - - private void updateArmorStandCustomName() - { - if ( isDyanmicTag ) { - - double countdown = (terminateOnZeroTicks / 20.0d); - String tagName = this.tagName.replace( "{countdown}", dFmt.format( countdown) ); - - armorStand.setCustomName( tagName ); - } - } - - - @Override - public void run() - { - - double speed = 0.35; - - eulerAngleX += speed; - eulerAngleY += speed / 3; - eulerAngleZ += speed / 5; - - - EulerAngle arm = new EulerAngle( eulerAngleX, eulerAngleY, eulerAngleZ ); - - armorStand.setRightArmPose(arm); - - - if ( eulerAngleX > twoPI ) { - eulerAngleX -= twoPI; - } - if ( eulerAngleY > twoPI ) { - eulerAngleY -= twoPI; - } - if ( eulerAngleZ > twoPI ) { - eulerAngleZ -= twoPI; - } - - - // Track the time that this has lived: - if ( --terminateOnZeroTicks == 0 || !armorStand.isValid() ) { - - armorStand.remove(); - - this.cancel(); - } - - updateArmorStandCustomName(); - - } - - public BukkitTask getBukkitTask() { - return bukkitTask; - } - public void setBukkitTask( BukkitTask bukkitTask ) { - this.bukkitTask = bukkitTask; - } +// PlacedMineBombItemTask placedTask = new PlacedMineBombItemTask( bomb, sBlock, item ); +// +// BukkitTask task = placedTask.runTaskTimer( +// SpigotPrison.getInstance(), 1, 1 ); +// +// placedTask.setBukkitTask( task ); +// return placedTask; } +// public class PlacedMineBombItemTask +// extends BukkitRunnable +// { +// +// private MineBombData bomb; +// private SpigotBlock sBlock; +// private SpigotItemStack item; +// +// private double eulerAngleX = 1.0; +// private double eulerAngleY = 0; +// private double eulerAngleZ = 0; +// +// private double twoPI; +// +// private ArmorStand armorStand; +// private boolean isDyanmicTag = false; +// private String tagName; +// +//// long ageTicks = 0L; +// long terminateOnZeroTicks = 0L; +// +// private BukkitTask bukkitTask; +// +// private DecimalFormat dFmt; +// +// public PlacedMineBombItemTask( MineBombData bomb, +// SpigotBlock sBombBlock, SpigotItemStack item ) { +// super(); +// +// this.bomb = bomb; +// this.sBlock = sBombBlock; +// this.item = item; +// +// +// this.twoPI = Math.PI * 2; +// +//// this.ageTicks = 0; +// this.terminateOnZeroTicks = getTaskLifeSpan(); +// +// this.isDyanmicTag = bomb.getNameTag().contains( "{countdown}" ); +// this.tagName = ""; +// +// this.dFmt = Prison.get().getDecimalFormat( "0.0" ); +// +// initializeArmorStand(); +// } +// +// +// /** +// *

This will calculate how long the placed item needs to +// * exist before removal, and this task will remove itself. +// * While this item is placed, this task will run every 2 +// * ticks and will spin the item in 3d space. +// *

+// * +// *

Removal is based upon the fuseDelayTicks which will take it to +// * the explosion, then scanning the final effects to find how long +// * the last one will be submitted for. Then add 15 ticks. +// *

+// * +// *

At this time, not 100% sure if this item or armor stand +// * will be used to "place" the effects. Probably not. If it's not +// * needed, then this can be removed when the explosions start. +// *

+// * +// * @return +// */ +// private long getTaskLifeSpan() +// { +// int removeInTicks = bomb.getFuseDelayTicks() + bomb.getItemRemovalDelayTicks(); +// return removeInTicks; +// } +// +// +// private void initializeArmorStand() { +// +// Location location = sBlock.getLocation(); +// location.setY( location.getY() + 2.5 ); +// +// SpigotWorld sWorld = (SpigotWorld) location.getWorld(); +// +// +// EulerAngle arm = new EulerAngle( eulerAngleX, eulerAngleY, eulerAngleZ ); +// +// armorStand = sWorld.getWrapper().spawn( +// sWorld.getBukkitLocation( location ), +// ArmorStand.class); +// +//// int removeInTicks = (int) getTaskLifeSpan(); +// +// //armorStand.addAttachment( SpigotPrison.getInstance(), removeInTicks ); +// +// if ( bomb.getNameTag() != null && !bomb.getNameTag().trim().isEmpty() ) { +// +// String tagName = bomb.getNameTag(); +// if ( tagName.contains( "{name}" ) ) { +// tagName = tagName.replace( "{name}", bomb.getName() ); +// } +// this.tagName = Text.translateAmpColorCodes( tagName ); +// +// //updateArmorStandCustomName(); +// armorStand.setCustomName( this.tagName ); +// armorStand.setCustomNameVisible(true); +// } +// else { +// +// armorStand.setCustomNameVisible(false); +// } +// armorStand.setVisible(false); +// armorStand.setRemoveWhenFarAway(false); +// armorStand.setItemInHand( sWorld.getBukkitItemStack( item ) ); +// armorStand.setRightArmPose(arm); +// +// +// if ( new BluesSemanticVersionComparator().compareMCVersionTo( "1.9.0" ) >= 0 ) { +// +// armorStand.setGlowing( bomb.isGlowing() ); +// +// // setGravity is invalid for spigot 1.8.8: +// armorStand.setGravity( bomb.isGravity() ); +// } +// } +// +// private void updateArmorStandCustomName() +// { +// if ( isDyanmicTag ) { +// +// double countdown = (terminateOnZeroTicks / 20.0d); +// String tagName = this.tagName.replace( "{countdown}", dFmt.format( countdown) ); +// +// armorStand.setCustomName( tagName ); +// } +// } +// +// +// @Override +// public void run() +// { +// +// double speed = 0.35; +// +// eulerAngleX += speed; +// eulerAngleY += speed / 3; +// eulerAngleZ += speed / 5; +// +// +// EulerAngle arm = new EulerAngle( eulerAngleX, eulerAngleY, eulerAngleZ ); +// +// armorStand.setRightArmPose(arm); +// +// +// if ( eulerAngleX > twoPI ) { +// eulerAngleX -= twoPI; +// } +// if ( eulerAngleY > twoPI ) { +// eulerAngleY -= twoPI; +// } +// if ( eulerAngleZ > twoPI ) { +// eulerAngleZ -= twoPI; +// } +// +// +// // Track the time that this has lived: +// if ( --terminateOnZeroTicks == 0 || !armorStand.isValid() ) { +// +// armorStand.remove(); +// +// this.cancel(); +// } +// +// updateArmorStandCustomName(); +// +// } +// +// public BukkitTask getBukkitTask() { +// return bukkitTask; +// } +// public void setBukkitTask( BukkitTask bukkitTask ) { +// this.bukkitTask = bukkitTask; +// } +// +// } + } From 1fae2839d6987facef0ba24263bb2cef49c3b8ca Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 5 Jul 2024 13:42:59 -0400 Subject: [PATCH 049/323] Prison API: I noticed that an API class had an PrisonItemStack qualifying the class? I have no idea what happened here, or why it even was added. All I can think of is that it was a stray paste or something. This was removed. --- docs/changelog_v3.3.x.md | 5 +++++ .../tech/mcprison/prison/spigot/api/PrisonSpigotAPI.java | 8 +++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 965e54999..50e602066 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.18b 2024-07-05 +* **Prison API: I noticed that an API class had an PrisonItemStack qualifying the class?**] +I have no idea what happened here, or why it even was added. All I can think of is that it was a stray paste or something. +This was removed. + + * **Prison Bomb Animations: Initial setup and switch over to use the new prison bomb animations. Non-functional.** This state of development has the animations working, but the bomb's actual explosions are not yet enabled, so this commit is non-functional. It's being committed due to the number of classes changed and for how much is working well too. The animations were pushed back to core so that way it's not more code that is being crammed within the spigot module, which was originally intended to be a light weight layer sitting between the actual prison code, and the platform. 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 58d8d426a..60597ec0c 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 @@ -51,17 +51,15 @@ *

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

- * @param - * */ -public class PrisonSpigotAPI { +public class PrisonSpigotAPI { private PrisonMines prisonMineManager; private boolean mineModuleDisabled = false; private SellAllUtil sellAll; - private void junk() { +// private void junk() { // SpigotPrison.getInstance().isSellAllEnabled(); // @@ -75,7 +73,7 @@ private void junk() { // // PrisonSpigotAPI.sellPlayerItems(Player player ); - } +// } // private void handleAffectedBlocks(Player p, IWrappedRegion region, List blocksAffected) { // double totalDeposit = 0.0; From 15caca671d56487178696142f59e7aa15ccb2a07 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 5 Jul 2024 13:45:01 -0400 Subject: [PATCH 050/323] Entity clean up: Small changes that missed the last commit related to the addition of the Entity and mine bomb animations. --- docs/changelog_v3.3.x.md | 3 +++ .../tech/mcprison/prison/spigot/block/SpigotItemStack.java | 2 +- .../java/tech/mcprison/prison/spigot/game/SpigotPlayer.java | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 50e602066..8e4a3247a 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.18b 2024-07-05 +* **Entity clean up: Small changes that missed the last commit related to the addition of the Entity and mine bomb animations.** + + * **Prison API: I noticed that an API class had an PrisonItemStack qualifying the class?**] I have no idea what happened here, or why it even was added. All I can think of is that it was a stray paste or something. This was removed. diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/SpigotItemStack.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/SpigotItemStack.java index a35990cd1..cca87d259 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/SpigotItemStack.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/SpigotItemStack.java @@ -28,7 +28,7 @@ public class SpigotItemStack // private NBTItem nbtBukkitStack; // private boolean nbtChecked = false; // private org.bukkit.inventory.ItemStack bukkitStack; - private org.bukkit.inventory.ItemStack deserialize; +// private org.bukkit.inventory.ItemStack deserialize; public SpigotItemStack( org.bukkit.inventory.ItemStack bukkitStack ) throws PrisonItemStackNotSupportedRuntimeException { 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 49ea6806d..b66d47ad7 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 @@ -52,6 +52,7 @@ 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.game.entity.SpigotEntity; import tech.mcprison.prison.spigot.inventory.SpigotPlayerInventory; import tech.mcprison.prison.spigot.scoreboard.SpigotScoreboard; import tech.mcprison.prison.spigot.sellall.SellAllUtil; From 9bceb6a04efd046d0f0f64031b7833b520516c4b Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 5 Jul 2024 14:32:00 -0400 Subject: [PATCH 051/323] AutoFeatures: Added new blocking capabilities: raw_gold => raw_gold_block, raw_iron => raw_iron_block, and raw_copper => raw_copper_block. --- docs/changelog_v3.3.x.md | 4 ++ .../autofeatures/AutoFeaturesFileConfig.java | 5 ++- .../autofeatures/AutoManagerFeatures.java | 39 +++++++++++++++++-- 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 8e4a3247a..c835e7d69 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.18b 2024-07-05 +* **AutoFeatures: Added new blocking capabilities: raw to raw blocks.** +raw_gold => raw_gold_block, raw_iron => raw_iron_block, and raw_copper => raw_copper_block. + + * **Entity clean up: Small changes that missed the last commit related to the addition of the Entity and mine bomb animations.** 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 06d1baf83..6c9891d52 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 @@ -429,8 +429,10 @@ public enum AutoFeatures { blockAllBlocks(blockFeature, true), + blockRawGoldBlock(blockFeature, true), blockGoldBlock(blockFeature, true), blockIronBlock(blockFeature, true), + blockRawIronBlock(blockFeature, true), blockCoalBlock(blockFeature, true), blockDiamondBlock(blockFeature, true), blockRedstoneBlock(blockFeature, true), @@ -440,6 +442,7 @@ public enum AutoFeatures { blockLapisBlock(blockFeature, true), blockSnowBlock(blockFeature, true), blockGlowstone(blockFeature, true), + blockRawCopperBlock(blockFeature, true), blockCopperBlock(blockFeature, true), @@ -454,7 +457,7 @@ public enum AutoFeatures { + "this will replace the list of hard coded blocks listed above for " + "blocking and smelting."), - isEnabledBlockConvertersEventTriggers(blockConverters, false ) + isEnabledBlockConvertersEventTriggers(blockConverters, false ), 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 0a924ff4b..2b79c5834 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 @@ -2518,9 +2518,20 @@ protected void normalDropBlock( Player player, List drops ) { switch ( source ) { + case RAW_GOLD: + if ( isAll || isBoolean( AutoFeatures.blockRawGoldBlock ) ) { + + if ( includePlayerInventory ) { + SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( + player, source, drop ); + } + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.RAW_GOLD_BLOCK, 9 ); + } + break; + case GOLD_INGOT: if ( isAll || isBoolean( AutoFeatures.blockGoldBlock ) ) { - + if ( includePlayerInventory ) { SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( player, source, drop ); @@ -2529,9 +2540,20 @@ protected void normalDropBlock( Player player, List drops ) { } break; + case RAW_IRON: + if ( isAll || isBoolean( AutoFeatures.blockRawIronBlock ) ) { + + if ( includePlayerInventory ) { + SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( + player, source, drop ); + } + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.RAW_IRON_BLOCK, 9 ); + } + break; + case IRON_INGOT: if ( isAll || isBoolean( AutoFeatures.blockIronBlock ) ) { - + if ( includePlayerInventory ) { SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( player, source, drop ); @@ -2639,9 +2661,20 @@ protected void normalDropBlock( Player player, List drops ) { } break; + case RAW_COPPER: + if ( isAll || isBoolean( AutoFeatures.blockRawCopperBlock ) ) { + + if ( includePlayerInventory ) { + SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( + player, source, drop ); + } + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.RAW_COPPER_BLOCK, 9 ); + } + break; + case COPPER_INGOT: if ( isAll || isBoolean( AutoFeatures.blockCopperBlock ) ) { - + if ( includePlayerInventory ) { SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( player, source, drop ); From 9231b26c29187699cf5919ddf6b632799b48ea20 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 6 Jul 2024 01:12:28 -0400 Subject: [PATCH 052/323] Mine Bombs: Added NBT ids to all mine bomb armor stands so they can be identified as being part of the mine bombs processes. Added this support to the `/prison utils bomb findArmorStand` command so it applies to only mine bomb used ones. --- docs/changelog_v3.3.x.md | 4 ++ .../tech/mcprison/prison/bombs/MineBombs.java | 3 + .../animations/BombAnimationInfinity.java | 3 + .../tech/mcprison/prison/internal/Entity.java | 4 ++ .../spigot/game/entity/SpigotEntity.java | 19 ++++++ .../prison/spigot/nbt/PrisonNBTUtil.java | 67 +++++++++++++++++++ .../spigot/utils/PrisonUtilsMineBombs.java | 17 ++++- 7 files changed, 115 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index c835e7d69..22fcaf4d8 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.18b 2024-07-05 +* **Mine Bombs: Added NBT ids to all mine bomb armor stands so they can be identified as being part of the mine bombs processes.** +Added this support to the `/prison utils bomb findArmorStand` command so it applies to only mine bomb used ones. + + * **AutoFeatures: Added new blocking capabilities: raw to raw blocks.** raw_gold => raw_gold_block, raw_iron => raw_iron_block, and raw_copper => raw_copper_block. 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 6fe590dbb..6aa5a3932 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 @@ -16,6 +16,9 @@ public class MineBombs implements Comparable { + public static final String MINE_BOMBS_NBT_KEY = "MineBombNbtKey"; + public static final String MINE_BOMBS_NBT_THROWER_UUID = "MineBombNbtThrowerUUID"; + public static final String MINE_BOMBS_FILE_NAME = "mineBombsConfig.json"; public static final String MINE_BOMBS_PATH_NAME = "module_conf/mines"; diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationInfinity.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationInfinity.java index 53fa65e1b..e27f30ff0 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationInfinity.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationInfinity.java @@ -1,6 +1,7 @@ package tech.mcprison.prison.bombs.animations; import tech.mcprison.prison.bombs.MineBombData; +import tech.mcprison.prison.bombs.MineBombs; import tech.mcprison.prison.internal.ArmorStand; import tech.mcprison.prison.internal.EulerAngle; import tech.mcprison.prison.internal.ItemStack; @@ -68,6 +69,8 @@ private void initializeArmorStand() { armorStand = location.spawnArmorStand(); + armorStand.setNbtString( MineBombs.MINE_BOMBS_NBT_KEY, getBomb().getName() ); + if ( armorStand != null ) { armorStand.setVisible(false); diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/Entity.java b/prison-core/src/main/java/tech/mcprison/prison/internal/Entity.java index 6d1079aca..a0333c60d 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/Entity.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/Entity.java @@ -11,6 +11,10 @@ public interface Entity { + public String getNbtString( String key ); + public void setNbtString( String key, String value ); + + /** Returns a unique and persistent id for this entity */ public UUID getUniqueId(); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotEntity.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotEntity.java index c04340b98..bda61774e 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotEntity.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotEntity.java @@ -12,6 +12,7 @@ import tech.mcprison.prison.spigot.game.SpigotCommandSender; import tech.mcprison.prison.spigot.game.SpigotLocation; import tech.mcprison.prison.spigot.game.SpigotWorld; +import tech.mcprison.prison.spigot.nbt.PrisonNBTUtil; import tech.mcprison.prison.util.Location; import tech.mcprison.prison.util.Vector; @@ -28,6 +29,24 @@ public SpigotEntity(org.bukkit.entity.Entity entity ) { } + @Override + public String getNbtString( String key ) { + String results = ""; + + if ( bukkitEntity != null ) { + results = PrisonNBTUtil.getNBTString(bukkitEntity, key); + } + + return results; + } + @Override + public void setNbtString( String key, String value ) { + if ( bukkitEntity != null ) { + PrisonNBTUtil.setNBTString(bukkitEntity, key, value); + } + } + + @Override public UUID getUniqueId() { return getBukkitEntity().getUniqueId(); 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 73bc6bbf6..021ad750d 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 @@ -4,6 +4,7 @@ import org.bukkit.block.Block; import org.bukkit.block.BlockState; +import org.bukkit.entity.Entity; import org.bukkit.inventory.ItemStack; import de.tr7zw.changeme.nbtapi.NBT; @@ -145,6 +146,54 @@ public static void setNBTBoolean( ItemStack bukkitStack, String key, boolean val } + + public static boolean hasNBTString( Entity entity, String key ) { + String results = null; + + results = getNBTString( entity, key ); + + return results != null && results.trim().length() > 0; + } + public static String getNBTString( Entity entity, String key ) { + String results = null; + + try { + Function gsFnc = nbt -> nbt.getString(key); + + results = NBT.get(entity, gsFnc ); +// results = NBT.get(bukkitStack, nbt -> nbt.getString(key)); + } + catch (Exception e) { + Output.get().logInfo( + "PrisonNBTUtil.getNBTString(): Failure trying to use NBTs. " + + "Contact prison support. The NBT library may need to be updated. [%s]", + e.getMessage() + ); + } + + return results; + } + public static void setNBTString( Entity entity, String key, String value ) { + + try { + NBT.modify(entity, nbt -> { + nbt.setString(key, value); + }); + + if ( isEnableDebugLogging() ) { + nbtDebugLog( entity, "setNBTString" ); + } + } + catch (Exception e) { + Output.get().logInfo( + "PrisonNBTUtil.setNBTString(): Failure trying to use NBTs. " + + "Contact prison support. The NBT library may need to be updated. [%s]", + e.getMessage() + ); + } + } + + public static void nbtDebugLog( ItemStack bukkitStack, String desc ) { if ( Output.get().isDebug() ) { @@ -168,6 +217,24 @@ public static void nbtDebugLog( ItemStack bukkitStack, String desc ) { } } + public static void nbtDebugLog( Entity entity, String desc ) { + if ( Output.get().isDebug() ) { + + int sysId = System.identityHashCode(entity); + + String message = Output.stringFormat( + "NBT %s ItemStack for %s: sysId: %d", + desc, + entity.getName(), + sysId ); + + Output.get().logInfo( message ); + + //Output.get().logInfo( "NBT: " + new NBTItem( getBukkitStack() ) ); + + } + } + public static String nbtDebugString( ItemStack bukkitStack ) { 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 764bc6903..71027ed85 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 @@ -184,6 +184,17 @@ public void utilsFindMineBombsArmorStands( CommandSender sender, for (Entity entity : entities) { SpigotEntity sEntity = (SpigotEntity) entity; + boolean hasId = false; + + String bombName = sEntity.getNbtString( MineBombs.MINE_BOMBS_NBT_KEY ); + if ( bombName != null && bombName.trim().length() > 0 ) { + hasId = true; + } + + if ( any && !hasId ) { + // Not a mine bomb armor stand so continue and bypass processing: + continue; + } Location l = entity.getLocation(); @@ -220,7 +231,8 @@ else if ( removeAll || } String msg = String.format( - "&3ArmorStand: distance &7%4s &3id: &7%s &3x:%4s y:%4s z: %4s age: %s %s %s", + "&3ArmorStand: distance &7%4s &3id: &7%s " + + "&3x:%4s y:%4s z: %4s age: %s %s %s bombName: %s", iFmt.format( bounds.getDistance3d() ), id, iFmt.format( l.getBlockX() ), @@ -228,7 +240,8 @@ else if ( removeAll || iFmt.format( l.getBlockZ() ), dFmt.format( times ), sfx, - status + status, + hasId ? bombName : "none" ); sender.sendMessage( msg ); From 073eef8ed28c20547b24d95c64f8b27ccb5535df Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 6 Jul 2024 01:17:41 -0400 Subject: [PATCH 053/323] Mines: Converted a mine cache lookup from using longs which were a fragment of the player's uuid, to using their whole uuid. This change was made to ensure that bedrock players won't have problems. --- docs/changelog_v3.3.x.md | 6 +++++- .../tech/mcprison/prison/mines/PrisonMines.java | 15 +++++++++------ .../prison/spigot/api/PrisonSpigotAPI.java | 9 +++++---- .../prison/spigot/block/OnBlockBreakMines.java | 11 ++++++----- 4 files changed, 25 insertions(+), 16 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 22fcaf4d8..6ce823e98 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.18b 2024-07-05 +# 3.3.0-alpha.18b 2024-07-06 + + +* **Mines: Converted a mine cache lookup from using longs which were a fragment of the player's uuid, to using their whole uuid. ** +This change was made to ensure that bedrock players won't have problems. * **Mine Bombs: Added NBT ids to all mine bomb armor stands so they can be identified as being part of the mine bombs processes.** 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 d4d0739f6..dced8dfd7 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 @@ -78,7 +78,7 @@ public class PrisonMines extends Module { *

* */ - private final TreeMap playerCache; + private final TreeMap playerCache; @@ -229,17 +229,20 @@ public Mine findMineLocationIncludeTopBottomOfMine( Location locationToCheck ) { return mine; } - public TreeMap getPlayerCache() { + public TreeMap getPlayerCache() { return playerCache; } public Mine findMineLocation( Player player ) { Mine results = null; - Long playerUUIDLSB = Long.valueOf( player.getUUID().getLeastSignificantBits() ); + String uuid = player.getUUID().toString(); + +// Long playerUUIDLSB = Long.valueOf( player.getUUID().getLeastSignificantBits() ); // Get the cached mine, if it exists: - Mine mine = getPlayerCache().get( playerUUIDLSB ); + Mine mine = getPlayerCache().get( uuid ); +// Mine mine = getPlayerCache().get( playerUUIDLSB ); if ( mine != null && mine.isInMineIncludeTopBottomOfMine( player.getLocation() )) { results = mine; @@ -251,10 +254,10 @@ else if ( player.getLocation() != null ) { // Store the mine in the player cache if not null: if ( results != null ) { - getPlayerCache().put( playerUUIDLSB, results ); + getPlayerCache().put( uuid, results ); } else { - getPlayerCache().remove( playerUUIDLSB ); + getPlayerCache().remove( uuid ); } } 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 60597ec0c..b5c43341f 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 @@ -359,10 +359,11 @@ public Mine getPrisonMine( Player player, Block block, boolean isCanceledEvent) // Need to wrap in a Prison block so it can be used with the mines: SpigotBlock spigotBlock = SpigotBlock.getSpigotBlock(block); - Long playerUUIDLSB = Long.valueOf( player.getUniqueId().getLeastSignificantBits() ); + String uuid = player.getUniqueId().toString(); +// Long playerUUIDLSB = Long.valueOf( player.getUniqueId().getLeastSignificantBits() ); // Get the cached mine, if it exists: - Mine mine = getPlayerCache().get( playerUUIDLSB ); + Mine mine = getPlayerCache().get( uuid ); if ( mine == null || !mine.isInMineExact( spigotBlock.getLocation() ) ) { // Look for the correct mine to use. @@ -371,7 +372,7 @@ public Mine getPrisonMine( Player player, Block block, boolean isCanceledEvent) // Store the mine in the player cache if not null: if ( mine != null ) { - getPlayerCache().put( playerUUIDLSB, mine ); + getPlayerCache().put( uuid, mine ); } } @@ -448,7 +449,7 @@ public boolean createMine( String mineName, String tag, return results; } - private TreeMap getPlayerCache() { + private TreeMap getPlayerCache() { return getPrisonMineManager().getPlayerCache(); } 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 80e7c8a6e..d136a301d 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 @@ -191,10 +191,10 @@ public Mine findMine( Player player, SpigotBlock sBlock, List altBlocksSo public Mine findMine( UUID playerUUID, SpigotBlock sBlock, List altBlocksSource, PrisonMinesBlockBreakEvent pmEvent ) { - Long playerUUIDLSB = Long.valueOf( playerUUID.getLeastSignificantBits() ); +// Long playerUUIDLSB = Long.valueOf( playerUUID.getLeastSignificantBits() ); // Get the cached mine, if it exists: - Mine mine = getPlayerCache().get( playerUUIDLSB ); + Mine mine = getPlayerCache().get( playerUUID.toString() ); if ( mine == null || sBlock != null && !mine.isInMineExact( sBlock.getLocation() ) ) { @@ -232,7 +232,8 @@ public Mine findMine( UUID playerUUID, SpigotBlock sBlock, List altBlocks // Store the mine in the player cache if not null: if ( mine != null ) { - getPlayerCache().put( playerUUIDLSB, mine ); + getPlayerCache().put( playerUUID.toString(), mine ); +// getPlayerCache().put( playerUUIDLSB, mine ); } } @@ -681,9 +682,9 @@ private Mine findMineLocation( SpigotBlock block ) { } - private TreeMap getPlayerCache() { + private TreeMap getPlayerCache() { return getPrisonMineManager() == null ? - new TreeMap() : + new TreeMap() : getPrisonMineManager().getPlayerCache(); } From 45fffcc18d476bc190975288785255bd0de7b639 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 6 Jul 2024 01:19:21 -0400 Subject: [PATCH 054/323] Spigot compatibility: Expanded some of the compatibility functions so that some other mine bomb code can be simplified. --- docs/changelog_v3.3.x.md | 3 +++ .../prison/spigot/compat/Compatibility.java | 7 +++++++ .../prison/spigot/compat/Spigot_1_13.java | 16 ++++++++++++++++ .../prison/spigot/compat/Spigot_1_8.java | 15 +++++++++++++++ .../prison/spigot/compat/Spigot_1_9.java | 16 ++++++++++++++++ 5 files changed, 57 insertions(+) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 6ce823e98..99dc99095 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.18b 2024-07-06 +* **Spigot compatibility: Expanded some of the compatibility functions so that some other mine bomb code can be simplified.** + + * **Mines: Converted a mine cache lookup from using longs which were a fragment of the player's uuid, to using their whole uuid. ** This change was made to ensure that bedrock players won't have problems. diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Compatibility.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Compatibility.java index ce342617a..b6666c83a 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Compatibility.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Compatibility.java @@ -27,6 +27,7 @@ import org.bukkit.inventory.PlayerInventory; import tech.mcprison.prison.spigot.block.SpigotItemStack; +import tech.mcprison.prison.spigot.game.SpigotPlayer; import tech.mcprison.prison.spigot.inventory.SpigotPlayerInventory; /** @@ -53,7 +54,11 @@ public interface Compatibility public SpigotItemStack getPrisonItemInMainHand(Player player); + public SpigotItemStack getPrisonItemInMainHand(SpigotPlayer player); + public SpigotItemStack getPrisonItemInOffHand(Player player); + + public SpigotItemStack getPrisonItemInOffHand(SpigotPlayer player); public ItemStack getItemInOffHand(PlayerInteractEvent e); @@ -64,6 +69,8 @@ public interface Compatibility public void setItemStackInMainHand( SpigotPlayerInventory inventory, SpigotItemStack itemStack ); public void setItemInMainHand(Player p, ItemStack itemStack); + + public void setItemInMainHand(SpigotPlayer p, ItemStack itemStack); public void setItemStackInOffHand( SpigotPlayerInventory inventory, SpigotItemStack itemStack ); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_13.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_13.java index c14d3a370..599477d32 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_13.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_13.java @@ -11,6 +11,7 @@ import tech.mcprison.prison.spigot.SpigotUtil; import tech.mcprison.prison.spigot.block.SpigotItemStack; +import tech.mcprison.prison.spigot.game.SpigotPlayer; import tech.mcprison.prison.spigot.inventory.SpigotPlayerInventory; public class Spigot_1_13 @@ -60,10 +61,20 @@ public SpigotItemStack getPrisonItemInMainHand(Player player) { return SpigotUtil.bukkitItemStackToPrison( getItemInMainHand( player ) ); } + @Override + public SpigotItemStack getPrisonItemInMainHand(SpigotPlayer player) { + return SpigotUtil.bukkitItemStackToPrison( getItemInMainHand( player.getWrapper() ) ); + } + @Override public SpigotItemStack getPrisonItemInOffHand(Player player) { return SpigotUtil.bukkitItemStackToPrison( getItemInOffHand( player ) ); } + + @Override + public SpigotItemStack getPrisonItemInOffHand(SpigotPlayer player) { + return SpigotUtil.bukkitItemStackToPrison( getItemInOffHand( player.getWrapper() ) ); + } @Override public ItemStack getItemInOffHand(PlayerInteractEvent e) { @@ -92,6 +103,11 @@ public void setItemInMainHand(Player p, ItemStack itemStack){ p.getInventory().setItemInMainHand(itemStack); } + @Override + public void setItemInMainHand(SpigotPlayer p, ItemStack itemStack){ + p.getWrapper().getInventory().setItemInMainHand(itemStack); + } + @Override public void setItemStackInOffHand( SpigotPlayerInventory inventory, SpigotItemStack itemStack ) { diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_8.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_8.java index 67fb01c47..86af647d4 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_8.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_8.java @@ -29,6 +29,7 @@ import tech.mcprison.prison.spigot.SpigotUtil; import tech.mcprison.prison.spigot.block.SpigotItemStack; +import tech.mcprison.prison.spigot.game.SpigotPlayer; import tech.mcprison.prison.spigot.inventory.SpigotPlayerInventory; /** @@ -75,9 +76,17 @@ public SpigotItemStack getPrisonItemInMainHand(Player player) { return SpigotUtil.bukkitItemStackToPrison( getItemInMainHand( player ) ); } + public SpigotItemStack getPrisonItemInMainHand(SpigotPlayer player) { + return SpigotUtil.bukkitItemStackToPrison( getItemInMainHand( player.getWrapper() ) ); + } + public SpigotItemStack getPrisonItemInOffHand(Player player) { return SpigotUtil.bukkitItemStackToPrison( getItemInMainHand( player ) ); } + + public SpigotItemStack getPrisonItemInOffHand(SpigotPlayer player) { + return SpigotUtil.bukkitItemStackToPrison( getItemInMainHand( player.getWrapper() ) ); + } @Override public ItemStack getItemInOffHand(PlayerInteractEvent e) { @@ -109,6 +118,12 @@ public void setItemStackInMainHand( SpigotPlayerInventory inventory, SpigotItemS public void setItemInMainHand(Player p, ItemStack itemStack) { p.getInventory().setItemInHand(itemStack); } + + @SuppressWarnings("deprecation") + @Override + public void setItemInMainHand(SpigotPlayer p, ItemStack itemStack) { + p.getWrapper().getInventory().setItemInHand(itemStack); + } /** * Spigot v1.8 does not have an off hand, so set it to main hand. diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_9.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_9.java index 7f005893f..41c404697 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_9.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_9.java @@ -29,6 +29,7 @@ import tech.mcprison.prison.spigot.SpigotUtil; import tech.mcprison.prison.spigot.block.SpigotItemStack; +import tech.mcprison.prison.spigot.game.SpigotPlayer; import tech.mcprison.prison.spigot.inventory.SpigotPlayerInventory; /** @@ -83,10 +84,20 @@ public SpigotItemStack getPrisonItemInMainHand(Player player) { return SpigotUtil.bukkitItemStackToPrison( getItemInMainHand( player ) ); } + @Override + public SpigotItemStack getPrisonItemInMainHand(SpigotPlayer player) { + return SpigotUtil.bukkitItemStackToPrison( getItemInMainHand( player.getWrapper() ) ); + } + @Override public SpigotItemStack getPrisonItemInOffHand(Player player) { return SpigotUtil.bukkitItemStackToPrison( getItemInOffHand( player ) ); } + + @Override + public SpigotItemStack getPrisonItemInOffHand(SpigotPlayer player) { + return SpigotUtil.bukkitItemStackToPrison( getItemInOffHand( player.getWrapper() ) ); + } @Override public ItemStack getItemInOffHand(PlayerInteractEvent e) { @@ -114,6 +125,11 @@ public void setItemStackInMainHand( SpigotPlayerInventory inventory, SpigotItemS public void setItemInMainHand(Player p, ItemStack itemStack) { p.getInventory().setItemInMainHand(itemStack); } + + @Override + public void setItemInMainHand(SpigotPlayer p, ItemStack itemStack) { + p.getWrapper().getInventory().setItemInMainHand(itemStack); + } @Override public void setItemStackInOffHand( SpigotPlayerInventory inventory, SpigotItemStack itemStack ) { From 64db1d32384de1c173af2806278b45675d3a0963 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 6 Jul 2024 01:26:48 -0400 Subject: [PATCH 055/323] More work on the findArmorStands function. Fixed an issue with getting the entities within an area too. Found that was not working correctly. --- docs/changelog_v3.3.x.md | 4 ++++ .../spigot/game/entity/SpigotEntity.java | 6 ++++-- .../spigot/utils/PrisonUtilsMineBombs.java | 18 +++++++++++++----- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 99dc99095..9d8d1c13d 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.18b 2024-07-06 +* **More work on the findArmorStands function.** +Fixed an issue with getting the entities within an area too. Found that was not working correctly. + + * **Spigot compatibility: Expanded some of the compatibility functions so that some other mine bomb code can be simplified.** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotEntity.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotEntity.java index bda61774e..9c381aa2f 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotEntity.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotEntity.java @@ -104,9 +104,11 @@ public int getMaxFireTicks() { * @return */ public List getNearbyEntities( int r, EntityType eType ) { - Location loc = getLocation(); +// Location loc = getLocation(); + List bEntities = getBukkitEntity() - .getNearbyEntities( loc.getX() + r, loc.getY() + r, loc.getZ() + r); + .getNearbyEntities( r * 2, r * 2, r * 2 ); + return convertEntities( bEntities, (SpigotEntityType) eType ); } 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 71027ed85..8ae7d14fc 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 @@ -113,20 +113,21 @@ protected Boolean initialize() permissions = "prison.utils.bombs", altPermissions = "prison.utils.bombs.others") public void utilsFindMineBombsArmorStands( CommandSender sender, - @Arg(name = "radius", def = "10", - description = "Number of blocks in a radius from the player " - + "to search for armor stands to remove.") int radius, @Arg(name = "playerName", description = "Player name") String playerName, + @Arg(name = "radius", def = "10", + description = "Number of blocks in a radius from the player " + + "to search for armor stands to remove.") int radius, @Wildcard(join=true) @Arg(name = "options", def = "list", description = "Action to perform. 'list' will list all armor stands within" - + "the general cubic-radius. " + + "the general cubic-radius that are marked with the mine bomb NBT Id." + + "To include 'any' armor stand include the keyword '*any*'. " + "'show' will make the armor stands visible for a few minutes " + "and optionally provide an id for showing only one. " + "removeAll' will remove all armor stands " + "within the general cubic-radius. And 'removeId' will remove " + "only one armor stand that matches the supplied ID. " - + " [list, show , removeAll, removeId ]") String options + + " [list, show , removeAll, removeId , *any*]") String options ) { if ( !isEnableMineBombs() ) { @@ -138,16 +139,23 @@ public void utilsFindMineBombsArmorStands( CommandSender sender, SpigotPlayer player = checkPlayerPerms( sender, playerName, "prison.utils.bomb", "prison.utils.bomb.others" ); + sender.sendMessage( "#### findArmorStands: radius: " + radius ); + boolean list = false; boolean show = false; boolean removeAll = false; boolean removeId = false; + boolean any = false; String uuid = null; options = options.toLowerCase().trim(); + if ( options.contains( "*any*" ) ) { + any = true; + options = options.replace( "*any*", "" ).trim(); + } if ( options.contains( "list" ) ) { list = true; options = options.replace( "list", "" ).trim(); From dadeee6391ab665da68c1f8b2f213faf3f58d776 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 6 Jul 2024 01:30:45 -0400 Subject: [PATCH 056/323] Mine Bombs: Refactoring how mine bombs are handled when placed. Had to shift a lot of the variable types over to more of the prison flavors to allow for better support of the newer functions. This is setting up support for throwing mine bombs. --- docs/changelog_v3.3.x.md | 4 + .../spigot/block/OnBlockBreakMines.java | 5 ++ .../prison/spigot/game/SpigotLocation.java | 5 ++ .../spigot/utils/PrisonBombListener.java | 84 ++++++++++++++----- .../spigot/utils/PrisonUtilsMineBombs.java | 18 ++-- 5 files changed, 87 insertions(+), 29 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 9d8d1c13d..91c48146d 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.18b 2024-07-06 +* **Mine Bombs: Refactoring how mine bombs are handled when placed.** Had to shift a lot of the variable types over to more of the prison flavors to allow for better support of the newer functions. +This is setting up support for throwing mine bombs. + + * **More work on the findArmorStands function.** Fixed an issue with getting the entities within an area too. Found that was not working correctly. 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 d136a301d..cdd7de9ad 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 @@ -184,6 +184,11 @@ public void setSpigotBlock(SpigotBlock spigotBlock) { } + public Mine findMine( SpigotPlayer player, SpigotBlock sBlock, List altBlocksSource, PrisonMinesBlockBreakEvent pmEvent ) + { + return findMine( player.getUniqueId(), sBlock, altBlocksSource, pmEvent ); + } + public Mine findMine( Player player, SpigotBlock sBlock, List altBlocksSource, PrisonMinesBlockBreakEvent pmEvent ) { return findMine( player.getUniqueId(), sBlock, altBlocksSource, pmEvent ); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotLocation.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotLocation.java index 6eaa9cb97..a6ad49e97 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotLocation.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotLocation.java @@ -2,6 +2,7 @@ import org.bukkit.Bukkit; +import tech.mcprison.prison.internal.World; import tech.mcprison.prison.spigot.SpigotUtil; import tech.mcprison.prison.util.Location; @@ -14,6 +15,10 @@ public SpigotLocation( Location location ) { super( location ); } + public SpigotLocation( World world, double x, double y, double z, float yaw, float pitch ) { + super( new Location( world, x, y, z, yaw, pitch) ); + } + public SpigotLocation( org.bukkit.Location bukkitLocation ) { super( SpigotUtil.bukkitLocationToPrison( bukkitLocation ) ); 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 83ac8ca39..1a36618dc 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 @@ -2,30 +2,40 @@ import java.util.HashSet; import java.util.List; +import java.util.Optional; import org.bukkit.Material; import org.bukkit.block.Block; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; +import org.bukkit.entity.Snowball; import org.bukkit.event.Event; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.block.Action; import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.entity.ProjectileHitEvent; import org.bukkit.event.player.PlayerDropItemEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.inventory.ItemStack; +import org.bukkit.util.Vector; import tech.mcprison.prison.Prison; import tech.mcprison.prison.bombs.MineBombData; import tech.mcprison.prison.bombs.MineBombs; import tech.mcprison.prison.mines.data.Mine; import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.block.OnBlockBreakMines; import tech.mcprison.prison.spigot.block.SpigotBlock; import tech.mcprison.prison.spigot.compat.Compatibility.EquipmentSlot; import tech.mcprison.prison.spigot.compat.SpigotCompatibility; +import tech.mcprison.prison.spigot.game.SpigotLocation; import tech.mcprison.prison.spigot.game.SpigotPlayer; +import tech.mcprison.prison.spigot.game.entity.SpigotArmorStand; import tech.mcprison.prison.spigot.nbt.PrisonNBTUtil; import tech.mcprison.prison.util.Location; @@ -74,7 +84,7 @@ public void onInteract( BlockPlaceEvent event ) { EquipmentSlot hand = SpigotCompatibility.getInstance().getHand(event); - boolean canceled = processBombTriggerEvent(event, player, bombName, + boolean canceled = processBombTriggerEvent( player, bombName, targetBlock, hand ); if ( canceled ) { @@ -114,7 +124,7 @@ public void onInteract( PlayerInteractEvent event ) { EquipmentSlot hand = SpigotCompatibility.getInstance().getHand(event); - boolean canceled = processBombTriggerEvent(event, player, bombName, + boolean canceled = processBombTriggerEvent( player, bombName, targetBlock, hand ); if ( canceled ) { @@ -154,10 +164,42 @@ else if ( bombName != null ){ return bombName; } - private boolean processBombTriggerEvent( Event event, Player player, + private boolean processBombTriggerEvent( SpigotPlayer sPlayer, + String bombName, SpigotBlock sBlock) { + + EquipmentSlot hand = null; + + return processBombTriggerEvent( sPlayer, bombName, sBlock, hand ); + } + private boolean processBombTriggerEvent( Player player, String bombName, Block targetBlock, EquipmentSlot hand ) { + SpigotPlayer sPlayer = new SpigotPlayer( player ); + + SpigotBlock sBlock = null; + +// SpigotPlayer sPlayer = new SpigotPlayer( player ); + + // If clicking AIR, then event.getClickedBlock() will be null... + // so if null, then use the player's location for placing the bomb. + if ( targetBlock == null ) { + Location loc = sPlayer.getLocation(); + + // Get the block 3 away from the player, in the direction (vector) in which + // the player is looking. + sBlock = (SpigotBlock) loc.add( loc.getDirection().multiply( 3 ) ) .getBlockAt(); + } + else { + sBlock = SpigotBlock.getSpigotBlock( targetBlock ); + } + + return processBombTriggerEvent( sPlayer, bombName, sBlock, hand ); + } + + private boolean processBombTriggerEvent( SpigotPlayer sPlayer, + String bombName, SpigotBlock sBlock, EquipmentSlot hand ) { + boolean canceled = false; @@ -190,25 +232,25 @@ private boolean processBombTriggerEvent( Event event, Player player, return canceled; } - SpigotBlock sBlock = null; - - SpigotPlayer sPlayer = new SpigotPlayer( player ); - - // If clicking AIR, then event.getClickedBlock() will be null... - // so if null, then use the player's location for placing the bomb. - if ( targetBlock == null ) { - Location loc = sPlayer.getLocation(); - - // Get the block 3 away from the player, in the direction (vector) in which - // the player is looking. - sBlock = (SpigotBlock) loc.add( loc.getDirection().multiply( 3 ) ) .getBlockAt(); - } - else { - sBlock = SpigotBlock.getSpigotBlock( targetBlock ); - } +// SpigotBlock sBlock = null; +// +//// SpigotPlayer sPlayer = new SpigotPlayer( player ); +// +// // If clicking AIR, then event.getClickedBlock() will be null... +// // so if null, then use the player's location for placing the bomb. +// if ( targetBlock == null ) { +// Location loc = sPlayer.getLocation(); +// +// // Get the block 3 away from the player, in the direction (vector) in which +// // the player is looking. +// sBlock = (SpigotBlock) loc.add( loc.getDirection().multiply( 3 ) ) .getBlockAt(); +// } +// else { +// sBlock = SpigotBlock.getSpigotBlock( targetBlock ); +// } - Mine mine = blockBreakMines.findMine(player, sBlock, null, null); + Mine mine = blockBreakMines.findMine( sPlayer, sBlock, null, null); if ( mine == null ) { // player is not in a mine, so do not allow them to trigger a mine bomb: @@ -257,7 +299,7 @@ else if ( !mine.hasMiningAccess( sPlayer ) ) { // EquipmentSlot hand = event.getHand(); // Output.get().logInfo( "### PrisonBombListener: PlayerInteractEvent 02 " ); - if ( getPrisonUtilsMineBombs().setBombInHand( player, bomb, sBlock, hand ) ) { + if ( getPrisonUtilsMineBombs().setBombInHand( sPlayer, bomb, sBlock, hand ) ) { // The item was a bomb and it was activated. // Cancel the event so the item will not be placed or processed farther. 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 8ae7d14fc..b41932851 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 @@ -972,7 +972,7 @@ public MineBombData getBombItem( String bombName ) { * @param bomb * @return */ - public boolean setBombInHand( Player player, + public boolean setBombInHand( SpigotPlayer sPlayer, MineBombData bomb, SpigotBlock sBlock, tech.mcprison.prison.spigot.compat.Compatibility.EquipmentSlot hand ) { boolean isABomb = false; @@ -1021,9 +1021,11 @@ else if ( bomb != null ) { bomb.setToolInHandName( xMat.name() ); } - SpigotPlayer sPlayer = new SpigotPlayer( player ); +// SpigotPlayer sPlayer = new SpigotPlayer( player ); - String playerUUID = player.getUniqueId().toString(); + String playerUUID = sPlayer.getUniqueId().toString(); +// String playerUUID = player.getUniqueId().toString(); + int cooldownTicks = checkPlayerCooldown( playerUUID ); if ( cooldownTicks == 0 ) { @@ -1094,7 +1096,7 @@ else if ( bomb != null ) { // check if in a mine: OnBlockBreakMines obbm = new OnBlockBreakMines(); - Mine mine = obbm.findMine( player, bombBlock, null, null ); + Mine mine = obbm.findMine( sPlayer, bombBlock, null, null ); if ( mine == null ) { // Cannot set the bomb outside of a mine, so cancel: @@ -1108,8 +1110,8 @@ else if ( bomb != null ) { SpigotItemStack itemInHand = hand == EquipmentSlot.HAND ? - SpigotCompatibility.getInstance().getPrisonItemInMainHand( player ) : - SpigotCompatibility.getInstance().getPrisonItemInOffHand( player ) + SpigotCompatibility.getInstance().getPrisonItemInMainHand( sPlayer ) : + SpigotCompatibility.getInstance().getPrisonItemInOffHand( sPlayer ) ; // Remove from inventory: @@ -1118,7 +1120,7 @@ else if ( bomb != null ) { if ( hand == EquipmentSlot.HAND ) { SpigotCompatibility.getInstance() - .setItemInMainHand( player, null ); + .setItemInMainHand( sPlayer, null ); } else { @@ -1138,7 +1140,7 @@ else if ( bomb != null ) { // Apply updates to the player's inventory: - player.updateInventory(); + sPlayer.updateInventory(); From 48199866bf14f31d617ae73e858ef290ed3d3ca0 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 6 Jul 2024 02:18:05 -0400 Subject: [PATCH 057/323] Player Cache: Adjustments to improve access to the RankPlayer object. --- docs/changelog_v3.3.x.md | 3 ++ .../cache/PlayerCacheCheckTimersTask.java | 32 +++++++++++++------ .../prison/cache/PlayerCacheEvents.java | 8 +++++ .../cache/PlayerCacheUnloadPlayerTask.java | 18 +++++++++-- 4 files changed, 48 insertions(+), 13 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 91c48146d..72ec46a8e 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.18b 2024-07-06 +* **Player Cache: Adjustments to improve access to the RankPlayer object.** + + * **Mine Bombs: Refactoring how mine bombs are handled when placed.** Had to shift a lot of the variable types over to more of the prison flavors to allow for better support of the newer functions. This is setting up support for throwing mine bombs. diff --git a/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheCheckTimersTask.java b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheCheckTimersTask.java index 431f7aede..a052deca6 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheCheckTimersTask.java +++ b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheCheckTimersTask.java @@ -7,6 +7,7 @@ import java.util.UUID; import tech.mcprison.prison.Prison; +import tech.mcprison.prison.internal.Player; import tech.mcprison.prison.ranks.data.RankPlayer; /** @@ -93,21 +94,32 @@ private void processCache() { if ( playerData != null ) { + playerData.checkTimers(); // By adding a zero earnings, this will force the earnings "cache" to // progress, even if the player stopped mining. playerData.addEarnings( 0, null ); - } - - UUID uuid = UUID.fromString( key ); - - RankPlayer rPlayer = Prison.get().getPlatform() - .getRankPlayer( uuid, - playerData != null ? playerData.getPlayerName() : "" ); - - if ( rPlayer != null ) { - rPlayer.updateTotalLastValues(playerData); + + RankPlayer rPlayer = null; + + Player player = playerData.getPlayer(); + + if ( player != null ) { + rPlayer = player.getRankPlayer(); + } + else { + UUID uuid = UUID.fromString( key ); + + + rPlayer = Prison.get().getPlatform() + .getRankPlayer( uuid, + playerData != null ? playerData.getPlayerName() : "" ); + } + + if ( rPlayer != null ) { + rPlayer.updateTotalLastValues(playerData); + } } } diff --git a/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheEvents.java b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheEvents.java index 127f9e2f4..920700444 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheEvents.java +++ b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheEvents.java @@ -51,6 +51,14 @@ public PlayerCacheEvents() { public void onPlayerJoin(PlayerJoinEvent event) { Player player = event.getPlayer(); + + + // Change all player cache references of "Player" to PlayerRank: + +// RankPlayer rPlayer = player.getRankPlayer(); +// RankPlayer rPlayer = Prison.get().getPlatform() +// .getRankPlayer( player.getUUID(), player.getName() ); + PlayerCache.getInstance().submitAsyncLoadPlayer( player ); } diff --git a/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheUnloadPlayerTask.java b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheUnloadPlayerTask.java index 5d18df8c7..c7b192c03 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheUnloadPlayerTask.java +++ b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheUnloadPlayerTask.java @@ -3,6 +3,7 @@ import java.util.UUID; import tech.mcprison.prison.Prison; +import tech.mcprison.prison.internal.Player; import tech.mcprison.prison.ranks.data.RankPlayer; public class PlayerCacheUnloadPlayerTask @@ -31,10 +32,21 @@ public void run() { UUID uuid = UUID.fromString( removed.getPlayerUuid() ); - RankPlayer rPlayer = Prison.get().getPlatform() - .getRankPlayer( uuid, + RankPlayer rPlayer = null; + + Player player = getPlayerData().getPlayer(); + if ( player != null ) { + rPlayer = player.getRankPlayer(); + } + else { + rPlayer = Prison.get().getPlatform() + .getRankPlayer( uuid, removed != null ? removed.getPlayerName() : "" ); - rPlayer.updateTotalLastValues( removed ); + + } + if ( rPlayer != null ) { + rPlayer.updateTotalLastValues( removed ); + } pCache.getCacheFiles().toJsonFile( removed ); } From 0e4c2b43450a8c7f1c80fb968492ee0baa13e111 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 6 Jul 2024 03:45:57 -0400 Subject: [PATCH 058/323] RankPlayer: Updated how some classes uses the RankPlayer object, and how it gets it, to help improve the code by simplifying it, and helping to ensure it's accurate. Also updated some of the comments in the PlayerManager. --- .../prison/ranks/commands/RankUpCommand.java | 15 ++++++- .../prison/ranks/commands/RanksCommands.java | 3 +- .../prison/ranks/managers/PlayerManager.java | 44 +++++++++++++------ .../prison/spigot/api/PrisonSpigotAPI.java | 24 ++++++++-- .../spigot/game/SpigotCommandSender.java | 3 +- 5 files changed, 67 insertions(+), 22 deletions(-) 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 f6b2034d1..1ab4cad4e 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 @@ -1186,10 +1186,21 @@ private String confirmLadder( CommandSender sender, String ladderName, RankPlaye } + /** + * This gets the RankPlayer for the given UUID or playerName. The 'sender' generally is the + * console, or an admin that is trying to run the command for a player. + * So although the sender has a 'getRankPlayer()' function, it may be for the wrong player. + * + + * + * @param sender The one who should get an messages, but is not the one for RankPlayer. + * @param playerUuid + * @param playerName + * @return + */ public RankPlayer getRankPlayer( CommandSender sender, UUID playerUuid, String playerName ) { - RankPlayer player = - PrisonRanks.getInstance().getPlayerManager().getPlayer(playerUuid, playerName); + RankPlayer player = PrisonRanks.getInstance().getPlayerManager().getPlayer(playerUuid, playerName); // Well, this isn't supposed to happen... if ( player == null ) { 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 759b92083..f65063f2f 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 @@ -1634,7 +1634,8 @@ public void rankPlayer(CommandSender sender, PlayerManager pm = PrisonRanks.getInstance().getPlayerManager(); - RankPlayer rankPlayer = pm.getPlayer(player.getUUID(), player.getName()); + RankPlayer rankPlayer = player.getRankPlayer(); +// RankPlayer rankPlayer = pm.getPlayer(player.getUUID(), player.getName()); // Get the cachedPlayer: PlayerCachePlayerData cPlayer = PlayerCache.getInstance().getOnlinePlayer( rankPlayer ); diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java index 3ea25f7f3..0d2a00002 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java @@ -289,6 +289,7 @@ public Set getPlayerErrors() { *

Get the player, if they don't exist, add them. *

* + * * @param uid * @return */ @@ -305,7 +306,9 @@ public RankPlayer getPlayer(UUID uid, String playerName) { if ( results == null ) { - debugLogPlayerInfo( "getPlayer(): UUID check:", playerName, false ); + // Debug info on player when results are null from the first "search". + debugLogPlayerInfo( "getPlayer(): UUID check (could not match on playerName):", playerName, + uid == null ? "none" : uid.toString(), false ); for ( RankPlayer rankPlayer : players ) { if ( uid != null && rankPlayer.getUUID().equals(uid) || @@ -335,7 +338,8 @@ public RankPlayer getPlayer(UUID uid, String playerName) { if ( results == null && playerName != null && !"console".equalsIgnoreCase( playerName ) ) { - debugLogPlayerInfo( "getPlayer(): addPlayer:", playerName, false ); + debugLogPlayerInfo( "getPlayer(): addPlayer (final attempt: could not match on playerName or UUID):", + playerName, uid == null ? "none" : uid.toString(), false ); results = addPlayer(uid, playerName); @@ -360,6 +364,12 @@ public RankPlayer getPlayer(UUID uid, String playerName) { public RankPlayer getPlayer( Player player ) { RankPlayer rPlayer = null; if ( player != null ) { + + // This function is called by SpigotCommander, as an example, and if we use the + // function 'player.getRankPlayer()' then that will become an endless loop. + // Also, we cannot use that either, because if the RankPlayer is null, then it + // needs to be added, which is what this class's 'getPlayer()' does. +// rPlayer = player.getRankPlayer(); rPlayer = getPlayer( player.getUUID(), player.getName() ); } return rPlayer; @@ -420,14 +430,16 @@ protected RankPlayer addPlayerSyncTask( UUID uid, String playerName ) { getPlayersByName().put( playerName, newPlayer ); - debugLogPlayerInfo( "addPlayerSyncTask: firstJoin:", playerName, false ); + debugLogPlayerInfo( "addPlayerSyncTask: firstJoin:", playerName, + newPlayer.getUUID().toString(), false ); rankPlayerFactory.firstJoin( newPlayer ); boolean joined = newPlayer.getPlayerRankDefault() != null; String msg = joined ? "joined" : "failed"; - debugLogPlayerInfo( "addPlayerSyncTask: " + msg, playerName, false ); + debugLogPlayerInfo( "addPlayerSyncTask: " + msg, playerName, + newPlayer.getUUID().toString(), false ); // the new player is now saved in firstJoin()( @@ -461,16 +473,19 @@ public void onPlayerJoin(PlayerJoinEvent event) { Player player = event.getPlayer(); - debugLogPlayerInfo( "onPlayerJoin:", player.getName(), true ); - - // Player is auto added if they do not exist when calling getPlayer so don't try to - // add them a second time. - RankPlayer rPlayer = getPlayer(player.getUUID(), player.getName()); - - rPlayer.doNothing(); + if ( player != null ) { + debugLogPlayerInfo( "onPlayerJoin:", player.getName(), player.getUUID().toString(), true ); + + // Player is auto added if they do not exist when calling getPlayer so don't try to + // add them a second time. + RankPlayer rPlayer = player.getRankPlayer(); +// RankPlayer rPlayer = getPlayer(player.getUUID(), player.getName()); + + rPlayer.doNothing(); + } } - public void debugLogPlayerInfo( String eventName, String playerName, boolean date ) { + public void debugLogPlayerInfo( String eventName, String playerName, String uuid, boolean date ) { if ( Output.get().isDebug() ) { @@ -483,11 +498,12 @@ public void debugLogPlayerInfo( String eventName, String playerName, boolean dat SimpleDateFormat sdFmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String msg = String.format( - "&6%s: &c%s &6%s &d%s", + "&6%s: &c%s &6%s &d%s uuid=%s", eventName, playerName, date ? sdFmt.format(new Date()) : "", - newPlayer ? "[New Player]" : "" + newPlayer ? "[New Player]" : "", + uuid ); Output.get().logInfo( msg ); 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 b5c43341f..d9200bbff 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 @@ -26,7 +26,6 @@ import tech.mcprison.prison.ranks.PrisonRanks; import tech.mcprison.prison.ranks.data.Rank; import tech.mcprison.prison.ranks.data.RankPlayer; -import tech.mcprison.prison.ranks.managers.PlayerManager; import tech.mcprison.prison.ranks.managers.RankManager; import tech.mcprison.prison.selection.Selection; import tech.mcprison.prison.spigot.SpigotPrison; @@ -168,14 +167,30 @@ public PrisonSortableResults getMines( MineSortOrder sortOrder ) { } + /** + *

This will get the prison's RankPlayer object, which will trigger adding the + * given player to Prison if they do not already exist. This is done through the + * SpigotPlayer. + *

+ * + * @param bukkitPlayer + * @return + */ public RankPlayer getRankPlayer( Player bukkitPlayer ) { RankPlayer results = null; if ( PrisonRanks.getInstance() != null && PrisonRanks.getInstance().isEnabled() ) { - PlayerManager pm = PrisonRanks.getInstance().getPlayerManager(); + SpigotPlayer sPlayer = new SpigotPlayer( bukkitPlayer ); + + if ( sPlayer != null ) { + + results = sPlayer.getRankPlayer(); + } - results = pm.getPlayer( bukkitPlayer.getUniqueId(), bukkitPlayer.getName() ); +// PlayerManager pm = PrisonRanks.getInstance().getPlayerManager(); +// +// results = pm.getPlayer( bukkitPlayer.getUniqueId(), bukkitPlayer.getName() ); } return results; @@ -780,7 +795,8 @@ public void payPlayer( Player player, double amount, String currency, boolean completelySilent = notifyPlayerEarned || notifyPlayerDelay || notifyPlayerEarningDelay || playSoundOnSellAll; SpigotPlayer sPlayer = new SpigotPlayer( player ); - RankPlayer rankPlayer = PrisonRanks.getInstance().getPlayerManager().getPlayer(sPlayer.getUUID(), sPlayer.getName()); + RankPlayer rankPlayer = sPlayer.getRankPlayer(); +// RankPlayer rankPlayer = PrisonRanks.getInstance().getPlayerManager().getPlayer(sPlayer.getUUID(), sPlayer.getName()); currency = currency != null && currency.equalsIgnoreCase("default") ? null : currency; 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 b1ae3ad97..e26df1fed 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 @@ -285,7 +285,8 @@ public RankPlayer getRankPlayer() { if ( PrisonRanks.getInstance().isEnabled() ) { - rankPlayer = PrisonRanks.getInstance().getPlayerManager().getPlayer( (Player) this ); + rankPlayer = PrisonRanks.getInstance().getPlayerManager() + .getPlayer( (Player) this ); } return rankPlayer; } From 4464e286bdf3d91d4dcdb0b3928ee4d99b643a18 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 6 Jul 2024 03:47:02 -0400 Subject: [PATCH 059/323] RankPlayer: Updated how some classes uses the RankPlayer object, and how it gets it, to help improve the code by simplifying it, and helping to ensure it's accurate. Also updated some of the comments in the PlayerManager. --- docs/changelog_v3.3.x.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 72ec46a8e..0b10379f7 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.18b 2024-07-06 +* **RankPlayer: Updated how some classes uses the RankPlayer object**, and how it gets it, to help improve the code by simplifying it, and helping to ensure it's accurate. +Also updated some of the comments in the PlayerManager. + + * **Player Cache: Adjustments to improve access to the RankPlayer object.** From befa0b58cfa59f1a44c93eafef7ab4be8a176999 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 6 Jul 2024 20:51:24 -0400 Subject: [PATCH 060/323] Mine Bomb Animations: More changes to fix more issues with the mine bombs in general, and the animations. These major changes has broke many things, so they are being hooked up little by little as each part is tested. --- docs/changelog_v3.3.x.md | 4 + .../bombs/MineBombDefaultConfigSettings.java | 2 +- .../prison/bombs/MineBombDetonateTask.java | 7 ++ .../animations/BombAnimationInfinity.java | 12 +- .../bombs/animations/BombAnimationNone.java | 109 ++++++++++++++++++ .../bombs/animations/BombAnimations.java | 14 ++- .../bombs/animations/BombAnimationsTask.java | 54 ++++++++- .../spigot/utils/PrisonUtilsMineBombs.java | 19 ++- .../utils/PrisonUtilsMineBombsTasks.java | 55 +++++---- 9 files changed, 234 insertions(+), 42 deletions(-) create mode 100644 prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombDetonateTask.java create mode 100644 prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationNone.java diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 0b10379f7..ccc41c751 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.18b 2024-07-06 +* **Mine Bomb Animations: More changes to fix more issues with the mine bombs in general, and the animations.** +These major changes has broke many things, so they are being hooked up little by little as each part is tested. + + * **RankPlayer: Updated how some classes uses the RankPlayer object**, and how it gets it, to help improve the code by simplifying it, and helping to ensure it's accurate. Also updated some of the comments in the PlayerManager. 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 00106a082..a1172d7b0 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 @@ -212,7 +212,7 @@ public void setupDefaultMineBombData(MineBombs mineBombs) mbd.setNameTag( "&7A &2Wimpy &cBomb" ); mbd.setItemName( MineBombData.MINE_BOMB_DEFAULT_ITEM_NAME ); - mbd.setRadiusInner( 2 ); + mbd.setRadiusInner( 1 ); mbd.setDescription("A whimpy bomb made with gunpowder and packs the punch of a " + "dull wooden pickaxe. For some reason, it only has a 40% chance of removing " + "a block."); diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombDetonateTask.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombDetonateTask.java new file mode 100644 index 000000000..ffc748c10 --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombDetonateTask.java @@ -0,0 +1,7 @@ +package tech.mcprison.prison.bombs; + +public interface MineBombDetonateTask { + + public void runDetonation(); + +} diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationInfinity.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationInfinity.java index e27f30ff0..2e3866979 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationInfinity.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationInfinity.java @@ -25,7 +25,7 @@ public class BombAnimationInfinity private float entityYaw; private float entityPitch; - private int id; + public BombAnimationInfinity( MineBombData bomb, @@ -46,7 +46,6 @@ public void initialize() { this.twoPI = Math.PI * 2; - setId( getTask().getAnimators().size() ); initializeArmorStand(); } @@ -79,7 +78,7 @@ private void initializeArmorStand() { armorStand.setRightArmPose(arm); - if ( initializeCustomName() ) { + if ( initializeCustomName() && getId() == 1 ) { //updateArmorStandCustomName(); armorStand.setCustomName( getTagName() ); @@ -151,11 +150,4 @@ public void step() } - public int getId() { - return id; - } - public void setId(int id) { - this.id = id; - } - } diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationNone.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationNone.java new file mode 100644 index 000000000..f26e13251 --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationNone.java @@ -0,0 +1,109 @@ +package tech.mcprison.prison.bombs.animations; + +import tech.mcprison.prison.bombs.MineBombData; +import tech.mcprison.prison.bombs.MineBombs; +import tech.mcprison.prison.internal.ArmorStand; +import tech.mcprison.prison.internal.ItemStack; +import tech.mcprison.prison.internal.block.PrisonBlock; +import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.util.BluesSemanticVersionComparator; +import tech.mcprison.prison.util.Location; + +public class BombAnimationNone + extends BombAnimations { + + private ArmorStand armorStand; + + private float entityYaw; + private float entityPitch; + + + public BombAnimationNone( MineBombData bomb, + PrisonBlock sBombBlock, ItemStack item, + BombAnimationsTask task, + float entityYaw, float entityPitch ) { + super( bomb, sBombBlock, item, task ); + + this.entityYaw = entityYaw; + this.entityPitch = entityPitch; + + initialize(); + } + + public void initialize() { + + initializeArmorStand(); + } + + private void initializeArmorStand() { + + Location location = getsBlock().getLocation(); + location.setY( location.getY() + 2.5 ); + + location.setYaw( entityYaw ); + location.setPitch( entityPitch + 90 ); + + + armorStand = location.spawnArmorStand(); + + armorStand.setNbtString( MineBombs.MINE_BOMBS_NBT_KEY, getBomb().getName() ); + + if ( armorStand != null ) { + + armorStand.setVisible(false); + armorStand.setRemoveWhenFarAway(false); + armorStand.setItemInHand( getItem() ); + //armorStand.setRightArmPose(arm); + + + if ( initializeCustomName() ) { + + //updateArmorStandCustomName(); + armorStand.setCustomName( getTagName() ); + armorStand.setCustomNameVisible(true); + } + else { + + armorStand.setCustomNameVisible(false); + } + + if ( new BluesSemanticVersionComparator().compareMCVersionTo( "1.9.0" ) >= 0 ) { + + armorStand.setGlowing( getBomb().isGlowing() ); + + // setGravity is invalid for spigot 1.8.8: + armorStand.setGravity( getBomb().isGravity() ); + } + } + + if ( Output.get().isDebug() ) { + String msg = String.format( + "### BombAnimationInfinity.initializeArmorStand : id: %s ", + Integer.toString(getId()) + + ); + Output.get().logInfo( msg ); + } + } + + + + + @Override + public void step() + { + + // Track the time that this has lived: + if ( --terminateOnZeroTicks == 0 || !armorStand.isValid() ) { + + armorStand.remove(); + + cancel(); + } + + updateCustomName(); + + } + + +} diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java index aee0ab9e9..471690d64 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java @@ -10,6 +10,8 @@ public abstract class BombAnimations { + private int id; + private BombAnimationsTask task; private MineBombData bomb; @@ -32,9 +34,11 @@ public BombAnimations( MineBombData bomb, BombAnimationsTask task ) { super(); - // Used for "canceling" the task: + // Used for "canceling" and detonating the task: this.task = task; + setId( getTask().getAnimators().size() ); + this.bomb = bomb; this.sBlock = sBombBlock; this.item = item; @@ -114,7 +118,13 @@ protected void updateCustomName() } } - + public int getId() { + return id; + } + public void setId(int id) { + this.id = id; + } + public BombAnimationsTask getTask() { return task; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationsTask.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationsTask.java index 4d9862b38..bb250f69b 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationsTask.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationsTask.java @@ -4,6 +4,7 @@ import java.util.List; import tech.mcprison.prison.bombs.MineBombData; +import tech.mcprison.prison.bombs.MineBombDetonateTask; import tech.mcprison.prison.bombs.MineBombs.AnimationPattern; import tech.mcprison.prison.internal.ItemStack; import tech.mcprison.prison.internal.block.PrisonBlock; @@ -18,16 +19,27 @@ public class BombAnimationsTask private List animators; + private MineBombDetonateTask detonateBomb; + + private boolean detonated = false; + private Object detonationLock; + public BombAnimationsTask() { super(); + this.detonationLock = new Object(); + this.animators = new ArrayList<>(); } public void animatorFactory( // AnimationPattern animation, - MineBombData bomb, PrisonBlock pBlock, ItemStack item ) { + MineBombData bomb, PrisonBlock pBlock, + ItemStack item, MineBombDetonateTask detonateBomb ) { + + this.detonateBomb = detonateBomb; + AnimationPattern animation = bomb.getAnimationPattern(); @@ -54,11 +66,11 @@ public void animatorFactory( float yaw = 0; float pitch = 0; - BombAnimationInfinity bai = new BombAnimationInfinity( bomb, + BombAnimationInfinity ba = new BombAnimationInfinity( bomb, pBlock, item, this, yaw, pitch ); - getAnimators().add( bai ); + getAnimators().add( ba ); submitTask(); } @@ -71,11 +83,11 @@ public void animatorFactory( float yawStep = 360f / 8f; for ( int i = 0; i < 8; i++ ) { - BombAnimationInfinity bai = new BombAnimationInfinity( bomb, + BombAnimationInfinity ba = new BombAnimationInfinity( bomb, pBlock, item, this, yaw, pitch ); - getAnimators().add( bai ); + getAnimators().add( ba ); yaw += yawStep; } @@ -87,10 +99,25 @@ public void animatorFactory( case none: + { + float yaw = 0; + float pitch = 0; + + BombAnimationNone ba = new BombAnimationNone( bomb, + pBlock, item, this, + yaw, pitch ); + + getAnimators().add( ba ); + submitTask(); + } + default: // Do nothing... do not submit task to run. break; } + + + detonateBomb(); } private void submitTask() { @@ -103,6 +130,23 @@ protected void cancel() { PrisonTaskSubmitter.cancelTask( getTaskId() ); } + private void detonateBomb() { + + // Need to use a multi-layered synchronized lock since there may be + // many animations ending at the same time, and we only want one to + // trigger the detonation. + if ( !detonated ) { + synchronized ( detonationLock ) { + if ( !detonated ) { + detonated = true; + + // Detonate the bomb using the callback: + detonateBomb.runDetonation(); + } + } + } + } + /** * The animators will override this function. 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 b41932851..1e3a2e2a1 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 @@ -22,6 +22,7 @@ import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; import tech.mcprison.prison.autofeatures.AutoFeaturesWrapper; import tech.mcprison.prison.bombs.MineBombData; +import tech.mcprison.prison.bombs.MineBombDetonateTask; import tech.mcprison.prison.bombs.MineBombEffectsData; import tech.mcprison.prison.bombs.MineBombEffectsData.EffectType; import tech.mcprison.prison.bombs.MineBombs; @@ -1137,18 +1138,28 @@ else if ( bomb != null ) { } - - // Apply updates to the player's inventory: sPlayer.updateInventory(); + + + final SpigotBlock sBombBlock = bombBlock; + MineBombDetonateTask detonateBomb = new MineBombDetonateTask() { + + @Override + public void runDetonation() { + + // Submit the bomb's task to go off: + setoffBombDelayed( sPlayer, bomb, sBombBlock ); + } + }; // This setups the animations that are assigned to each bomb type and // will submit the tasks, unless no animations are chosen. BombAnimationsTask animationsTask = new BombAnimationsTask(); - animationsTask.animatorFactory( bomb, bombBlock, itemInHand ); + animationsTask.animatorFactory( bomb, bombBlock, itemInHand, detonateBomb ); @@ -1183,7 +1194,7 @@ else if ( bomb != null ) { // Submit the bomb's task to go off: - //setoffBombDelayed( sPlayer, bomb, bombBlock ); +// setoffBombDelayed( sPlayer, bomb, bombBlock ); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTasks.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTasks.java index db670067d..cc7261cf6 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTasks.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTasks.java @@ -22,7 +22,6 @@ import tech.mcprison.prison.bombs.MineBombs; import tech.mcprison.prison.bombs.MineBombs.ExplosionOrientation; import tech.mcprison.prison.bombs.MineBombs.ExplosionShape; -import tech.mcprison.prison.bombs.animations.BombAnimationsTask; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.api.ExplosiveBlockBreakEvent; @@ -438,27 +437,43 @@ private List calculatBlocksForExplosion( MineBombData bo return results; } - public BombAnimationsTask submitPlacedMineBombItemTask( MineBombData bomb, SpigotBlock sBlock, SpigotItemStack item ) { - - - - // This setups the animations that are assigned to each bomb type and - // will submit the tasks, unless no animations are chosen. - BombAnimationsTask animationsTask = new BombAnimationsTask(); - - animationsTask.animatorFactory( bomb, sBlock, item ); - - return animationsTask; - -// PlacedMineBombItemTask placedTask = new PlacedMineBombItemTask( bomb, sBlock, item ); + + // NOT USED: +// public BombAnimationsTask submitPlacedMineBombItemTask( SpigotPlayer sPlayer, +// MineBombData bomb, +// SpigotBlock sBlock, SpigotItemStack item ) { // -// BukkitTask task = placedTask.runTaskTimer( -// SpigotPrison.getInstance(), 1, 1 ); // -// placedTask.setBukkitTask( task ); - -// return placedTask; - } +// +// final SpigotBlock sBombBlock = sBlock; +// MineBombDetonateTask detonateBomb = new MineBombDetonateTask() { +// +// @Override +// public void runDetonation() { +// +// // Submit the bomb's task to go off: +// setoffBombDelayed( sPlayer, bomb, sBombBlock ); +// } +// }; +// +// +// // This setups the animations that are assigned to each bomb type and +// // will submit the tasks, unless no animations are chosen. +// BombAnimationsTask animationsTask = new BombAnimationsTask(); +// +// animationsTask.animatorFactory( bomb, sBlock, item, detonateBomb ); +// +// return animationsTask; +// +//// PlacedMineBombItemTask placedTask = new PlacedMineBombItemTask( bomb, sBlock, item ); +//// +//// BukkitTask task = placedTask.runTaskTimer( +//// SpigotPrison.getInstance(), 1, 1 ); +//// +//// placedTask.setBukkitTask( task ); +// +//// return placedTask; +// } // public class PlacedMineBombItemTask // extends BukkitRunnable From 10aa5ef48021b96f9f6512faedff21c579c62150 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 6 Jul 2024 21:00:34 -0400 Subject: [PATCH 061/323] Mine bomb animations: Throw velocity. Added support for throw velocity by providing a low and high range, which will randomly select a value between those points. This provides for a variation in throw speed to keep it challenging. --- docs/changelog_v3.3.x.md | 4 ++ .../mcprison/prison/bombs/MineBombData.java | 52 +++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index ccc41c751..770f32cdf 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.18b 2024-07-06 +* **Mine bomb animations: Throw velocity.** +Added support for throw velocity by providing a low and high range, which will randomly select a value between those points. This provides for a variation in throw speed to keep it challenging. + + * **Mine Bomb Animations: More changes to fix more issues with the mine bombs in general, and the animations.** These major changes has broke many things, so they are being hooked up little by little as each part is tested. 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 35dc20437..ce2f3ba75 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 @@ -166,6 +166,11 @@ public class MineBombData private AnimationPattern animationPattern = AnimationPattern.infinity; + + private double throwVelocityLow = 1.5; + private double throwVelocityHigh = 3; + + /** *

On spigot versions that support it, the bomb, when placed, will glow. * Was introduced with Minecraft 1.9. Applies only to Entities, of which @@ -290,6 +295,11 @@ public MineBombData( String name, String itemType, String explosionShape, this.animationPattern = AnimationPattern.infinity; // setAnimationPattern( AnimationPattern.infinity ); + + this.throwVelocityLow = 1.5; + this.throwVelocityHigh = 3; + + this.glowing = false; this.gravity = true; @@ -333,6 +343,10 @@ public MineBombData clone() { cloned.setAnimationPattern( getAnimationPattern() ); + cloned.setThrowVelocityLow( getThrowVelocityLow() ); + cloned.setThrowVelocityHigh( getThrowVelocityHigh() ); + + cloned.setItemRemovalDelayTicks( getItemRemovalDelayTicks() ); cloned.setAutosell( isAutosell() ); @@ -414,6 +428,30 @@ public int compareTo(MineBombData o) { return results; } + + + /** + *

This function calculates the throw velocity based upon a randomly generated + * value between the 'throwValueVelocityLow' and 'throwVelocityHeigh'. + *

+ * + * @return + */ + public double getThrowVelocity() { + double results = getThrowVelocityLow(); + + if ( getThrowVelocityLow() != getThrowVelocityHigh() ) { + + double range = getThrowVelocityLow() < getThrowVelocityHigh() ? + getThrowVelocityHigh() - getThrowVelocityLow() : + getThrowVelocityLow() - getThrowVelocityHigh(); + double rnd = Math.random() * range; + + results += rnd; + } + + return results; + } public String getName() { @@ -606,6 +644,20 @@ public void setAnimationPattern(AnimationPattern animationPattern) { animationPattern; } + public double getThrowVelocityLow() { + return throwVelocityLow; + } + public void setThrowVelocityLow(double throwVelocityLow) { + this.throwVelocityLow = throwVelocityLow; + } + + public double getThrowVelocityHigh() { + return throwVelocityHigh; + } + public void setThrowVelocityHigh(double throwVelocityHigh) { + this.throwVelocityHigh = throwVelocityHigh; + } + public boolean isAutosell() { return autosell; } From 039052d13b020bc5a18cf1b192bc66ff10aa9811 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 6 Jul 2024 21:04:33 -0400 Subject: [PATCH 062/323] NBT library: Some adjustments to make the code more "correct". This does not work with entities, since you can write a value to the entity, but you cannot read it. ItemStacks do work fine. --- docs/changelog_v3.3.x.md | 5 +++++ .../prison/spigot/nbt/PrisonNBTUtil.java | 21 +++++++++++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 770f32cdf..c3fde55a0 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.18b 2024-07-06 +* **NBT library: Some adjustments to make the code more "correct".** +This does not work with entities, since you can write a value to the entity, but you cannot read it. +ItemStacks do work fine. + + * **Mine bomb animations: Throw velocity.** Added support for throw velocity by providing a low and high range, which will randomly select a value between those points. This provides for a variation in throw speed to keep it challenging. 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 021ad750d..99aa3ea9d 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 @@ -48,7 +48,14 @@ public static String getNBTString( ItemStack bukkitStack, String key ) { String results = null; try { - Function gsFnc = nbt -> nbt.getString(key); + Function gsFnc = nbt -> { + String value = (String) nbt.getString(key); + +// if ( Output.get().isDebug() ) { +// Output.get().logInfo( "PrisonNBTUtil.getNBTString():ItemStack: %s", nbt.toString() ); +// } + return value; + }; results = NBT.get(bukkitStack, gsFnc ); // results = NBT.get(bukkitStack, nbt -> nbt.getString(key)); @@ -68,7 +75,7 @@ public static String getNBTString( Block bukkitBlock, String key ) { String results = null; try { - Function gsFnc = nbt -> nbt.getString(key); + Function gsFnc = nbt -> (String) nbt.getString(key); BlockState blockState = bukkitBlock.getState(); @@ -158,9 +165,15 @@ public static String getNBTString( Entity entity, String key ) { String results = null; try { - Function gsFnc = nbt -> nbt.getString(key); + results = NBT.get(entity, nbt -> { + + String value = (String) nbt.getString(key); + return value; + }); + +// Function gsFnc = nbt -> (String) nbt.getString(key); - results = NBT.get(entity, gsFnc ); +// results = NBT.get(entity, gsFnc ); // results = NBT.get(bukkitStack, nbt -> nbt.getString(key)); } catch (Exception e) { From 1ae46a36d677f3816fbd70401a0cea29ecf5020e Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 6 Jul 2024 21:05:54 -0400 Subject: [PATCH 063/323] Rankup: removed dead code. --- docs/changelog_v3.3.x.md | 3 +++ .../mcprison/prison/ranks/commands/RankUpCommand.java | 8 ++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index c3fde55a0..2f869730e 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.18b 2024-07-06 +* **Rankup: removed dead code.** + + * **NBT library: Some adjustments to make the code more "correct".** This does not work with entities, since you can write a value to the entity, but you cannot read it. ItemStacks do work fine. 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 1ab4cad4e..f634c3e15 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 @@ -874,10 +874,10 @@ public void promotePlayer(CommandSender sender, Player player = getPlayer( sender, playerName ); UUID playerUuid = player.getUUID(); - if (player == null) { - ranksPromotePlayerMustBeOnlineMsg( sender ); - return; - } +// if (player == null) { +// ranksPromotePlayerMustBeOnlineMsg( sender ); +// return; +// } RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); RankPlayer rankPlayer = getRankPlayer( sender, playerUuid, player.getName() ); From 057c961274c0e54604d1512acb1b60e77637d5c6 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 6 Jul 2024 21:18:48 -0400 Subject: [PATCH 064/323] Mine bombs: More work on getting the new mine bombs functional and working better. Still not perfect and fully working yet, but getting there. --- docs/changelog_v3.3.x.md | 5 + .../tech/mcprison/prison/bombs/MineBombs.java | 368 +++--------------- .../spigot/game/entity/SpigotArmorStand.java | 10 + .../spigot/utils/PrisonBombListener.java | 70 ++-- .../spigot/utils/PrisonUtilsMineBombs.java | 42 +- .../utils/PrisonUtilsMineBombsTasks.java | 1 + 6 files changed, 143 insertions(+), 353 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 2f869730e..5386ad9b9 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.18b 2024-07-06 +* **Mine bombs: More work on getting the new mine bombs functional and working better. +Still not perfect and fully working yet, but getting there.** + + + * **Rankup: removed dead code.** 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 6aa5a3932..671193b9d 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 @@ -18,11 +18,12 @@ public class MineBombs { public static final String MINE_BOMBS_NBT_KEY = "MineBombNbtKey"; public static final String MINE_BOMBS_NBT_THROWER_UUID = "MineBombNbtThrowerUUID"; + public static final String MINE_BOMBS_NBT_OWNER_UUID = "MineBombNbtOwnerUUID"; public static final String MINE_BOMBS_FILE_NAME = "mineBombsConfig.json"; public static final String MINE_BOMBS_PATH_NAME = "module_conf/mines"; - public static final String MINE_BOMBS_NBT_BOMB_KEY = "PrisonMineBombNbtKey"; +// public static final String MINE_BOMBS_NBT_BOMB_KEY = "PrisonMineBombNbtKey"; private static MineBombs instance; @@ -161,27 +162,75 @@ public int compareTo(MineBombs o) { } +// /** +// *

This finds a bomb with the given name, and returns a clone. The clone is +// * important since individual instances will set the isActivated() variable to +// * true if the bomb is active. If it's activated, then that indicates the +// * bomb will be used and the bomb was removed from the player's inventory. +// *

+// * +// * @param bombName +// * @return +// */ +// public MineBombData findBomb( String bombName ) { +// MineBombData bombOriginal = null; +// +// if ( bombName != null ) { +// +// // Remove color codes from bomb's name for matching: +// bombName = Text.stripColor( bombName ); +// +// bombOriginal = getConfigData().getBombs().get( bombName.toLowerCase() ); +// } +// +// return bombOriginal.clone(); +// } + + /** - *

This finds a bomb with the given name, and returns a clone. The clone is - * important since individual instances will set the isActivated() variable to - * true if the bomb is active. If it's activated, then that indicates the - * bomb will be used and the bomb was removed from the player's inventory. + *

This finds a bomb based upon a bombName which may include formatting. + * All formatting is removed from the search name, and the bomb names prior to + * making any comparisons. The bomb's key is also checked too for a match. + *

+ * + *

When a mine bomb is found, it is cloned since some bomb values will + * change during the detonation sequence, so cloning prevents altering the + * original source. *

* * @param bombName * @return */ - public MineBombData findBomb( String bombName ) { - MineBombData bombOriginal = null; + public MineBombData findBombByName( String bombName ) + { + MineBombData results = null; + + String cleanedBombName = Text.stripColor( bombName.toLowerCase() ); + + if ( cleanedBombName != null && !cleanedBombName.isEmpty() ) { + for ( String bombKey : getConfigData().getBombs().keySet() ) + { + MineBombData bomb = getConfigData().getBombs().get( bombKey ); + + if ( bomb != null ) { + String cBombName = Text.stripColor( bomb.getName().toLowerCase() ); - if ( bombName != null ) { - - bombOriginal = getConfigData().getBombs().get( bombName.toLowerCase() ); + if ( cBombName != null && + (cBombName.equalsIgnoreCase( cleanedBombName ) || + cleanedBombName.equalsIgnoreCase( bombKey )) ) { + + results = bomb; + } + } + + + } } - return bombOriginal.clone(); + return results == null ? null : results.clone(); } + public void saveConfigJson() { JsonFileIO fio = new JsonFileIO( null, null ); @@ -675,274 +724,6 @@ public List calculateCube( Location loc1, Location loc2 ) { -// -// @SuppressWarnings( "unused" ) -// public void setupDefaultMineBombData() -// { -// if ( getConfigData().getBombs().size() == 0 ) { -// -//// XMaterial.WOODEN_PICKAXE; -//// XMaterial.STONE_PICKAXE; -//// XMaterial.IRON_PICKAXE; -//// XMaterial.GOLDEN_PICKAXE; -//// XMaterial.DIAMOND_PICKAXE; -//// XMaterial.NETHERITE_PICKAXE; -// -// MineBombEffectsData mbeSound01 = new MineBombEffectsData( "ENTITY_CREEPER_PRIMED", EffectState.placed, 0 ); -// MineBombEffectsData mbeSound02 = new MineBombEffectsData( "CAT_HISS", EffectState.placed, 0 ); -// -// MineBombEffectsData mbeSound03 = new MineBombEffectsData( "ENTITY_GENERIC_EXPLODE", EffectState.explode, 0 ); -// MineBombEffectsData mbeSound04 = new MineBombEffectsData( "ENTITY_DRAGON_FIREBALL_EXPLODE", EffectState.explode, 0 ); -// -// // Does not work with spigot 1.8.x: -// MineBombEffectsData mbeExplode01 = new MineBombEffectsData( "FIREWORKS_SPARK", EffectState.placed, 0 ); -// // Does not work with spigot 1.8.x: -// MineBombEffectsData mbeExplode02 = new MineBombEffectsData( "BUBBLE_COLUMN_UP", EffectState.placed, 0 ); -// MineBombEffectsData mbeExplode03 = new MineBombEffectsData( "ENCHANTMENT_TABLE", EffectState.placed, 0 ); -// -//// MineBombEffectsData mbeExplode05 = new MineBombEffectsData( "END_ROD", EffectState.placed, 0 ); -// MineBombEffectsData mbeExplode04 = new MineBombEffectsData( "FLAME", EffectState.placed, 0 ); -// // Does not work with spigot 1.8.x: -// MineBombEffectsData mbeExplode08 = new MineBombEffectsData( "DRAGON_BREATH", EffectState.placed, 0 ); -// -// MineBombEffectsData mbeExplode06a = new MineBombEffectsData( "SMOKE", EffectState.placed, 0 ); -// // Does not work with spigot 1.8.x: -// MineBombEffectsData mbeExplode06 = new MineBombEffectsData( "SMOKE_NORMAL", EffectState.placed, 0 ); -// // Does not work with spigot 1.8.x: -// MineBombEffectsData mbeExplode07 = new MineBombEffectsData( "SMOKE_LARGE", EffectState.placed, 0 ); -// -// MineBombEffectsData mbeExplode10 = new MineBombEffectsData( "EXPLOSION_NORMAL", EffectState.explode, 0 ); -// MineBombEffectsData mbeExplode11 = new MineBombEffectsData( "EXPLOSION_LARGE", EffectState.explode, 0 ); -// // Does not work with spigot 1.8.x: -// MineBombEffectsData mbeExplode12 = new MineBombEffectsData( "EXPLOSION_HUGE", EffectState.explode, 0 ); -// -// -// { -// MineBombData mbd = new MineBombData( -// "SmallBomb", "brewing_stand", ExplosionShape.sphere.name(), 2, "&dSmall &6Mine &eBomb &3(lore line 1)" ); -// -// mbd.setNameTag( "&6&kABC&r&c-= &7{name}&c =-&6&kCBA" ); -// -// mbd.setToolInHandName( "DIAMOND_PICKAXE" ); -// mbd.setToolInHandFortuneLevel( 0 ); -// mbd.setDescription("A small mine bomb made with some chemicals and a brewing stand."); -// -// mbd.getLore().add( "&4Lore line 2" ); -// mbd.getLore().add( "&aLore line &73" ); -// -// mbd.getSoundEffects().add( mbeSound01.clone() ); -// mbd.getSoundEffects().add( mbeSound02.clone().setOffsetTicks( 30 ) ); -// mbd.getSoundEffects().add( mbeSound03.clone() ); -// -// mbd.getVisualEffects().add( mbeExplode04.clone() ); -// mbd.getVisualEffects().add( mbeExplode03.clone().setOffsetTicks( 30 ) ); -// -// mbd.getVisualEffects().add( mbeExplode06a.clone() ); -// mbd.getVisualEffects().add( mbeExplode10.clone() ); -// mbd.getVisualEffects().add( mbeExplode06.clone() ); -// -// mbd.setCooldownTicks( 10 ); -// -// getConfigData().getBombs().put( mbd.getName().toLowerCase(), mbd ); -// -// } -// -// { -// MineBombData mbd = new MineBombData( -// "MediumBomb", "firework_rocket", ExplosionShape.sphere.name(), 5, "Medium Mine Bomb" ); -// mbd.setDescription("A medium mine bomb made from leftover fireworks, " + -// "but supercharged with a strange green glowing liquid."); -// -// mbd.setNameTag( "&6&k1 23 456&r&a-=- &7{name}&a -=-&6&k654 32 1" ); -// -// mbd.setToolInHandName( "DIAMOND_PICKAXE" ); -// mbd.setToolInHandFortuneLevel( 3 ); -// -// mbd.getSoundEffects().add( mbeSound01.clone() ); -// mbd.getSoundEffects().add( mbeSound02.clone().setOffsetTicks( 30 ) ); -// mbd.getSoundEffects().add( mbeSound03.clone() ); -// -// mbd.getVisualEffects().add( mbeExplode04.clone() ); -// mbd.getVisualEffects().add( mbeExplode03.clone().setOffsetTicks( 30 ) ); -// -// mbd.getVisualEffects().add( mbeExplode10.clone() ); -// mbd.getVisualEffects().add( mbeExplode06.clone() ); -// -// mbd.setCooldownTicks( 60 ); -// -// getConfigData().getBombs().put( mbd.getName().toLowerCase(), mbd ); -// -// } -// -// { -// MineBombData mbd = new MineBombData( -// "LargeBomb", "tnt", ExplosionShape.sphereHollow.name(), 12, "Large Mine Bomb" ); -// mbd.setRadiusInner( 3 ); -// mbd.setDescription("A large mine bomb made from TNT with some strange parts " + -// "that maybe be described as alien technology."); -// mbd.setToolInHandName( "DIAMOND_PICKAXE" ); -// mbd.setToolInHandFortuneLevel( 3 ); -// -// mbd.getSoundEffects().add( mbeSound01.clone() ); -// mbd.getSoundEffects().add( mbeSound02.clone().setOffsetTicks( 30 ) ); -// mbd.getSoundEffects().add( mbeSound03.clone().setVolumne( 2.0f ) ); -// -// mbd.getVisualEffects().add( mbeExplode04.clone() ); -// mbd.getVisualEffects().add( mbeExplode03.clone().setOffsetTicks( 30 ) ); -// -// mbd.getVisualEffects().add( mbeExplode10.clone() ); -// mbd.getVisualEffects().add( mbeExplode06.clone() ); -// mbd.getVisualEffects().add( mbeExplode06a.clone() ); -// -// mbd.setCooldownTicks( 60 ); -// -// getConfigData().getBombs().put( mbd.getName().toLowerCase(), mbd ); -// } -// -// { -// MineBombData mbd = new MineBombData( -// "OofBomb", "tnt_minecart", ExplosionShape.sphereHollow.name(), 21, "Oof Mine Bomb" ); -// mbd.setRadiusInner( 3 ); -// -// mbd.setNameTag( "&c&k1&6&k23&e&k456&r&a-=- &4{countdown} &5-=- &7{name} &5-=- &4{countdown} &a-=-&e&k654&6&k32&c&k1" ); -// -// mbd.setDescription("An oof-ably large mine bomb made with a minecart heaping with TNT. " + -// "Unlike the large mine bomb, this one obviously is built with alien technology."); -// -// mbd.setToolInHandName( "GOLDEN_PICKAXE" ); -// mbd.setToolInHandFortuneLevel( 13 ); -// -// mbd.getSoundEffects().add( mbeSound01.clone() ); -// mbd.getSoundEffects().add( mbeSound02.clone().setOffsetTicks( 10 ).setVolumne( 0.25f ).setPitch( 0.25f ) ); -// mbd.getSoundEffects().add( mbeSound02.clone().setOffsetTicks( 20 ).setVolumne( 0.5f ).setPitch( 0.5f ) ); -// mbd.getSoundEffects().add( mbeSound02.clone().setOffsetTicks( 30 ).setVolumne( 1.0f ).setPitch( 0.75f ) ); -// mbd.getSoundEffects().add( mbeSound02.clone().setOffsetTicks( 40 ).setVolumne( 2.0f ).setPitch( 1.5f ) ); -// mbd.getSoundEffects().add( mbeSound02.clone().setOffsetTicks( 50 ).setVolumne( 5.0f ).setPitch( 2.5f ) ); -// -// mbd.getSoundEffects().add( mbeSound03.clone().setOffsetTicks( 0 ).setVolumne( 3.0f ) ); -// mbd.getSoundEffects().add( mbeSound04.clone().setOffsetTicks( 5 ).setVolumne( 1.5f ) ); -// mbd.getSoundEffects().add( mbeSound03.clone().setOffsetTicks( 10 ).setVolumne( 2.5f ) ); -// mbd.getSoundEffects().add( mbeSound04.clone().setOffsetTicks( 15 ).setVolumne( 1.0f ) ); -// mbd.getSoundEffects().add( mbeSound03.clone().setOffsetTicks( 20 ).setVolumne( 2.0f ) ); -// mbd.getSoundEffects().add( mbeSound04.clone().setOffsetTicks( 25 ).setVolumne( 0.75f ) ); -// mbd.getSoundEffects().add( mbeSound03.clone().setOffsetTicks( 30 ).setVolumne( 1.5f ) ); -// mbd.getSoundEffects().add( mbeSound04.clone().setOffsetTicks( 35 ).setVolumne( 0.55f ) ); -// mbd.getSoundEffects().add( mbeSound03.clone().setOffsetTicks( 40 ).setVolumne( 1.0f ) ); -// mbd.getSoundEffects().add( mbeSound04.clone().setOffsetTicks( 45 ).setVolumne( 0.25f ) ); -// mbd.getSoundEffects().add( mbeSound03.clone().setOffsetTicks( 50 ).setVolumne( 0.5f ) ); -// mbd.getSoundEffects().add( mbeSound04.clone().setOffsetTicks( 55 ).setVolumne( 0.15f ) ); -// -// -// mbd.getVisualEffects().add( mbeExplode06.clone() ); -// mbd.getVisualEffects().add( mbeExplode06a.clone() ); -// mbd.getVisualEffects().add( mbeExplode03.clone() ); -// mbd.getVisualEffects().add( mbeExplode12.clone() ); -// mbd.getVisualEffects().add( mbeExplode12.clone().setOffsetTicks( 30 ) ); -// mbd.getVisualEffects().add( mbeExplode12.clone().setOffsetTicks( 60 ) ); -// mbd.getVisualEffects().add( mbeExplode07.clone().setOffsetTicks( 60 ) ); -// mbd.getVisualEffects().add( mbeExplode08.clone().setOffsetTicks( 90 ) ); -// -// mbd.getVisualEffects().add( mbeExplode10.clone() ); -// mbd.getVisualEffects().add( mbeExplode06.clone().setOffsetTicks( 20 ) ); -// -// mbd.setAutosell( true ); -// mbd.setGlowing( true ); -// mbd.setAutosell( true ); -// -// mbd.setCooldownTicks( 60 ); -// mbd.setFuseDelayTicks( 13 * 20 ); // 13 seconds -// -// getConfigData().getBombs().put( mbd.getName().toLowerCase(), mbd ); -// } -// -// { -// MineBombData mbd = new MineBombData( -// "WimpyBomb", "GUNPOWDER", ExplosionShape.sphere.name(), 5, -// "A Wimpy Mine Bomb" ); -//// mbd.setLoreBombItemId( "&7A &2Wimpy &cBomb &9...&02A3F" ); -// -// mbd.setNameTag( "&7A &2Wimpy &cBomb" ); -// -// mbd.setRadiusInner( 2 ); -// mbd.setDescription("A whimpy bomb made with gunpowder and packs the punch of a " + -// "dull wooden pickaxe. For some reason, it only has a 40% chance of removing " + -// "a block."); -// -// mbd.getLore().add( "" ); -// mbd.getLore().add( "A whimpy bomb made with gunpowder and packs the punch " ); -// mbd.getLore().add( "of a dull wooden pickaxe. For some reason, it only " ); -// mbd.getLore().add( "has a 40% chance of removing a block." ); -// mbd.getLore().add( "" ); -// mbd.getLore().add( "Not labeled for retail sale." ); -// -// mbd.setToolInHandName( "WOODEN_PICKAXE" ); -// mbd.setToolInHandFortuneLevel( 0 ); -// mbd.setRemovalChance( 40.0d ); -// -// mbd.getSoundEffects().add( mbeSound01.clone() ); -// mbd.getSoundEffects().add( mbeSound02.clone().setOffsetTicks( 30 ) ); -// mbd.getSoundEffects().add( mbeSound03.clone() ); -// -// mbd.getVisualEffects().add( mbeExplode01.clone() ); -// mbd.getVisualEffects().add( mbeExplode02.clone().setOffsetTicks( 30 ) ); -// mbd.getVisualEffects().add( mbeExplode03.clone().setOffsetTicks( 10 ) ); -// mbd.getVisualEffects().add( mbeExplode04.clone() ); -// -// mbd.getVisualEffects().add( mbeExplode10.clone() ); -// mbd.getVisualEffects().add( mbeExplode06.clone() ); -// mbd.getVisualEffects().add( mbeExplode06a.clone() ); -// mbd.getVisualEffects().add( mbeExplode11.clone().setOffsetTicks( 05 ) ); -// -// mbd.setCooldownTicks( 3 * 20 ); // 3 seconds -// mbd.setFuseDelayTicks( 2 * 20 ); // 2 seconds -// -// mbd.setGlowing( true ); -// mbd.setGravity( false ); -// -// mbd.setCooldownTicks( 5 ); -// -// getConfigData().getBombs().put( mbd.getName().toLowerCase(), mbd ); -// } -// -// -// { -// MineBombData mbd = new MineBombData( -// "CubeBomb", "SLIME_BLOCK", ExplosionShape.cube.name(), 2, -// "A Cubic Bomb" ); -// mbd.setDescription("The most anti-round bomb you will ever be able to find. " + -// "It's totally cubic."); -// -// mbd.setToolInHandName( "DIAMOND_PICKAXE" ); -// mbd.setToolInHandFortuneLevel( 7 ); -// mbd.setRemovalChance( 100.0d ); -// -// mbd.getSoundEffects().add( mbeSound01.clone() ); -// mbd.getSoundEffects().add( mbeSound02.clone().setOffsetTicks( 30 ) ); -// mbd.getSoundEffects().add( mbeSound03.clone() ); -// -// mbd.getVisualEffects().add( mbeExplode04.clone() ); -// mbd.getVisualEffects().add( mbeExplode02.clone().setOffsetTicks( 30 ) ); -// -// mbd.setGlowing( true ); -// -// mbd.setCooldownTicks( 60 ); -// -// getConfigData().getBombs().put( mbd.getName().toLowerCase(), mbd ); -// } -// -// -// saveConfigJson(); -// -// Output.get().logInfo( "Mine bombs: setup default values." ); -// } -// else { -// Output.get().logInfo( "Could not generate a mine bombs save file since at least one " + -// "mine bomb already exists." ); -// } -// -// } - - public MineBombsConfigData getConfigData() { return configData; } @@ -950,33 +731,4 @@ public void setConfigData( MineBombsConfigData configData ) { this.configData = configData; } - - public MineBombData findBombByName( String bombName ) - { - MineBombData results = null; - - String cleanedBombName = Text.stripColor( bombName ); - - if ( cleanedBombName != null && !cleanedBombName.isEmpty() ) { - for ( String bombKey : getConfigData().getBombs().keySet() ) - { - MineBombData bomb = getConfigData().getBombs().get( bombKey ); - - if ( bomb != null ) { - String cBombName = Text.stripColor( bomb.getName() ); - - if ( cBombName != null && - cBombName.equalsIgnoreCase( cleanedBombName ) ) { - - results = bomb; - } - } - - - } - } - - return results; - } - } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotArmorStand.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotArmorStand.java index 8c7a2fa84..cb651f52d 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotArmorStand.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotArmorStand.java @@ -1,5 +1,6 @@ package tech.mcprison.prison.spigot.game.entity; +import tech.mcprison.prison.internal.Entity; import tech.mcprison.prison.internal.EulerAngle; import tech.mcprison.prison.internal.ItemStack; import tech.mcprison.prison.spigot.block.SpigotItemStack; @@ -27,6 +28,15 @@ public SpigotArmorStand( org.bukkit.entity.ArmorStand bArmorStand ) { // return sArmorStand; // } + public SpigotArmorStand(Entity entity) { + super( ((SpigotEntity) entity).getBukkitEntity() ); + + org.bukkit.entity.Entity bEntity = ((SpigotEntity) entity).getBukkitEntity(); + if ( bEntity instanceof org.bukkit.entity.ArmorStand ) { + this.bArmorStand = (org.bukkit.entity.ArmorStand) bEntity; + } + } + @Override public boolean isVisible() { return bArmorStand.isVisible(); 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 1a36618dc..3892cf41d 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 @@ -2,7 +2,6 @@ import java.util.HashSet; import java.util.List; -import java.util.Optional; import org.bukkit.Material; import org.bukkit.block.Block; @@ -10,8 +9,6 @@ import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; -import org.bukkit.entity.Snowball; -import org.bukkit.event.Event; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; @@ -71,20 +68,29 @@ public void onInteract( BlockPlaceEvent event ) { ItemStack iStack = event.getItemInHand(); - if ( iStack.getType() != Material.AIR ) { + if ( iStack != null && iStack.getType() != Material.AIR ) { String bombName = checkMineBombItemStack( iStack ); if ( bombName != null ) { + MineBombData mineBomb = MineBombs.getInstance().findBombByName(bombName); + Player player = event.getPlayer(); + PrisonNBTUtil.setNBTString(iStack, + MineBombs.MINE_BOMBS_NBT_KEY, + bombName ); + PrisonNBTUtil.setNBTString(iStack, + MineBombs.MINE_BOMBS_NBT_THROWER_UUID, + player.getUniqueId().toString() ); + Block targetBlock = event.getBlockAgainst(); EquipmentSlot hand = SpigotCompatibility.getInstance().getHand(event); - boolean canceled = processBombTriggerEvent( player, bombName, + boolean canceled = processBombTriggerEvent( player, mineBomb, targetBlock, hand ); if ( canceled ) { @@ -96,7 +102,13 @@ public void onInteract( BlockPlaceEvent event ) { } - @EventHandler( priority = EventPriority.LOW ) + + /** + *

This function will initiate the placement of a mine bomb. + *

+ * @param event + */ + @EventHandler( priority = EventPriority.LOW ) public void onInteract( PlayerInteractEvent event ) { // if ( !event.getPlayer().hasPermission("prison.minebombs.use") ) { // return; @@ -104,27 +116,31 @@ public void onInteract( PlayerInteractEvent event ) { //Output.get().logInfo( "### PrisonBombListener: PlayerInteractEvent 01 " ); + ItemStack iStack = event.getItem(); - if ( (event.getAction().equals(Action.RIGHT_CLICK_BLOCK) || + if ( iStack != null && (event.getAction().equals(Action.RIGHT_CLICK_BLOCK) || event.getAction().equals(Action.RIGHT_CLICK_AIR)) && event.getItem() != null && event.getItem().getType() != Material.AIR ) { // If the player is holding a mine bomb, then get the bomb and decrease the // ItemStack in the player's hand by 1: - ItemStack iStack = event.getItem(); String bombName = checkMineBombItemStack( iStack ); if ( bombName != null ) { + MineBombData mineBomb = MineBombs.getInstance().findBombByName(bombName); + Player player = event.getPlayer(); + //String ownerUUID = PrisonNBTUtil.getNBTString( iStack, MineBombs.MINE_BOMBS_NBT_OWNER_UUID ); + Block targetBlock = event.getClickedBlock(); EquipmentSlot hand = SpigotCompatibility.getInstance().getHand(event); - boolean canceled = processBombTriggerEvent( player, bombName, + boolean canceled = processBombTriggerEvent( player, mineBomb, targetBlock, hand ); if ( canceled ) { @@ -143,7 +159,8 @@ private String checkMineBombItemStack( ItemStack iStack ) { // NOTE: Because we're just checking, do not auto update the itemstack. // NBTItem nbtItem = new NBTItem( event.getItem() ); - String bombName = PrisonNBTUtil.getNBTString( iStack, MineBombs.MINE_BOMBS_NBT_BOMB_KEY ); + String bombName = PrisonNBTUtil.getNBTString( iStack, MineBombs.MINE_BOMBS_NBT_KEY ); +// String ownerUUID = PrisonNBTUtil.getNBTString( iStack, MineBombs.MINE_BOMBS_NBT_OWNER_UUID ); if ( bombName != null && bombName.trim().length() == 0 ) { bombName = null; @@ -165,14 +182,14 @@ else if ( bombName != null ){ } private boolean processBombTriggerEvent( SpigotPlayer sPlayer, - String bombName, SpigotBlock sBlock) { + MineBombData mineBomb, SpigotBlock sBlock) { EquipmentSlot hand = null; - return processBombTriggerEvent( sPlayer, bombName, sBlock, hand ); + return processBombTriggerEvent( sPlayer, mineBomb, sBlock, hand ); } private boolean processBombTriggerEvent( Player player, - String bombName, Block targetBlock, + MineBombData mineBomb, Block targetBlock, EquipmentSlot hand ) { SpigotPlayer sPlayer = new SpigotPlayer( player ); @@ -194,11 +211,12 @@ private boolean processBombTriggerEvent( Player player, sBlock = SpigotBlock.getSpigotBlock( targetBlock ); } - return processBombTriggerEvent( sPlayer, bombName, sBlock, hand ); + return processBombTriggerEvent( sPlayer, mineBomb, sBlock, hand ); } private boolean processBombTriggerEvent( SpigotPlayer sPlayer, - String bombName, SpigotBlock sBlock, EquipmentSlot hand ) { + MineBombData mineBomb, + SpigotBlock sBlock, EquipmentSlot hand ) { boolean canceled = false; @@ -221,16 +239,16 @@ private boolean processBombTriggerEvent( SpigotPlayer sPlayer, // Output.get().logInfo( sItemStack.getNBT().toString() ); // } - MineBombData bomb = getPrisonUtilsMineBombs().getBombItem( bombName ); +// MineBombData bomb = getPrisonUtilsMineBombs().getBombItem( bombName ); +// if ( bomb == null ) { +// if ( Output.get().isDebug() ) { +// Output.get().logInfo( "MineBombs: The bomb named '%s' cannot be mapped to a mine bomb.", +// bombName ); +// } +// return canceled; +// } - if ( bomb == null ) { - if ( Output.get().isDebug() ) { - Output.get().logInfo( "MineBombs: The bomb named '%s' cannot be mapped to a mine bomb.", - bombName ); - } - return canceled; - } // SpigotBlock sBlock = null; // @@ -275,8 +293,8 @@ else if ( !mine.hasMiningAccess( sPlayer ) ) { return canceled; } - HashSet allowedMines = new HashSet<>( bomb.getAllowedMines() ); - HashSet preventedMines = new HashSet<>( bomb.getPreventedMines() ); + HashSet allowedMines = new HashSet<>( mineBomb.getAllowedMines() ); + HashSet preventedMines = new HashSet<>( mineBomb.getPreventedMines() ); List globalPreventedMines = (List) Prison.get().getPlatform() .getConfigStringArray("prison-mines.mine-bombs.prevent-usage-in-mines"); preventedMines.addAll( globalPreventedMines ); @@ -299,7 +317,7 @@ else if ( !mine.hasMiningAccess( sPlayer ) ) { // EquipmentSlot hand = event.getHand(); // Output.get().logInfo( "### PrisonBombListener: PlayerInteractEvent 02 " ); - if ( getPrisonUtilsMineBombs().setBombInHand( sPlayer, bomb, sBlock, hand ) ) { + if ( getPrisonUtilsMineBombs().setBombInHand( sPlayer, mineBomb, sBlock, hand ) ) { // The item was a bomb and it was activated. // Cancel the event so the item will not be placed or processed farther. 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 1e3a2e2a1..bd14c3a51 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 @@ -704,24 +704,24 @@ public void utilsMineBombsGive( CommandSender sender, MineBombs mBombs = MineBombs.getInstance(); - MineBombData bomb = null; + MineBombData bomb = mBombs.findBombByName(bombName); - // Remove color codes from bomb's name for matching: - bombName = Text.stripColor( bombName ); - - Set keys = mBombs.getConfigData().getBombs().keySet(); - for ( String key : keys ) { - MineBombData mbd = mBombs.getConfigData().getBombs().get( key ); - String cleanedBombName = Text.stripColor( mbd.getName() ); - if ( cleanedBombName.equalsIgnoreCase( bombName ) ) { - bomb = mbd; - break; - } - } +// // Remove color codes from bomb's name for matching: +// bombName = Text.stripColor( bombName ); +// +// Set keys = mBombs.getConfigData().getBombs().keySet(); +// for ( String key : keys ) { +// MineBombData mbd = mBombs.getConfigData().getBombs().get( key ); +// String cleanedBombName = Text.stripColor( mbd.getName() ); +// if ( cleanedBombName.equalsIgnoreCase( bombName ) ) { +// bomb = mbd; +// break; +// } +// } if ( bomb != null ) { - ItemStack bombs = getItemStackBomb( bomb ); + ItemStack bombs = getItemStackBomb( bomb, player ); if ( bombs != null ) { @@ -837,7 +837,7 @@ public void utilsMineBombsGive( CommandSender sender, } - public static ItemStack getItemStackBomb( MineBombData bombData ) { + public ItemStack getItemStackBomb( MineBombData bombData, SpigotPlayer player ) { ItemStack sItemStack = null; SpigotItemStack bombs = null; // NBTItem nbtItem = null; @@ -891,7 +891,10 @@ public static ItemStack getItemStackBomb( MineBombData bombData ) { if ( sItemStack != null ) { // Set the NBT String key-value pair: - PrisonNBTUtil.setNBTString(sItemStack, MineBombs.MINE_BOMBS_NBT_BOMB_KEY, bombData.getName() ); + PrisonNBTUtil.setNBTString(sItemStack, MineBombs.MINE_BOMBS_NBT_KEY, bombData.getName() ); + PrisonNBTUtil.setNBTString(sItemStack, MineBombs.MINE_BOMBS_NBT_OWNER_UUID, player.getUUID().toString() ); + + // nbtItem = new NBTItem( sItemStack, true ); // nbtItem.setString( MineBombs.MINE_BOMBS_NBT_BOMB_KEY, bombData.getName() ); @@ -942,9 +945,9 @@ public MineBombData getBombItem( Player player ) { SpigotItemStack itemInHand = SpigotCompatibility.getInstance().getPrisonItemInMainHand( player ); - if ( itemInHand != null && itemInHand.hasNBTKey( MineBombs.MINE_BOMBS_NBT_BOMB_KEY ) ) { + if ( itemInHand != null && itemInHand.hasNBTKey( MineBombs.MINE_BOMBS_NBT_KEY ) ) { - String bombName = itemInHand.getNBTString( MineBombs.MINE_BOMBS_NBT_BOMB_KEY ); + String bombName = itemInHand.getNBTString( MineBombs.MINE_BOMBS_NBT_KEY ); bomb = getBombItem( bombName ); } @@ -1035,7 +1038,8 @@ else if ( bomb != null ) { // Set cooldown: addPlayerCooldown( playerUUID, bomb.getCooldownTicks() ); - SpigotItemStack bombs = new SpigotItemStack( PrisonUtilsMineBombs.getItemStackBomb( bomb )); + SpigotItemStack bombs = new SpigotItemStack( + getItemStackBomb( bomb, sPlayer )); if ( bombs != null ) { diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTasks.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTasks.java index cc7261cf6..8a0fc39e2 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTasks.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTasks.java @@ -193,6 +193,7 @@ public void run() { new BukkitRunnable() { + @SuppressWarnings("deprecation") @Override public void run() { From ce933104d79e1bb71233cda324b03debe1135424 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 6 Jul 2024 21:20:39 -0400 Subject: [PATCH 065/323] Mine bombs: Fix issue with the printing of the error message with the included json data since it contains non-encoded % signs. Setup regex comments on them by using: `\Q` and `\E`. --- docs/changelog_v3.3.x.md | 3 +++ .../spigot/utils/PrisonUtilsMineBombsTasks.java | 12 ++++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 5386ad9b9..904a613a8 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.18b 2024-07-06 +* **Mine bombs: Fix issue with the printing of the error message with the included json data since it contains non-encoded % signs. Setup regex comments on them by using: `\Q` and `\E`.*** + + * **Mine bombs: More work on getting the new mine bombs functional and working better. Still not perfect and fully working yet, but getting there.** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTasks.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTasks.java index 8a0fc39e2..fb6c2936d 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTasks.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTasks.java @@ -177,9 +177,11 @@ public void run() { NullPointerException e ) { Output.get().logWarn( String.format( - "Invalid Sound Effect value in bomb %s: %s Error: [%s]", + "Invalid Sound Effect value in bomb %s: Error: [%s] [\\Q%s\\E] ", bomb.getName(), - effect.toString(), e.getMessage()) ); + e.getMessage(), + effect.toString()) + ); } } }.runTaskLater( SpigotPrison.getInstance(), effect.getOffsetTicks() ); @@ -220,9 +222,11 @@ public void run() { NullPointerException e ) { Output.get().logWarn( String.format( - "Invalid Visual Effect value in bomb %s: %s Error: [%s]", + "Invalid Visual Effect value in bomb %s: Error: [%s] [\\Q%s\\E] ", bomb.getName(), - effect.toString(), e.getMessage()) ); + e.getMessage(), + effect.toString()) + ); } } From ff232d943687af952bf9c90ab7f8f26b1d67378b Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 6 Jul 2024 21:22:31 -0400 Subject: [PATCH 066/323] Mine bomb findArmorStands: More work to provide more features and to work around issues with NBT data not working correctly with entities. --- docs/changelog_v3.3.x.md | 4 + .../spigot/utils/PrisonUtilsMineBombs.java | 98 +++++++++++++++++-- 2 files changed, 94 insertions(+), 8 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 904a613a8..7072aec65 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.18b 2024-07-06 +* **Mine bomb findArmorStands: More work to provide more features and to work around issues with NBT data not working correctly with entities.** + + + * **Mine bombs: Fix issue with the printing of the error message with the included json data since it contains non-encoded % signs. Setup regex comments on them by using: `\Q` and `\E`.*** 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 bd14c3a51..022f1c804 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 @@ -6,6 +6,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.UUID; import org.bukkit.Bukkit; import org.bukkit.Effect; @@ -45,6 +46,7 @@ import tech.mcprison.prison.spigot.compat.SpigotCompatibility; import tech.mcprison.prison.spigot.game.SpigotPlayer; import tech.mcprison.prison.spigot.game.SpigotWorld; +import tech.mcprison.prison.spigot.game.entity.SpigotArmorStand; import tech.mcprison.prison.spigot.game.entity.SpigotEntity; import tech.mcprison.prison.spigot.game.entity.SpigotEntityType; import tech.mcprison.prison.spigot.inventory.SpigotPlayerInventory; @@ -128,7 +130,7 @@ public void utilsFindMineBombsArmorStands( CommandSender sender, + "removeAll' will remove all armor stands " + "within the general cubic-radius. And 'removeId' will remove " + "only one armor stand that matches the supplied ID. " - + " [list, show , removeAll, removeId , *any*]") String options + + " [list, show , removeAll, removeId , any]") String options ) { if ( !isEnableMineBombs() ) { @@ -153,9 +155,9 @@ public void utilsFindMineBombsArmorStands( CommandSender sender, options = options.toLowerCase().trim(); - if ( options.contains( "*any*" ) ) { + if ( options.contains( "any" ) ) { any = true; - options = options.replace( "*any*", "" ).trim(); + options = options.replace( "any", "" ).trim(); } if ( options.contains( "list" ) ) { list = true; @@ -191,19 +193,30 @@ public void utilsFindMineBombsArmorStands( CommandSender sender, DecimalFormat iFmt = Prison.getDecimalFormatStaticInt(); DecimalFormat dFmt = Prison.getDecimalFormatStatic( "#,##0.0"); + int count = 0; for (Entity entity : entities) { SpigotEntity sEntity = (SpigotEntity) entity; + SpigotArmorStand sArmorStand = new SpigotArmorStand( entity ); + + String bombName = getBombName( sEntity, sArmorStand ); + boolean hasId = false; - String bombName = sEntity.getNbtString( MineBombs.MINE_BOMBS_NBT_KEY ); +// String bombName = sEntity.getNbtString( MineBombs.MINE_BOMBS_NBT_KEY ); if ( bombName != null && bombName.trim().length() > 0 ) { hasId = true; } - if ( any && !hasId ) { + if ( !any && !hasId ) { // Not a mine bomb armor stand so continue and bypass processing: continue; } + + + tech.mcprison.prison.internal.Player owner = getOwner(sEntity, sArmorStand); + + tech.mcprison.prison.internal.Player thrower = getThrower(sEntity, sArmorStand); + Location l = entity.getLocation(); @@ -241,21 +254,35 @@ else if ( removeAll || String msg = String.format( "&3ArmorStand: distance &7%4s &3id: &7%s " - + "&3x:%4s y:%4s z: %4s age: %s %s %s bombName: %s", + + "&3x:%4s y:%4s z: %4s " + + "&3age: &7%5s " // Age + + "&3%-4s " // Age unit + + "&3%s " // sfx + + "&3bombName: &c%s " + + "&3owner: &a%s " + + "&3usedBy: &a%s ", iFmt.format( bounds.getDistance3d() ), id, iFmt.format( l.getBlockX() ), iFmt.format( l.getBlockY() ), iFmt.format( l.getBlockZ() ), - dFmt.format( times ), + dFmt.format( times ), // age sfx, status, - hasId ? bombName : "none" + bombName != null && bombName.trim().length() > 0 ? + bombName : "none", + owner != null ? owner.getName() : "&dunknown", + thrower != null ? thrower.getName() : "&dunknown" ); sender.sendMessage( msg ); + + count++; } + if ( count == 0 ) { + sender.sendMessage( "&3-= No ArmmorStands were located with the selected filters =-"); + } // Location EntityArea = new Location(Bukkit.getWorld("world"),125,71,105); // World world = Bukkit.getServer().getWorld("world"); @@ -275,6 +302,61 @@ else if ( removeAll || } + /** + *

This tries to get the bomb name from the armor stand, if it cannot get it + * directly from the armor stand, then it will try to get it from the + * item that the armor stand is holding. + *

+ * + * @param sEntity + * @param sArmorStand + * @return + */ + private String getBombName(SpigotEntity sEntity, SpigotArmorStand sArmorStand) { + String key = MineBombs.MINE_BOMBS_NBT_KEY; + return getNBTString( sEntity, sArmorStand, key ); + } + private tech.mcprison.prison.internal.Player getOwner(SpigotEntity sEntity, SpigotArmorStand sArmorStand) { + tech.mcprison.prison.internal.Player results = null; + String key = MineBombs.MINE_BOMBS_NBT_OWNER_UUID; + String uuid = getNBTString( sEntity, sArmorStand, key ); + if ( uuid != null && uuid.trim().length() > 0 ) { + results = Prison.get().getPlatform().getPlayer( UUID.fromString(uuid)).orElse(null); + } + return results; + } + private tech.mcprison.prison.internal.Player getThrower(SpigotEntity sEntity, SpigotArmorStand sArmorStand) { + tech.mcprison.prison.internal.Player results = null; + String key = MineBombs.MINE_BOMBS_NBT_THROWER_UUID; + String uuid = getNBTString( sEntity, sArmorStand, key ); + if ( uuid != null && uuid.trim().length() > 0 ) { + results = Prison.get().getPlatform().getPlayer( UUID.fromString(uuid)).orElse(null); + } + return results; + } + + private String getNBTString(SpigotEntity sEntity, SpigotArmorStand sArmorStand, String key) { + String bombName = null; + + bombName = sEntity.getNbtString( key ); + if ( bombName == null || bombName.trim().length() == 0 ) { + + SpigotItemStack iStack = (SpigotItemStack) sArmorStand.getItemInHand(); + + if ( iStack != null && !iStack.isAir() ) { + + bombName = PrisonNBTUtil.getNBTString( iStack.getBukkitStack(), key ); + + if ( bombName == null || bombName.trim().length() == 0 ) { + + bombName = PrisonNBTUtil.getNBTString( iStack.getBukkitStack(), key ); + } + } + } + + return bombName; + } + @Command(identifier = "prison utils bombs", description = "Activates a mine bomb for a given player at a specific location. " + "The attributes of the bomb can be controlled with this command, such " + From 1acf65ee8466f151905b35397a3a3ea5205b98fb Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 6 Jul 2024 21:26:51 -0400 Subject: [PATCH 067/323] Mine bombs: throwing. Setup the first pass with throwing mine bombs. This is not fully functioning yet, but it's getting closer. --- docs/changelog_v3.3.x.md | 5 + .../spigot/utils/PrisonBombListener.java | 169 ++++++++++++++++++ 2 files changed, 174 insertions(+) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 7072aec65..86c19c3e8 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.18b 2024-07-06 +* **Mine bombs: throwing. Setup the first pass with throwing mine bombs.** +This is not fully functioning yet, but it's getting closer. + + + * **Mine bomb findArmorStands: More work to provide more features and to work around issues with NBT data not working correctly with entities.** 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 3892cf41d..259a99002 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 @@ -101,6 +101,175 @@ public void onInteract( BlockPlaceEvent event ) { } } + + /** + *

Thowing minebombs. + *

+ * + * https://www.spigotmc.org/threads/tutorial-how-to-throw-items-like-knives-1-18-2.561482/ + * + * @param event + */ + @EventHandler( priority = EventPriority.LOW ) + public void throwMineBomb( PlayerInteractEvent event ) { + + ItemStack iStack = event.getItem(); + Action action = event.getAction(); // This is how we tell if it's a right-click + + + if ( iStack != null && action != null && + iStack.getType() != Material.AIR && + action == Action.RIGHT_CLICK_AIR ) { + + + String bombName = checkMineBombItemStack( iStack ); + + if ( bombName != null ) { + + MineBombData mineBomb = MineBombs.getInstance().findBombByName(bombName); + + Player player = event.getPlayer(); + + PrisonNBTUtil.setNBTString(iStack, + MineBombs.MINE_BOMBS_NBT_KEY, + bombName ); + PrisonNBTUtil.setNBTString(iStack, + MineBombs.MINE_BOMBS_NBT_THROWER_UUID, + player.getUniqueId().toString() ); + + SpigotLocation loc = new SpigotLocation( + player.getEyeLocation().add( player.getLocation().getDirection() )); + +// XMaterial xMat = XMaterial.matchXMaterial(iStack); + + + ArmorStand armorStand = player.getWorld().spawn( + loc.getBukkitLocation(), + ArmorStand.class); + + armorStand.setVisible( false ); + + SpigotArmorStand sArmorStand = new SpigotArmorStand(armorStand); + sArmorStand.setNbtString( MineBombs.MINE_BOMBS_NBT_KEY, bombName ); + sArmorStand.setNbtString( MineBombs.MINE_BOMBS_NBT_THROWER_UUID, + player.getUniqueId().toString() ); + + + Vector velocity = player.getLocation().getDirection().multiply( + mineBomb.getThrowVelocity() ); + + armorStand.setVelocity( velocity ); + + armorStand.setRemoveWhenFarAway(false); + armorStand.setItemInHand( iStack ); + + + // Remove the unused armorStand in 120 seconds: + SpigotPrison.getInstance().getScheduler().runTaskLater( new Runnable() { + public void run() { + armorStand.remove(); + } + }, 120 * 20); + + + +// player.launchProjectile( armorStand, velocity ); + +// ThrowableProjectile tProj = new Throw + + +// ProjectileSource pSrc = new Projec +// Projectile proj ; +// proj.set + + +// Snowball snowball = player.getWorld().spawn(loc.getBukkitLocation(), Snowball.class); +// snowball.setPassenger( armorStand ); +// Snowball snowball = player.getWorld().spawn(loc.getBukkitLocation(), Snowball.class); + + // the '.setItem()' was introduced with Spigot v1.14.x + //snowball.setItem(iStack); // uses the exact item clicked + +// snowball.setVelocity(player.getLocation().getDirection().multiply(3)); + + //iStack.setAmount(iStack.getAmount()-1); + + + } + } + } + + @EventHandler + public void onMineBombHit( ProjectileHitEvent e ) { + + + // e.getEntity() is the projectile which should be an NBT tagged ArmorStand: + if ( e.getEntityType() == EntityType.ARMOR_STAND && + e.getEntity() instanceof ArmorStand ) { + + SpigotArmorStand armorStand = new SpigotArmorStand( (ArmorStand) e.getEntity() ); + + String bombName = armorStand.getNbtString( MineBombs.MINE_BOMBS_NBT_KEY ); + if ( bombName != null && bombName.trim().length() > 0 ) { + + MineBombData mineBomb = MineBombs.getInstance().findBombByName(bombName); + + String throwerUUID = armorStand.getNbtString( MineBombs.MINE_BOMBS_NBT_THROWER_UUID ); + + SpigotPlayer player = (SpigotPlayer) + Prison.get().getPlatform().getPlayer( throwerUUID ).orElse(null); + + SpigotBlock targetBlock = SpigotBlock.getSpigotBlock( e.getHitBlock() ); + if ( targetBlock == null ) { + Entity entity = e.getHitEntity(); + Location location = new SpigotLocation( entity.getLocation() ); + for ( double y = 0d; y <= 4d; y++ ) { + SpigotLocation loc = new SpigotLocation( location.getWorld(), + location.getX(), location.getY() - y, location.getZ(), + location.getYaw(), location.getPitch() ); + + if ( !loc.getBlockAt().isEmpty() ) { + targetBlock = (SpigotBlock) loc.getBlockAt(); + + } + + } + } + + if ( targetBlock != null ) { + // Process mine bomb: + + processBombTriggerEvent( player, mineBomb, targetBlock ); + +// e.getEntity().getShooter().; +// +// boolean canceled = processBombTriggerEvent( event, player, bombName, +// targetBlock, hand ); + + } + + } + + + } + +// if(!(e.getHitEntity() instanceof LivingEntity)) { +// return; +// } +// +// LivingEntity ent = (LivingEntity)e.getHitEntity(); +// Projectile proj = e.getEntity(); +// + +// +// if(proj instanceof Snowball){ // All code for throwing knife will be in here +// Snowball snowball = (Snowball)proj; // cast projectile to snowball object +// ItemStack item = snowball.getItem(); // This beautiful method returns the itemstack that was put into the snowball +// if(item.getType().equals(Material.IRON_SWORD)) +// ent.damage(6); // 3 hearts of damage +// } + } + /** From 8d54464c8b0d8e496bc724181ab8c78f558c7de3 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 7 Jul 2024 00:00:13 -0400 Subject: [PATCH 068/323] Ranks: Fixed some issues with the newer formatting of the player files. Had an issue with using a rank name for a ladder name, which resulted in player's ranks from getting reset since the player had zero ranks due to incorrect mappings to ladders. --- docs/changelog_v3.3.x.md | 4 ++++ .../prison/ranks/data/RankPlayerFactory.java | 8 ++++++-- .../ranks/data/RankPlayerFactoryDataRank.java | 13 +++++++++++++ .../prison/ranks/managers/PlayerManager.java | 1 - 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 86c19c3e8..7d78a36b7 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.18b 2024-07-06 +* **Ranks: Fixed some issues with the newer formatting of the player files.** +Had an issue with using a rank name for a ladder name, which resulted in player's ranks from getting reset since the player had zero ranks due to incorrect mappings to ladders. + + * **Mine bombs: throwing. Setup the first pass with throwing mine bombs.** This is not fully functioning yet, but it's getting closer. diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactory.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactory.java index e38268999..61e8a18e4 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactory.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactory.java @@ -67,7 +67,7 @@ public RankPlayer createRankPlayer(Document document) { String json = rankObj.toString(); RankPlayerFactoryDataRank rData = jfIO.fromString( json, RankPlayerFactoryDataRank.class ); if ( rData != null ) { - rankPlayer.getRanksRefs().put( key, rData.getRankId() ); + rankPlayer.getRanksRefs().put( rData.getLadderName(), rData.getRankId() ); } } @@ -202,7 +202,11 @@ public static Document toDocument( RankPlayer rankPlayer ) { RankPlayerFactoryDataRank rData = new RankPlayerFactoryDataRank( rank.getRank().getName(), ladder.getName(), rank.getRank().getId() ); // String json = jfIO.toString( rData ); - playerRanks.put( rData.getRankName(), rData.getJsonObject() ); + + playerRanks.put( rData.getLadderName(), rData.getJsonObject() ); + + // The key must be ladder name: +// playerRanks.put( rData.getRankName(), rData.getJsonObject() ); } ret.put("ranks", playerRanks ); diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactoryDataRank.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactoryDataRank.java index 464461171..b3c6e1b4f 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactoryDataRank.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactoryDataRank.java @@ -30,6 +30,19 @@ public TreeMap getJsonObject(){ return results; } + public String toString() { + StringBuilder sb = new StringBuilder(); + + sb.append("Rank: ") + .append(getRankName()) + .append(" ") + .append(getRankId()) + .append(" Ladder: ") + .append(getLadderName()); + + return sb.toString(); + } + public String getRankName() { return rankName; } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java index 0d2a00002..0850a2589 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java @@ -479,7 +479,6 @@ public void onPlayerJoin(PlayerJoinEvent event) { // Player is auto added if they do not exist when calling getPlayer so don't try to // add them a second time. RankPlayer rPlayer = player.getRankPlayer(); -// RankPlayer rPlayer = getPlayer(player.getUUID(), player.getName()); rPlayer.doNothing(); } From 2fafd44f00580f13359e70802fde6c1fa7534793 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 7 Jul 2024 19:33:56 -0400 Subject: [PATCH 069/323] Mine bomb defaults: Added a couple of new sample mine bombs to illustrate the new animation sequences. Changed the text on the bombs' tags and lore to include a `%r` at the end; a reset character. This helps to prevent bleed over when dumping the raw values to the console and logs. --- docs/changelog_v3.3.x.md | 6 +- .../bombs/MineBombDefaultConfigSettings.java | 109 ++++++++++++------ 2 files changed, 81 insertions(+), 34 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 7d78a36b7..5afc6a0da 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.18b 2024-07-06 +# 3.3.0-alpha.18b 2024-07-07 + + +* **Mine bomb defaults: Added a couple of new sample mine bombs to illustrate the new animation sequences.** +Changed the text on the bombs' tags and lore to include a `%r` at the end; a reset character. This helps to prevent bleed over when dumping the raw values to the console and logs. * **Ranks: Fixed some issues with the newer formatting of the player files.** 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 a1172d7b0..512ce08c1 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 @@ -51,18 +51,19 @@ public void setupDefaultMineBombData(MineBombs mineBombs) { MineBombData mbd = new MineBombData( - "SmallBomb", "brewing_stand", ExplosionShape.sphere.name(), 2, "&dSmall &6Mine &eBomb &3(lore line 1)" ); + "SmallBomb", "brewing_stand", ExplosionShape.sphere.name(), 2, + "&dSmall &6Mine &eBomb &3(lore line 1)&r" ); - mbd.setNameTag( "&6&kABC&r&c-= &7{name}&c =-&6&kCBA" ); + mbd.setNameTag( "&6&kABC&r&c-= &7{name}&c =-&6&kCBA&r" ); mbd.setItemName( MineBombData.MINE_BOMB_DEFAULT_ITEM_NAME ); mbd.setToolInHandName( "DIAMOND_PICKAXE" ); mbd.setToolInHandFortuneLevel( 0 ); - mbd.setDescription("A small mine bomb made with some chemicals and a brewing stand."); + mbd.setDescription("A small mine bomb made with some chemicals and a brewing stand.&r"); - mbd.getLore().add( "&4Lore line 2" ); - mbd.getLore().add( "&aLore line &73" ); + mbd.getLore().add( "&4Lore line 2&r" ); + mbd.getLore().add( "&aLore line &73&r" ); mbd.addSoundEffects( mbeSound01.clone() ); mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 30 ) ); @@ -85,11 +86,11 @@ public void setupDefaultMineBombData(MineBombs mineBombs) { MineBombData mbd = new MineBombData( - "MediumBomb", "firework_rocket", ExplosionShape.sphere.name(), 5, "Medium Mine Bomb" ); - mbd.setDescription("A medium mine bomb made from leftover fireworks, " + - "but supercharged with a strange green glowing liquid."); + "MediumBomb", "firework_rocket", ExplosionShape.sphere.name(), 5, "Medium Mine Bomb&r" ); + mbd.setDescription("A medium mine bomb made from leftover fireworks, &r" + + "but supercharged with a strange green glowing liquid.&r"); - mbd.setNameTag( "&6&k1 23 456&r&a-=- &7{name}&a -=-&6&k654 32 1" ); + mbd.setNameTag( "&6&k1 23 456&r&a-=- &7{name}&a -=-&6&k654 32 1&r" ); mbd.setItemName( MineBombData.MINE_BOMB_DEFAULT_ITEM_NAME ); mbd.setToolInHandName( "DIAMOND_PICKAXE" ); @@ -117,12 +118,12 @@ public void setupDefaultMineBombData(MineBombs mineBombs) MineBombData mbd = new MineBombData( "LargeBomb", "tnt", ExplosionShape.sphereHollow.name(), 12, "Large Mine Bomb" ); - mbd.setNameTag( "&a-=- &7{name}&a -=--" ); + mbd.setNameTag( "&a-=- &7{name}&a -=--&r" ); mbd.setItemName( MineBombData.MINE_BOMB_DEFAULT_ITEM_NAME ); mbd.setRadiusInner( 3 ); mbd.setDescription("A large mine bomb made from TNT with some strange parts " + - "that maybe be described as alien technology."); + "that maybe be described as alien technology.&r"); mbd.setToolInHandName( "DIAMOND_PICKAXE" ); mbd.setToolInHandFortuneLevel( 3 ); @@ -146,14 +147,14 @@ public void setupDefaultMineBombData(MineBombs mineBombs) { MineBombData mbd = new MineBombData( - "OofBomb", "tnt_minecart", ExplosionShape.sphereHollow.name(), 21, "Oof Mine Bomb" ); + "OofBomb", "tnt_minecart", ExplosionShape.sphereHollow.name(), 21, "Oof Mine Bomb&r" ); mbd.setRadiusInner( 3 ); - mbd.setNameTag( "&c&k1&6&k23&e&k456&r&a-=- &4{countdown} &5-=- &7{name} &5-=- &4{countdown} &a-=-&e&k654&6&k32&c&k1" ); + mbd.setNameTag( "&c&k1&6&k23&e&k456&r&a-=- &4{countdown} &5-=- &7{name} &5-=- &4{countdown} &a-=-&e&k654&6&k32&c&k1&r" ); mbd.setItemName( MineBombData.MINE_BOMB_DEFAULT_ITEM_NAME ); mbd.setDescription("An oof-ably large mine bomb made with a minecart heaping with TNT. " + - "Unlike the large mine bomb, this one obviously is built with alien technology."); + "Unlike the large mine bomb, this one obviously is built with alien technology.&r"); mbd.setToolInHandName( "GOLDEN_PICKAXE" ); mbd.setToolInHandFortuneLevel( 13 ); @@ -205,28 +206,28 @@ public void setupDefaultMineBombData(MineBombs mineBombs) { MineBombData mbd = new MineBombData( - "WimpyBomb", "GUNPOWDER", ExplosionShape.sphere.name(), 5, - "A Wimpy Mine Bomb" ); + "WimpyBomb", "GUNPOWDER", ExplosionShape.sphere.name(), 4, + "A Wimpy Mine Bomb&r" ); // mbd.setLoreBombItemId( "&7A &2Wimpy &cBomb &9...&02A3F" ); - mbd.setNameTag( "&7A &2Wimpy &cBomb" ); + mbd.setNameTag( "&7A &2Wimpy &cBomb&r" ); mbd.setItemName( MineBombData.MINE_BOMB_DEFAULT_ITEM_NAME ); mbd.setRadiusInner( 1 ); mbd.setDescription("A whimpy bomb made with gunpowder and packs the punch of a " + - "dull wooden pickaxe. For some reason, it only has a 40% chance of removing " + - "a block."); + "dull wooden pickaxe. For some reason, it only has a 30 percent chance " + + "of removing a block.&r"); - mbd.getLore().add( "" ); - mbd.getLore().add( "A whimpy bomb made with gunpowder and packs the punch " ); - mbd.getLore().add( "of a dull wooden pickaxe. For some reason, it only " ); - mbd.getLore().add( "has a 40% chance of removing a block." ); - mbd.getLore().add( "" ); - mbd.getLore().add( "Not labeled for retail sale." ); + mbd.getLore().add( "&r" ); + mbd.getLore().add( "A whimpy bomb made with gunpowder and packs the punch &r" ); + mbd.getLore().add( "of a dull wooden pickaxe. For some reason, it only &r" ); + mbd.getLore().add( "has a 40% chance of removing a block.&r" ); + mbd.getLore().add( "&r" ); + mbd.getLore().add( "Not labeled for retail sale.&r" ); mbd.setToolInHandName( "WOODEN_PICKAXE" ); mbd.setToolInHandFortuneLevel( 0 ); - mbd.setRemovalChance( 40.0d ); + mbd.setRemovalChance( 30.0d ); mbd.getAllowedMines().add( "a" ); mbd.getAllowedMines().add( "b" ); @@ -250,14 +251,17 @@ public void setupDefaultMineBombData(MineBombs mineBombs) mbd.addVisualEffects( mbeExplode11.clone().setOffsetTicks( 05 ) ); mbd.setCooldownTicks( 3 * 20 ); // 3 seconds - mbd.setFuseDelayTicks( 2 * 20 ); // 2 seconds + mbd.setFuseDelayTicks( 15 * 20 ); // 15 seconds + mbd.setThrowVelocityLow( 0.25 ); + mbd.setThrowVelocityHigh( 1.25 ); + mbd.setGlowing( true ); mbd.setGravity( false ); mbd.setCooldownTicks( 5 ); - mbd.setAnimationPattern( AnimationPattern.infinity ); + mbd.setAnimationPattern( AnimationPattern.infinityEight ); mineBombs.getConfigData().getBombs().put( mbd.getName().toLowerCase(), mbd ); } @@ -266,11 +270,11 @@ public void setupDefaultMineBombData(MineBombs mineBombs) { MineBombData mbd = new MineBombData( "CubeBomb", "SLIME_BLOCK", ExplosionShape.cube.name(), 2, - "A Cubic Bomb" ); + "A Cubic Bomb&r" ); mbd.setDescription("The most anti-round bomb you will ever be able to find. " + - "It's totally cubic."); + "It's totally cubic.&r"); - mbd.setNameTag( "&a-=- &7{name}&a -=--" ); + mbd.setNameTag( "&a-=- &7{name}&a -=--&r" ); mbd.setItemName( MineBombData.MINE_BOMB_DEFAULT_ITEM_NAME ); mbd.setToolInHandName( "DIAMOND_PICKAXE" ); @@ -286,14 +290,53 @@ public void setupDefaultMineBombData(MineBombs mineBombs) mbd.setGlowing( true ); - mbd.setCooldownTicks( 60 ); + mbd.setCooldownTicks( 20 ); + mbd.setFuseDelayTicks( 10 * 20 ); // 10 seconds - mbd.setAnimationPattern( AnimationPattern.infinity ); + mbd.setAnimationPattern( AnimationPattern.orbital ); mineBombs.getConfigData().getBombs().put( mbd.getName().toLowerCase(), mbd ); } + + { + MineBombData mbd = new MineBombData( + "DudBomb", "SLIME_BLOCK", ExplosionShape.disk_x.name(), 1, + "This may be a bomb?&r" ); + mbd.setDescription("The most anti-round bomb you will ever be able to find. " + + "It's totally cubic.&r"); + + mbd.setNameTag( "&a-=- &7{name}&a -=--&r" ); + mbd.setItemName( MineBombData.MINE_BOMB_DEFAULT_ITEM_NAME ); + + mbd.setToolInHandName( "DIAMOND_PICKAXE" ); + mbd.setToolInHandFortuneLevel( 1 ); + mbd.setRemovalChance( 10.0d ); + + mbd.setHeight( 5 ); + + mbd.addSoundEffects( mbeSound01.clone() ); + mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 30 ) ); + mbd.addSoundEffects( mbeSound03.clone() ); + + mbd.addVisualEffects( mbeExplode04.clone() ); + mbd.addVisualEffects( mbeExplode02.clone().setOffsetTicks( 30 ) ); + + mbd.setGlowing( false ); + + mbd.setCooldownTicks( 10 ); + + mbd.setThrowVelocityLow( 0.05 ); + mbd.setThrowVelocityHigh( 0.5 ); + + + mbd.setAnimationPattern( AnimationPattern.none ); + + mineBombs.getConfigData().getBombs().put( mbd.getName().toLowerCase(), mbd ); + } + + mineBombs.saveConfigJson(); Output.get().logInfo( "Mine bombs: setup default values." ); From 60c51906dab69f22d0304e0763e37c467357bebc Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 7 Jul 2024 19:40:02 -0400 Subject: [PATCH 070/323] Mine bombs: Setup throwing of mine bombs. The mine bombs can now be thrown. If they don't land within the mine, then they are not removed from the player's inventory. The check for the mine is performed where the block lands. The throwing velocity can be controlled in the settings of each mine bomb; the higher the value, the farther the player can throw the bomb, which can easily be outside of the mine. --- docs/changelog_v3.3.x.md | 5 + .../mcprison/prison/bombs/MineBombData.java | 10 + .../tech/mcprison/prison/bombs/MineBombs.java | 5 + .../spigot/utils/PrisonBombListener.java | 434 ++++++++++++------ 4 files changed, 323 insertions(+), 131 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 5afc6a0da..ca823c1ef 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.18b 2024-07-07 +* **Mine bombs: Setup throwing of mine bombs.** +The mine bombs can now be thrown. If they don't land within the mine, then they are not removed from the player's inventory. +The check for the mine is performed where the block lands. The throwing velocity can be controlled in the settings of each mine bomb; the higher the value, the farther the player can throw the bomb, which can easily be outside of the mine. + + * **Mine bomb defaults: Added a couple of new sample mine bombs to illustrate the new animation sequences.** Changed the text on the bombs' tags and lore to include a `%r` at the end; a reset character. This helps to prevent bleed over when dumping the raw values to the console and logs. 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 ce2f3ba75..c5f693592 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 @@ -243,6 +243,9 @@ public class MineBombData private Block placedBombBlock; + private transient int taskId = -1; + + public MineBombData() { super(); @@ -770,5 +773,12 @@ public void setPlacedBombBlock( Block placedBombBlock ) { this.placedBombBlock = placedBombBlock; } + + public int getTask() { + return taskId; + } + public void setTaskId(int taskId ) { + this.taskId = taskId; + } } 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 671193b9d..73457b058 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 @@ -277,9 +277,14 @@ public void loadConfigJson() { boolean configExists = configFile.exists(); if ( !configExists ) { + + // The save file does not exist so regenerate the default bombs listing: + getConfigData().getBombs().clear(); + MineBombDefaultConfigSettings defaultConfigs = new MineBombDefaultConfigSettings(); defaultConfigs.setupDefaultMineBombData( this ); + } else { 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 259a99002..0da5410c8 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,20 +1,18 @@ package tech.mcprison.prison.spigot.utils; +import java.util.ArrayList; import java.util.HashSet; import java.util.List; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.entity.ArmorStand; -import org.bukkit.entity.Entity; -import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.block.Action; import org.bukkit.event.block.BlockPlaceEvent; -import org.bukkit.event.entity.ProjectileHitEvent; import org.bukkit.event.player.PlayerDropItemEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.inventory.ItemStack; @@ -63,8 +61,15 @@ public PrisonBombListener( PrisonUtilsMineBombs utilsMineBombs ) { this.blockBreakMines = new OnBlockBreakMines(); } + /** + *

This is the interactive event of when a player places a bomb by + * right-clicking on a block within the mine. + *

+ * + * @param event + */ @EventHandler( priority = EventPriority.LOW ) - public void onInteract( BlockPlaceEvent event ) { + public void mineBombPlacementEvent( BlockPlaceEvent event ) { ItemStack iStack = event.getItemInHand(); @@ -103,7 +108,7 @@ public void onInteract( BlockPlaceEvent event ) { } /** - *

Thowing minebombs. + *

Throwing mine bombs. *

* * https://www.spigotmc.org/threads/tutorial-how-to-throw-items-like-knives-1-18-2.561482/ @@ -111,7 +116,7 @@ public void onInteract( BlockPlaceEvent event ) { * @param event */ @EventHandler( priority = EventPriority.LOW ) - public void throwMineBomb( PlayerInteractEvent event ) { + public void mineBombThrowEvent( PlayerInteractEvent event ) { ItemStack iStack = event.getItem(); Action action = event.getAction(); // This is how we tell if it's a right-click @@ -126,9 +131,14 @@ public void throwMineBomb( PlayerInteractEvent event ) { if ( bombName != null ) { + event.setCancelled( true ); + MineBombData mineBomb = MineBombs.getInstance().findBombByName(bombName); Player player = event.getPlayer(); + final SpigotPlayer sPlayer = new SpigotPlayer( player ); + + EquipmentSlot hand = SpigotCompatibility.getInstance().getHand(event); PrisonNBTUtil.setNBTString(iStack, MineBombs.MINE_BOMBS_NBT_KEY, @@ -148,6 +158,8 @@ public void throwMineBomb( PlayerInteractEvent event ) { ArmorStand.class); armorStand.setVisible( false ); + armorStand.setItemInHand( iStack ); + SpigotArmorStand sArmorStand = new SpigotArmorStand(armorStand); sArmorStand.setNbtString( MineBombs.MINE_BOMBS_NBT_KEY, bombName ); @@ -161,17 +173,79 @@ public void throwMineBomb( PlayerInteractEvent event ) { armorStand.setVelocity( velocity ); armorStand.setRemoveWhenFarAway(false); - armorStand.setItemInHand( iStack ); // Remove the unused armorStand in 120 seconds: - SpigotPrison.getInstance().getScheduler().runTaskLater( new Runnable() { + final int taskId = SpigotPrison.getInstance().getScheduler() + .runTaskLater( + new Runnable() { public void run() { armorStand.remove(); } }, 120 * 20); + // Run the following every tick to detect when the armor stand has + // come to rest for 4 ticks, then trigger the animation. + final SpigotArmorStand aStnd = sArmorStand; + + // Save the taskId so this task can be canceled: + mineBomb.setTaskId( + SpigotPrison.getInstance().getScheduler() + .runTaskTimer( + new Runnable() { + private List locs = new ArrayList<>(); + + public void run() { + Location loc = aStnd.getLocation(); + locs.add(loc); + + if ( locs.size() > 4 ) { + locs.remove(0); + } + + if ( locs.size() == 4 ) { + if ( locs.get(0).equals(locs.get(1)) && + locs.get(1).equals(locs.get(2)) && + locs.get(2).equals(locs.get(3)) + ) { + + + // Cancel this task: + SpigotPrison.getInstance().getScheduler().cancelTask( mineBomb.getTask() ); + + // Cancel the cancellation task: + SpigotPrison.getInstance().getScheduler().cancelTask(taskId); + + + // remove armor stand: + aStnd.remove(); + + // Start mine bomb animation: + loc.setY( loc.getY() - 1); + SpigotBlock targetBlock = (SpigotBlock) loc.getBlockAt(); + + Mine mine = getMine(sPlayer, mineBomb, targetBlock ); + + if ( mine != null ) { + // It landed within a mine... subtract one from the player's inventory, + // if it's used up, then remove from the inventory: + iStack.setAmount( iStack.getAmount() - 1); + if ( iStack.getAmount() == 0 ) { + player.getInventory().removeItem( iStack ); + } + + processBombTriggerEvent( sPlayer, mine, mineBomb, targetBlock, hand ); + } + + } + } + } + + }, 2, 1)); + + + // player.launchProjectile( armorStand, velocity ); @@ -199,76 +273,140 @@ public void run() { } } - @EventHandler - public void onMineBombHit( ProjectileHitEvent e ) { - - - // e.getEntity() is the projectile which should be an NBT tagged ArmorStand: - if ( e.getEntityType() == EntityType.ARMOR_STAND && - e.getEntity() instanceof ArmorStand ) { - - SpigotArmorStand armorStand = new SpigotArmorStand( (ArmorStand) e.getEntity() ); - - String bombName = armorStand.getNbtString( MineBombs.MINE_BOMBS_NBT_KEY ); - if ( bombName != null && bombName.trim().length() > 0 ) { - - MineBombData mineBomb = MineBombs.getInstance().findBombByName(bombName); - - String throwerUUID = armorStand.getNbtString( MineBombs.MINE_BOMBS_NBT_THROWER_UUID ); - - SpigotPlayer player = (SpigotPlayer) - Prison.get().getPlatform().getPlayer( throwerUUID ).orElse(null); - - SpigotBlock targetBlock = SpigotBlock.getSpigotBlock( e.getHitBlock() ); - if ( targetBlock == null ) { - Entity entity = e.getHitEntity(); - Location location = new SpigotLocation( entity.getLocation() ); - for ( double y = 0d; y <= 4d; y++ ) { - SpigotLocation loc = new SpigotLocation( location.getWorld(), - location.getX(), location.getY() - y, location.getZ(), - location.getYaw(), location.getPitch() ); - - if ( !loc.getBlockAt().isEmpty() ) { - targetBlock = (SpigotBlock) loc.getBlockAt(); - - } - - } - } - - if ( targetBlock != null ) { - // Process mine bomb: - - processBombTriggerEvent( player, mineBomb, targetBlock ); - -// e.getEntity().getShooter().; +//// @EventHandler +// public void onMineBombThrownHitMine2Event( EntityInteractEvent e ) { +// +// // e.getEntity() is the projectile which should be an NBT tagged ArmorStand: +// if ( e.getEntityType() == EntityType.ARMOR_STAND && +// e.getEntity() instanceof ArmorStand ) { +// +// SpigotArmorStand armorStand = new SpigotArmorStand( (ArmorStand) e.getEntity() ); +// +// String bombName = armorStand.getNbtString( MineBombs.MINE_BOMBS_NBT_KEY ); +// if ( bombName != null && bombName.trim().length() > 0 ) { +// +// MineBombData mineBomb = MineBombs.getInstance().findBombByName(bombName); +// +// String throwerUUID = armorStand.getNbtString( MineBombs.MINE_BOMBS_NBT_THROWER_UUID ); +// +// SpigotPlayer player = (SpigotPlayer) +// Prison.get().getPlatform().getPlayer( throwerUUID ).orElse(null); +// +// +// +// SpigotBlock targetBlock = SpigotBlock.getSpigotBlock( e.getBlock() ); +//// if ( targetBlock == null ) { +//// Entity entity = e.getHitEntity(); +//// Location location = new SpigotLocation( entity.getLocation() ); +//// for ( double y = 0d; y <= 4d; y++ ) { +//// +//// +//// SpigotLocation loc = new SpigotLocation( location ); +////// SpigotLocation loc = new SpigotLocation( location.getWorld(), +////// location.getX(), location.getY() - y, location.getZ(), +////// location.getYaw(), location.getPitch() ); +//// +//// if ( !loc.getBlockAt().isEmpty() ) { +//// targetBlock = (SpigotBlock) loc.getBlockAt(); +//// +//// // Found a block under the entity that was hit, so stop looking: +//// break; +//// } +//// +//// } +//// } +// +// if ( targetBlock != null ) { +// // Process mine bomb: // -// boolean canceled = processBombTriggerEvent( event, player, bombName, -// targetBlock, hand ); - - } - - } - - - } - -// if(!(e.getHitEntity() instanceof LivingEntity)) { -// return; -// } -// -// LivingEntity ent = (LivingEntity)e.getHitEntity(); -// Projectile proj = e.getEntity(); -// - +// processBombTriggerEvent( player, mineBomb, targetBlock ); +// +//// e.getEntity().getShooter().; +//// +//// boolean canceled = processBombTriggerEvent( event, player, bombName, +//// targetBlock, hand ); +// +// } +// +// } +// } +// } + +// @EventHandler +// public void onMineBombThrownHitMineEvent( ProjectileHitEvent e ) { +// +// +// // e.getEntity() is the projectile which should be an NBT tagged ArmorStand: +// if ( e.getEntityType() == EntityType.ARMOR_STAND && +// e.getEntity() instanceof ArmorStand ) { +// +// SpigotArmorStand armorStand = new SpigotArmorStand( (ArmorStand) e.getEntity() ); +// +// String bombName = armorStand.getNbtString( MineBombs.MINE_BOMBS_NBT_KEY ); +// if ( bombName != null && bombName.trim().length() > 0 ) { +// +// MineBombData mineBomb = MineBombs.getInstance().findBombByName(bombName); +// +// String throwerUUID = armorStand.getNbtString( MineBombs.MINE_BOMBS_NBT_THROWER_UUID ); +// +// SpigotPlayer player = (SpigotPlayer) +// Prison.get().getPlatform().getPlayer( throwerUUID ).orElse(null); // -// if(proj instanceof Snowball){ // All code for throwing knife will be in here -// Snowball snowball = (Snowball)proj; // cast projectile to snowball object -// ItemStack item = snowball.getItem(); // This beautiful method returns the itemstack that was put into the snowball -// if(item.getType().equals(Material.IRON_SWORD)) -// ent.damage(6); // 3 hearts of damage -// } - } +// SpigotBlock targetBlock = SpigotBlock.getSpigotBlock( e.getHitBlock() ); +// if ( targetBlock == null ) { +// Entity entity = e.getHitEntity(); +// Location location = new SpigotLocation( entity.getLocation() ); +// for ( double y = 0d; y <= 4d; y++ ) { +// +// +// SpigotLocation loc = new SpigotLocation( location ); +//// SpigotLocation loc = new SpigotLocation( location.getWorld(), +//// location.getX(), location.getY() - y, location.getZ(), +//// location.getYaw(), location.getPitch() ); +// +// if ( !loc.getBlockAt().isEmpty() ) { +// targetBlock = (SpigotBlock) loc.getBlockAt(); +// +// // Found a block under the entity that was hit, so stop looking: +// break; +// } +// +// } +// } +// +// if ( targetBlock != null ) { +// // Process mine bomb: +// +// processBombTriggerEvent( player, mineBomb, targetBlock ); +// +//// e.getEntity().getShooter().; +//// +//// boolean canceled = processBombTriggerEvent( event, player, bombName, +//// targetBlock, hand ); +// +// } +// +// } +// +// +// } +// +//// if(!(e.getHitEntity() instanceof LivingEntity)) { +//// return; +//// } +//// +//// LivingEntity ent = (LivingEntity)e.getHitEntity(); +//// Projectile proj = e.getEntity(); +//// +// +//// +//// if(proj instanceof Snowball){ // All code for throwing knife will be in here +//// Snowball snowball = (Snowball)proj; // cast projectile to snowball object +//// ItemStack item = snowball.getItem(); // This beautiful method returns the itemstack that was put into the snowball +//// if(item.getType().equals(Material.IRON_SWORD)) +//// ent.damage(6); // 3 hearts of damage +//// } +// } @@ -278,7 +416,7 @@ public void onMineBombHit( ProjectileHitEvent e ) { * @param event */ @EventHandler( priority = EventPriority.LOW ) - public void onInteract( PlayerInteractEvent event ) { + public void bombPlacementEvent( PlayerInteractEvent event ) { // if ( !event.getPlayer().hasPermission("prison.minebombs.use") ) { // return; // } @@ -336,27 +474,28 @@ private String checkMineBombItemStack( ItemStack iStack ) { } else if ( bombName != null ){ - if ( Output.get().isDebug() ) { - Output.get().logInfo( "PrisonBombListener.onInteract (item) " - + "bombName: &7%s&r &3:: nbt: &r%s", - bombName, - PrisonNBTUtil.nbtDebugString( iStack ) -// (nbtItem == null ? "&a-no-nbt-" : nbtItem.toString()) - ); - } +// if ( Output.get().isDebug() ) { +// Output.get().logInfo( "PrisonBombListener.onInteract (item) " +// + "bombName: &7%s&r &3:: nbt: &r\\Q%s\\E", +// bombName, +// PrisonNBTUtil.nbtDebugString( iStack ).replace("%", "_") +//// (nbtItem == null ? "&a-no-nbt-" : nbtItem.toString()) +// ); +// } } return bombName; } - private boolean processBombTriggerEvent( SpigotPlayer sPlayer, - MineBombData mineBomb, SpigotBlock sBlock) { - - EquipmentSlot hand = null; - - return processBombTriggerEvent( sPlayer, mineBomb, sBlock, hand ); - } +// private boolean processBombTriggerEvent( SpigotPlayer sPlayer, +// Mine mine, +// MineBombData mineBomb, SpigotBlock sBlock) { +// +// EquipmentSlot hand = null; +// +// return mine == null ? false : processBombTriggerEvent( sPlayer, mine, mineBomb, sBlock, hand ); +// } private boolean processBombTriggerEvent( Player player, MineBombData mineBomb, Block targetBlock, EquipmentSlot hand ) { @@ -380,10 +519,13 @@ private boolean processBombTriggerEvent( Player player, sBlock = SpigotBlock.getSpigotBlock( targetBlock ); } - return processBombTriggerEvent( sPlayer, mineBomb, sBlock, hand ); + Mine mine = getMine(sPlayer, mineBomb, sBlock ); + + return mine == null ? false : processBombTriggerEvent( sPlayer, mine, mineBomb, sBlock, hand ); } private boolean processBombTriggerEvent( SpigotPlayer sPlayer, + Mine mine, MineBombData mineBomb, SpigotBlock sBlock, EquipmentSlot hand ) { @@ -437,17 +579,58 @@ private boolean processBombTriggerEvent( SpigotPlayer sPlayer, // } +// Mine mine = getMine(sPlayer, mineBomb, sBlock ); + + if ( mine == null ) { + canceled = true; + } + else { + + + // getHand() is not available with bukkit 1.8.8 so use the compatibility functions: +// EquipmentSlot hand = SpigotCompatibility.getInstance().getHand(event); +// EquipmentSlot hand = event.getHand(); + +// Output.get().logInfo( "### PrisonBombListener: PlayerInteractEvent 02 " ); + if ( getPrisonUtilsMineBombs().setBombInHand( sPlayer, mineBomb, sBlock, hand ) ) { + + // The item was a bomb and it was activated. + // Cancel the event so the item will not be placed or processed farther. + +// Output.get().logInfo( "### PrisonBombListener: PlayerInteractEvent 03 Bomb detected - May not have been set. " ); + canceled = true; +// event.setCancelled( true ); + } + } + + return canceled; + } + + /** + *

This function checks to see if the mine bomb is within a mine, and if it is, + * then it checks to see if the player has access to the mine. Then finally, + * the mine bomb is checked to see if it is allowed to be used within the mine. + *

+ * + *

If the player is permitted to use the mine bomb in the mine, then the mine will + * be returned. If they are not permitted, then a null will be returned. + *

+ * + * @param sPlayer + * @param mineBomb + * @param sBlock + * @return + */ + private Mine getMine(SpigotPlayer sPlayer, MineBombData mineBomb, SpigotBlock sBlock ) { Mine mine = blockBreakMines.findMine( sPlayer, sBlock, null, null); + if ( mine == null ) { // player is not in a mine, so do not allow them to trigger a mine bomb: if ( Output.get().isDebug() ) { - Output.get().logInfo( "MineBombs: Cannot mine bombs use outside of mines." ); + Output.get().logInfo( "MineBombs: Cannot use mine bombs use outside of mines." ); } - canceled = true; -// event.setCancelled( true ); - return canceled; } else if ( !mine.hasMiningAccess( sPlayer ) ) { // Player does not have access to the mine, so don't allow them to trigger a mine bomb: @@ -457,46 +640,35 @@ else if ( !mine.hasMiningAccess( sPlayer ) ) { sPlayer.getName(), mine.getName()); } - canceled = true; -// event.setCancelled( true ); - return canceled; + mine = null; } - - HashSet allowedMines = new HashSet<>( mineBomb.getAllowedMines() ); - HashSet preventedMines = new HashSet<>( mineBomb.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() ) ) { + else { - if ( preventedMines.contains( mine.getName().toLowerCase() ) ) { + HashSet allowedMines = new HashSet<>( mineBomb.getAllowedMines() ); + HashSet preventedMines = new HashSet<>( mineBomb.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() ) ) { - // Mine bombs are not allowed to be used in this mine so cancel: - canceled = true; -// event.setCancelled( true ); - return canceled; + if ( preventedMines.contains( mine.getName().toLowerCase() ) ) { + + // Mine bombs are not allowed to be used in this mine so cancel: + + sPlayer.sendMessage( String.format( + "&3You cannot use that bomb in this mine. mine: &7%s &3bomb: &7%s&r", + mine.getTag(), + mineBomb.getNameTag() + ) ); + + mine = null; + } } } - - // getHand() is not available with bukkit 1.8.8 so use the compatibility functions: -// EquipmentSlot hand = SpigotCompatibility.getInstance().getHand(event); -// EquipmentSlot hand = event.getHand(); - -// Output.get().logInfo( "### PrisonBombListener: PlayerInteractEvent 02 " ); - if ( getPrisonUtilsMineBombs().setBombInHand( sPlayer, mineBomb, sBlock, hand ) ) { - - // The item was a bomb and it was activated. - // Cancel the event so the item will not be placed or processed farther. - -// Output.get().logInfo( "### PrisonBombListener: PlayerInteractEvent 03 Bomb detected - May not have been set. " ); - canceled = true; -// event.setCancelled( true ); - } - - return canceled; + return mine; } From b30c03958877d3e3daf5f8adbeca971208540ce1 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 7 Jul 2024 19:42:00 -0400 Subject: [PATCH 071/323] Prison NBT: removed debug code which was generating a lot of entries in the logs. --- docs/changelog_v3.3.x.md | 3 +++ .../mcprison/prison/spigot/nbt/PrisonNBTUtil.java | 12 ++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index ca823c1ef..a15e4fe74 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.18b 2024-07-07 +* **Prison NBT: removed debug code which was generating a lot of entries in the logs.** + + * **Mine bombs: Setup throwing of mine bombs.** The mine bombs can now be thrown. If they don't land within the mine, then they are not removed from the player's inventory. The check for the mine is performed where the block lands. The throwing velocity can be controlled in the settings of each mine bomb; the higher the value, the farther the player can throw the bomb, which can easily be outside of the mine. 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 99aa3ea9d..abdc67c7f 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 @@ -99,9 +99,9 @@ public static void setNBTString( ItemStack bukkitStack, String key, String value nbt.setString(key, value); }); - if ( isEnableDebugLogging() ) { - nbtDebugLog( bukkitStack, "setNBTString" ); - } +// if ( isEnableDebugLogging() ) { +// nbtDebugLog( bukkitStack, "setNBTString" ); +// } } catch (Exception e) { Output.get().logInfo( @@ -139,9 +139,9 @@ public static void setNBTBoolean( ItemStack bukkitStack, String key, boolean val nbt.setBoolean(key, value); }); - if ( isEnableDebugLogging() ) { - nbtDebugLog( bukkitStack, "setNBTBoolean" ); - } +// if ( isEnableDebugLogging() ) { +// nbtDebugLog( bukkitStack, "setNBTBoolean" ); +// } } catch (Exception e) { Output.get().logInfo( From 78fc846163b935f044eafe7e00b8d74708f67a1a Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 8 Jul 2024 00:08:15 -0400 Subject: [PATCH 072/323] Mine bombs: Update and fix some issues with the new mine bomb processing and animations. --- docs/changelog_v3.3.x.md | 3 + .../animations/BombAnimationInfinity.java | 133 +---------- .../bombs/animations/BombAnimationNone.java | 88 +------ .../bombs/animations/BombAnimations.java | 224 ++++++++++++++++-- .../mcprison/prison/spigot/SpigotUtil.java | 15 +- .../spigot/game/entity/SpigotArmorStand.java | 15 +- .../spigot/utils/PrisonBombListener.java | 88 ++++--- .../spigot/utils/PrisonUtilsMineBombs.java | 10 +- 8 files changed, 306 insertions(+), 270 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index a15e4fe74..ea67ac6aa 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.18b 2024-07-07 +* **Mine bombs: Update and fix some issues with the new mine bomb processing and animations.** + + * **Prison NBT: removed debug code which was generating a lot of entries in the logs.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationInfinity.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationInfinity.java index 2e3866979..ea40ebd4f 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationInfinity.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationInfinity.java @@ -1,153 +1,36 @@ package tech.mcprison.prison.bombs.animations; import tech.mcprison.prison.bombs.MineBombData; -import tech.mcprison.prison.bombs.MineBombs; -import tech.mcprison.prison.internal.ArmorStand; import tech.mcprison.prison.internal.EulerAngle; import tech.mcprison.prison.internal.ItemStack; import tech.mcprison.prison.internal.block.PrisonBlock; -import tech.mcprison.prison.output.Output; -import tech.mcprison.prison.util.BluesSemanticVersionComparator; -import tech.mcprison.prison.util.Location; public class BombAnimationInfinity extends BombAnimations { - - private double eulerAngleX = 1.0; - private double eulerAngleY = 0; - private double eulerAngleZ = 0; - - private double twoPI; - - private ArmorStand armorStand; - - private float entityYaw; - private float entityPitch; - - - - public BombAnimationInfinity( MineBombData bomb, PrisonBlock sBombBlock, ItemStack item, BombAnimationsTask task, float entityYaw, float entityPitch ) { - super( bomb, sBombBlock, item, task ); + super( bomb, sBombBlock, item, task, entityYaw, entityPitch ); - this.entityYaw = entityYaw; - this.entityPitch = entityPitch; - - initialize(); } - - public void initialize() { - - this.twoPI = Math.PI * 2; - - - initializeArmorStand(); - } - - private void initializeArmorStand() { - - Location location = getsBlock().getLocation(); - location.setY( location.getY() + 2.5 ); - - location.setYaw( entityYaw ); - location.setPitch( entityPitch + 90 ); - - - double startingAngle = ( 360d / entityYaw ) * twoPI; - -// eulerAngleX += startingAngle; - - EulerAngle arm = new EulerAngle( eulerAngleX + startingAngle, eulerAngleY + startingAngle, eulerAngleZ + startingAngle ); - - - armorStand = location.spawnArmorStand(); - - armorStand.setNbtString( MineBombs.MINE_BOMBS_NBT_KEY, getBomb().getName() ); - - if ( armorStand != null ) { - - armorStand.setVisible(false); - armorStand.setRemoveWhenFarAway(false); - armorStand.setItemInHand( getItem() ); - armorStand.setRightArmPose(arm); - - - if ( initializeCustomName() && getId() == 1 ) { - - //updateArmorStandCustomName(); - armorStand.setCustomName( getTagName() ); - armorStand.setCustomNameVisible(true); - } - else { - - armorStand.setCustomNameVisible(false); - } - - if ( new BluesSemanticVersionComparator().compareMCVersionTo( "1.9.0" ) >= 0 ) { - - armorStand.setGlowing( getBomb().isGlowing() ); - - // setGravity is invalid for spigot 1.8.8: - armorStand.setGravity( getBomb().isGravity() ); - } - } - - if ( Output.get().isDebug() ) { - String msg = String.format( - "### BombAnimationInfinity.initializeArmorStand : id: %s ", - Integer.toString(getId()) - - ); - Output.get().logInfo( msg ); - } - } - - - - @Override - public void step() + public void stepAnimation() { - + double speed = 0.35; - eulerAngleX += speed; - eulerAngleY += speed / 3; - eulerAngleZ += speed / 5; - - - EulerAngle arm = new EulerAngle( eulerAngleX, eulerAngleY, eulerAngleZ ); - - armorStand.setRightArmPose(arm); + setEulerAngleX( getEulerAngleX() + speed ); + setEulerAngleY( getEulerAngleY() + speed / 3); + setEulerAngleZ( getEulerAngleZ() + speed / 5 ); - if ( eulerAngleX > twoPI ) { - eulerAngleX -= twoPI; - } - if ( eulerAngleY > twoPI ) { - eulerAngleY -= twoPI; - } - if ( eulerAngleZ > twoPI ) { - eulerAngleZ -= twoPI; - } - - - // Track the time that this has lived: - if ( --terminateOnZeroTicks == 0 || !armorStand.isValid() ) { - - armorStand.remove(); - - cancel(); - } - - updateCustomName(); + EulerAngle arm = new EulerAngle( getEulerAngleX(), getEulerAngleY(), getEulerAngleZ() ); + getArmorStand().setRightArmPose(arm); } } diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationNone.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationNone.java index f26e13251..f8adbe0a2 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationNone.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationNone.java @@ -1,109 +1,25 @@ package tech.mcprison.prison.bombs.animations; import tech.mcprison.prison.bombs.MineBombData; -import tech.mcprison.prison.bombs.MineBombs; -import tech.mcprison.prison.internal.ArmorStand; import tech.mcprison.prison.internal.ItemStack; import tech.mcprison.prison.internal.block.PrisonBlock; -import tech.mcprison.prison.output.Output; -import tech.mcprison.prison.util.BluesSemanticVersionComparator; -import tech.mcprison.prison.util.Location; public class BombAnimationNone extends BombAnimations { - private ArmorStand armorStand; - - private float entityYaw; - private float entityPitch; - - public BombAnimationNone( MineBombData bomb, PrisonBlock sBombBlock, ItemStack item, BombAnimationsTask task, float entityYaw, float entityPitch ) { - super( bomb, sBombBlock, item, task ); + super( bomb, sBombBlock, item, task, entityYaw, entityPitch ); - this.entityYaw = entityYaw; - this.entityPitch = entityPitch; - - initialize(); } - public void initialize() { - - initializeArmorStand(); - } - - private void initializeArmorStand() { - - Location location = getsBlock().getLocation(); - location.setY( location.getY() + 2.5 ); - - location.setYaw( entityYaw ); - location.setPitch( entityPitch + 90 ); - - - armorStand = location.spawnArmorStand(); - - armorStand.setNbtString( MineBombs.MINE_BOMBS_NBT_KEY, getBomb().getName() ); - - if ( armorStand != null ) { - - armorStand.setVisible(false); - armorStand.setRemoveWhenFarAway(false); - armorStand.setItemInHand( getItem() ); - //armorStand.setRightArmPose(arm); - - - if ( initializeCustomName() ) { - - //updateArmorStandCustomName(); - armorStand.setCustomName( getTagName() ); - armorStand.setCustomNameVisible(true); - } - else { - - armorStand.setCustomNameVisible(false); - } - - if ( new BluesSemanticVersionComparator().compareMCVersionTo( "1.9.0" ) >= 0 ) { - - armorStand.setGlowing( getBomb().isGlowing() ); - - // setGravity is invalid for spigot 1.8.8: - armorStand.setGravity( getBomb().isGravity() ); - } - } - - if ( Output.get().isDebug() ) { - String msg = String.format( - "### BombAnimationInfinity.initializeArmorStand : id: %s ", - Integer.toString(getId()) - - ); - Output.get().logInfo( msg ); - } - } - - - @Override - public void step() + public void stepAnimation() { - - // Track the time that this has lived: - if ( --terminateOnZeroTicks == 0 || !armorStand.isValid() ) { - - armorStand.remove(); - - cancel(); - } - - updateCustomName(); } - } diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java index 471690d64..485b26e20 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java @@ -4,8 +4,14 @@ import tech.mcprison.prison.Prison; import tech.mcprison.prison.bombs.MineBombData; +import tech.mcprison.prison.bombs.MineBombs; +import tech.mcprison.prison.internal.ArmorStand; +import tech.mcprison.prison.internal.EulerAngle; import tech.mcprison.prison.internal.ItemStack; import tech.mcprison.prison.internal.block.PrisonBlock; +import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.util.BluesSemanticVersionComparator; +import tech.mcprison.prison.util.Location; import tech.mcprison.prison.util.Text; public abstract class BombAnimations { @@ -18,20 +24,33 @@ public abstract class BombAnimations { private PrisonBlock sBlock; private ItemStack item; - + private String customName; private boolean isDyanmicTag = false; private String tagName; // long ageTicks = 0L; long terminateOnZeroTicks = 0L; + private ArmorStand armorStand; + + private double eulerAngleX = 1.0; + private double eulerAngleY = 0; + private double eulerAngleZ = 0; + + private double twoPI; + + private float entityYaw; + private float entityPitch; + private DecimalFormat dFmt; public BombAnimations( MineBombData bomb, PrisonBlock sBombBlock, ItemStack item, - BombAnimationsTask task ) { + BombAnimationsTask task, + float entityYaw, + float entityPitch ) { super(); // Used for "canceling" and detonating the task: @@ -46,22 +65,117 @@ public BombAnimations( MineBombData bomb, // this.ageTicks = 0; this.terminateOnZeroTicks = getTaskLifeSpan(); - this.isDyanmicTag = bomb.getNameTag().contains( "{countdown}" ); + this.isDyanmicTag = bomb.getNameTag() != null && + bomb.getNameTag().contains( "{countdown}" ); this.tagName = ""; - this.dFmt = Prison.get().getDecimalFormat( "0.0" ); + + this.entityYaw = entityYaw; + this.entityPitch = entityPitch; + + this.twoPI = Math.PI * 2; - // initialize(); + this.dFmt = Prison.get().getDecimalFormat( "0.0" ); + + initialize(); } protected void cancel() { task.cancel(); } - public abstract void initialize(); - + public void initialize() { + + Location location = getsBlock().getLocation(); + location.setY( location.getY() + 3 ); + + location.setYaw( entityYaw ); + location.setPitch( entityPitch + 90 ); + + + double startingAngle = ( 360d / entityYaw ) * twoPI; + + // eulerAngleX += startingAngle; + + EulerAngle arm = new EulerAngle( + eulerAngleX + startingAngle, + eulerAngleY + startingAngle, + eulerAngleZ + startingAngle ); + + + armorStand = location.spawnArmorStand(); + + if ( armorStand != null ) { + + armorStand.setVisible(false); + + armorStand.setNbtString( MineBombs.MINE_BOMBS_NBT_KEY, getBomb().getName() ); + + armorStand.setRightArmPose(arm); + armorStand.setItemInHand( getItem() ); + + armorStand.setCustomNameVisible( getId() == 0 && initializeCustomName() ); + armorStand.setRemoveWhenFarAway(false); + + if ( new BluesSemanticVersionComparator().compareMCVersionTo( "1.9.0" ) >= 0 ) { + + armorStand.setGlowing( getBomb().isGlowing() ); + + // setGravity is invalid for spigot 1.8.8: + armorStand.setGravity( getBomb().isGravity() ); + } + } + + if ( Output.get().isDebug() ) { + String msg = String.format( + "### BombAnimation.initializeArmorStand : id: %s %s ", + Integer.toString(getId()), + bomb.getAnimationPattern().name() + ); + + Output.get().logInfo( msg ); + } + } + + + public abstract void stepAnimation(); - public abstract void step(); + public void step() { + stepAnimation(); + + if ( eulerAngleX > twoPI ) { + eulerAngleX -= twoPI; + } + else if ( eulerAngleX < -twoPI ) { + eulerAngleX += twoPI; + } + if ( eulerAngleY > twoPI ) { + eulerAngleY -= twoPI; + } + else if ( eulerAngleY < -twoPI ) { + eulerAngleY += twoPI; + } + if ( eulerAngleZ > twoPI ) { + eulerAngleZ -= twoPI; + } + else if ( eulerAngleZ < -twoPI ) { + eulerAngleZ += twoPI; + } + + // Track the time that this has lived: + if ( --terminateOnZeroTicks == 0 || !armorStand.isValid() ) { + + armorStand.remove(); + + cancel(); + } + + if ( getId() == 0 ) { + + updateCustomName(); + } + + } /** @@ -93,16 +207,34 @@ protected long getTaskLifeSpan() protected boolean initializeCustomName() { boolean results = false; - if ( getBomb().getNameTag() != null && - !getBomb().getNameTag().trim().isEmpty() ) { + String tName = null; + + if ( getBomb().getNameTag() == null || + getBomb().getNameTag().trim().isEmpty() ) { + + tName = getBomb().getName(); + } + else { - String tagName = getBomb().getNameTag(); - if ( tagName.contains( "{name}" ) ) { - tagName = tagName.replace( "{name}", getBomb().getName() ); + tName = getBomb().getNameTag(); + if ( tName.contains( "{name}" ) ) { + tName = tName.replace( "{name}", getBomb().getName() ); } - setTagName( Text.translateAmpColorCodes( tagName ) ); } + + if ( tName != null ) { + + tName = Text.translateAmpColorCodes( tName ); + + setTagName( tName ); + setCustomName( tName ); + armorStand.setCustomName( tName ); + + updateCustomName(); + results = true; + } + return results; } @@ -111,9 +243,13 @@ protected void updateCustomName() if ( isDyanmicTag ) { double countdown = (terminateOnZeroTicks / 20.0d); - String tagName = this.tagName.replace( "{countdown}", dFmt.format( countdown) ); + String cName = getTagName().replace( "{countdown}", dFmt.format( countdown) ); - setTagName( tagName ); + setCustomName( cName ); + + armorStand.setCustomName( cName ); + +// setTagName( tagName ); // armorStand.setCustomName( tagName ); } } @@ -160,6 +296,13 @@ public void setDyanmicTag(boolean isDyanmicTag) { this.isDyanmicTag = isDyanmicTag; } + public String getCustomName() { + return customName; + } + public void setCustomName(String customName) { + this.customName = customName; + } + public String getTagName() { return tagName; } @@ -173,5 +316,54 @@ public long getTerminateOnZeroTicks() { public void setTerminateOnZeroTicks(long terminateOnZeroTicks) { this.terminateOnZeroTicks = terminateOnZeroTicks; } + + public ArmorStand getArmorStand() { + return armorStand; + } + public void setArmorStand(ArmorStand armorStand) { + this.armorStand = armorStand; + } + + public double getEulerAngleX() { + return eulerAngleX; + } + public void setEulerAngleX(double eulerAngleX) { + this.eulerAngleX = eulerAngleX; + } + + public double getEulerAngleY() { + return eulerAngleY; + } + public void setEulerAngleY(double eulerAngleY) { + this.eulerAngleY = eulerAngleY; + } + + public double getEulerAngleZ() { + return eulerAngleZ; + } + public void setEulerAngleZ(double eulerAngleZ) { + this.eulerAngleZ = eulerAngleZ; + } + + public double getTwoPI() { + return twoPI; + } + public void setTwoPI(double twoPI) { + this.twoPI = twoPI; + } + + public float getEntityYaw() { + return entityYaw; + } + public void setEntityYaw(float entityYaw) { + this.entityYaw = entityYaw; + } + + public float getEntityPitch() { + return entityPitch; + } + public void setEntityPitch(float entityPitch) { + this.entityPitch = entityPitch; + } } 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 6295fc029..66f567c23 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 @@ -1045,9 +1045,16 @@ public static Location bukkitLocationToPrison(org.bukkit.Location bukkitLocation } public static org.bukkit.Location prisonLocationToBukkit(Location prisonLocation) { - return new org.bukkit.Location(Bukkit.getWorld(prisonLocation.getWorld().getName()), - prisonLocation.getX(), prisonLocation.getY(), prisonLocation.getZ(), - prisonLocation.getYaw(), prisonLocation.getPitch()); + org.bukkit.Location loc = new org.bukkit.Location( + Bukkit.getWorld(prisonLocation.getWorld().getName()), + prisonLocation.getX(), prisonLocation.getY(), prisonLocation.getZ(), + prisonLocation.getYaw(), prisonLocation.getPitch() ); + + Vector v = prisonLocation.getDirection(); + org.bukkit.util.Vector vec = new org.bukkit.util.Vector( v.getX(), v.getY(), v.getZ() ); + loc.setDirection( vec ); + + return loc; } /* @@ -1055,7 +1062,7 @@ public static org.bukkit.Location prisonLocationToBukkit(Location prisonLocation */ public static SpigotItemStack bukkitItemStackToPrison( ItemStack bukkitStack) { -; SpigotItemStack results = null; + SpigotItemStack results = null; if ( bukkitStack != null ) { try { diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotArmorStand.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotArmorStand.java index cb651f52d..8c4d94196 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotArmorStand.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotArmorStand.java @@ -43,8 +43,19 @@ public boolean isVisible() { } @Override - public void setVisible(boolean visible) { - bArmorStand.setVisible(visible); + public void setVisible( boolean visible ) { + bArmorStand.setVisible( visible ); + } + + @Override + public void setCustomNameVisible( boolean visible ) { + bArmorStand.setCustomNameVisible( visible ); + } + + @Override + public void setCustomName( String customName ) { + + bArmorStand.setCustomName( customName ); } @Override 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 0da5410c8..9ee9d0a43 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 @@ -131,6 +131,8 @@ public void mineBombThrowEvent( PlayerInteractEvent event ) { if ( bombName != null ) { + // We do not know if the bomb will be in a mine, but we know + // it's a mine bomb so no other listener should handle it. event.setCancelled( true ); MineBombData mineBomb = MineBombs.getInstance().findBombByName(bombName); @@ -175,6 +177,8 @@ public void mineBombThrowEvent( PlayerInteractEvent event ) { armorStand.setRemoveWhenFarAway(false); + + // Remove the unused armorStand in 120 seconds: final int taskId = SpigotPrison.getInstance().getScheduler() .runTaskLater( @@ -411,7 +415,9 @@ public void run() { /** - *

This function will initiate the placement of a mine bomb. + *

This function will initiate the placement of a mine bomb. + * This handles the right-clicking on a block. This will not + * throw it. *

* @param event */ @@ -425,9 +431,8 @@ public void bombPlacementEvent( PlayerInteractEvent event ) { ItemStack iStack = event.getItem(); - if ( iStack != null && (event.getAction().equals(Action.RIGHT_CLICK_BLOCK) || - event.getAction().equals(Action.RIGHT_CLICK_AIR)) && - event.getItem() != null && event.getItem().getType() != Material.AIR ) { + if ( iStack != null && iStack.getType() != Material.AIR && + event.getAction().equals(Action.RIGHT_CLICK_BLOCK) ) { // If the player is holding a mine bomb, then get the bomb and decrease the // ItemStack in the player's hand by 1: @@ -531,6 +536,16 @@ private boolean processBombTriggerEvent( SpigotPlayer sPlayer, boolean canceled = false; + if ( getPrisonUtilsMineBombs().setBombInHand( sPlayer, mineBomb, sBlock, hand ) ) { + + // The item was a bomb and it was activated. + // Cancel the event so the item will not be placed or processed farther. + +// Output.get().logInfo( "### PrisonBombListener: PlayerInteractEvent 03 Bomb detected - May not have been set. " ); + canceled = true; + } + + // // Temp test stuff... remove when NBTs are working: // { @@ -581,27 +596,27 @@ private boolean processBombTriggerEvent( SpigotPlayer sPlayer, // Mine mine = getMine(sPlayer, mineBomb, sBlock ); - if ( mine == null ) { - canceled = true; - } - else { - - - // getHand() is not available with bukkit 1.8.8 so use the compatibility functions: -// EquipmentSlot hand = SpigotCompatibility.getInstance().getHand(event); -// EquipmentSlot hand = event.getHand(); - -// Output.get().logInfo( "### PrisonBombListener: PlayerInteractEvent 02 " ); - if ( getPrisonUtilsMineBombs().setBombInHand( sPlayer, mineBomb, sBlock, hand ) ) { - - // The item was a bomb and it was activated. - // Cancel the event so the item will not be placed or processed farther. - -// Output.get().logInfo( "### PrisonBombListener: PlayerInteractEvent 03 Bomb detected - May not have been set. " ); - canceled = true; -// event.setCancelled( true ); - } - } +// if ( mine == null ) { +// canceled = false; +// } +// else { +// +// +// // getHand() is not available with bukkit 1.8.8 so use the compatibility functions: +//// EquipmentSlot hand = SpigotCompatibility.getInstance().getHand(event); +//// EquipmentSlot hand = event.getHand(); +// +//// Output.get().logInfo( "### PrisonBombListener: PlayerInteractEvent 02 " ); +// if ( getPrisonUtilsMineBombs().setBombInHand( sPlayer, mineBomb, sBlock, hand ) ) { +// +// // The item was a bomb and it was activated. +// // Cancel the event so the item will not be placed or processed farther. +// +//// Output.get().logInfo( "### PrisonBombListener: PlayerInteractEvent 03 Bomb detected - May not have been set. " ); +// canceled = true; +//// event.setCancelled( true ); +// } +// } return canceled; } @@ -628,7 +643,9 @@ private Mine getMine(SpigotPlayer sPlayer, MineBombData mineBomb, SpigotBlock sB // player is not in a mine, so do not allow them to trigger a mine bomb: if ( Output.get().isDebug() ) { - Output.get().logInfo( "MineBombs: Cannot use mine bombs use outside of mines." ); + String msg = "MineBombs: Cannot use mine bombs use outside of mines."; + sPlayer.setActionBar( msg ); +// Output.get().logInfo( msg ); } } @@ -636,8 +653,11 @@ else if ( !mine.hasMiningAccess( sPlayer ) ) { // Player does not have access to the mine, so don't allow them to trigger a mine bomb: if ( Output.get().isDebug() ) { - Output.get().logInfo( "MineBombs: Player %s&r does not have access to Mine %s&r.", - sPlayer.getName(), mine.getName()); + String msg = String.format( + "MineBombs: %s&r, you do not have access to mine %s&r.", + sPlayer.getName(), mine.getName() ); + sPlayer.setActionBar( msg ); +// Output.get().logInfo( msg ); } mine = null; @@ -657,11 +677,13 @@ else if ( !mine.hasMiningAccess( sPlayer ) ) { // Mine bombs are not allowed to be used in this mine so cancel: - sPlayer.sendMessage( String.format( - "&3You cannot use that bomb in this mine. mine: &7%s &3bomb: &7%s&r", - mine.getTag(), - mineBomb.getNameTag() - ) ); + String msg = String.format( + "&3You cannot use the &7%s &3bomb in mine &7%s.&r", + mineBomb.getNameTag(), + mine.getTag() + ); + sPlayer.setActionBar( msg ); +// sPlayer.sendMessage( msg ); mine = null; } 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 022f1c804..5fd94f521 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 @@ -263,9 +263,9 @@ else if ( removeAll || + "&3usedBy: &a%s ", iFmt.format( bounds.getDistance3d() ), id, - iFmt.format( l.getBlockX() ), - iFmt.format( l.getBlockY() ), - iFmt.format( l.getBlockZ() ), + dFmt.format( l.getX() ), + dFmt.format( l.getY() ), + dFmt.format( l.getZ() ), dFmt.format( times ), // age sfx, status, @@ -986,7 +986,9 @@ public ItemStack getItemStackBomb( MineBombData bombData, SpigotPlayer player ) if ( Output.get().isDebug() ) { - Output.get().logInfo( "getItemStackBombs ntb: %s", PrisonNBTUtil.nbtDebugString(sItemStack) ); + Output.get().logInfo( "getItemStackBombs ntb: %s", + Text.translateAmpColorCodes( PrisonNBTUtil.nbtDebugString(sItemStack) ) + ); } } From 290bbdb5e439682bfe92a4aaec8b0212e87d682b Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 8 Jul 2024 03:38:13 -0400 Subject: [PATCH 073/323] Rankup messages: externalized another message related to an economy failure. --- docs/changelog_v3.3.x.md | 5 ++++- .../src/main/resources/lang/ranks/en_US.properties | 3 ++- .../src/main/resources/lang/ranks/fr_FR.properties | 3 ++- .../src/main/resources/lang/ranks/pt_PT.properties | 3 ++- .../src/main/resources/lang/ranks/zh-CN.properties | 3 ++- .../src/main/resources/lang/ranks/zh_TW.properties | 3 ++- .../mcprison/prison/ranks/commands/RankUpCommand.java | 8 ++++---- .../prison/ranks/commands/RankUpCommandMessages.java | 8 ++++++++ 8 files changed, 26 insertions(+), 10 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index ea67ac6aa..6d64a8deb 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.18b 2024-07-07 +# 3.3.0-alpha.18b 2024-07-08 + + +* **Rankup messages: externalized another message related to an economy failure.*** * **Mine bombs: Update and fix some issues with the new mine bomb processing and animations.** 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 9807416d3..2c1ec8c57 100644 --- a/prison-core/src/main/resources/lang/ranks/en_US.properties +++ b/prison-core/src/main/resources/lang/ranks/en_US.properties @@ -72,7 +72,7 @@ ## be able to enable them. -messages__version=29 +messages__version=30 messages__auto_refresh=true ranks_rankup__rankup_no_player_name=You have @@ -94,6 +94,7 @@ ranks_rankup__rankup_no_ranks=There are no ranks in this ladder. ranks_rankup__rankup_rank_does_not_exist=The rank %1 does not exist on this server. ranks_rankup__rankup_rank_is_not_in_ladder=The rank %1 does not exist in the ladder %2. ranks_rankup__rankup_currency_is_not_supported=The currency, %1, is not supported by any loaded economies. +ranks_rankup__rankup_economy_failed=Failed to adjust player's balance. Could be an issue with vault or a cache timing issue. Try again. ranks_rankup__rankup_ladder_removed=The ladder %1 was removed. ranks_rankup__rankup_failure_removing_ladder=Rankup failed since the player could not be removed from the ladder %1. (Players cannot be removed from the 'default' ladder). ranks_rankup__rankup_in_progress_failure=Rankup failed to complete normally. No status was set. 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 d5284ec1b..1e5c2ab66 100644 --- a/prison-core/src/main/resources/lang/ranks/fr_FR.properties +++ b/prison-core/src/main/resources/lang/ranks/fr_FR.properties @@ -72,7 +72,7 @@ ## be able to enable them. -messages__version=28 +messages__version=29 messages__auto_refresh=true ranks_rankup__rankup_no_player_name=Tu as @@ -94,6 +94,7 @@ ranks_rankup__rankup_no_ranks=Il n'y a pas de rangs dans ce classement. ranks_rankup__rankup_rank_does_not_exist=Le rang %1 n'existe pas dans ce serveur. ranks_rankup__rankup_rank_is_not_in_ladder=Le rang %1 n'existe pas dans le classement %2. ranks_rankup__rankup_currency_is_not_supported=La monnaie, %1, n'est pas supporté par aucun plugin d'économie chargé. +ranks_rankup__rankup_economy_failed=Failed to adjust player's balance. Could be an issue with vault or a cache timing issue. Try again. ranks_rankup__rankup_ladder_removed=Le classement %1 a été supprimé. ranks_rankup__rankup_failure_removing_ladder=La montée en rang a échoué comme le joueur n'a pas pu être supprimé du classement. (Les joueurs ne peuvent pas être supprimés du classement 'default'). ranks_rankup__rankup_in_progress_failure=La montée en rang n'a pas réussi à se terminer correctement. Aucun statut n'a été défini. 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 13c0a863c..d24bc1e39 100644 --- a/prison-core/src/main/resources/lang/ranks/pt_PT.properties +++ b/prison-core/src/main/resources/lang/ranks/pt_PT.properties @@ -72,7 +72,7 @@ ## be able to enable them. -messages__version=6 +messages__version=7 messages__auto_refresh=true ranks_rankup__rankup_no_player_name=Tu têns @@ -94,6 +94,7 @@ ranks_rankup__rankup_no_ranks=Não existe ranks nesta ladder. ranks_rankup__rankup_rank_does_not_exist=O rank %1 não existe neste server. ranks_rankup__rankup_rank_is_not_in_ladder=O rank %1 não existe naladder %2. ranks_rankup__rankup_currency_is_not_supported=A economia não é suportada, %1. +ranks_rankup__rankup_economy_failed=Failed to adjust player's balance. Could be an issue with vault or a cache timing issue. Try again. ranks_rankup__rankup_ladder_removed=A ladder %1 foi removida. ranks_rankup__rankup_failure_removing_ladder=Rankup falhou porque nao foi possivel remover o player da ladder %1. (Players cannot be removed from the 'default' ladder). ranks_rankup__rankup_in_progress_failure=Rankup falhou ser complet corretamente. 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 9a53f49c5..73d9bca5c 100644 --- a/prison-core/src/main/resources/lang/ranks/zh-CN.properties +++ b/prison-core/src/main/resources/lang/ranks/zh-CN.properties @@ -72,7 +72,7 @@ ## be able to enable them. -messages__version=25 +messages__version=26 messages__auto_refresh=true ranks_rankup__rankup_no_player_name=ä½ å·²ç» @@ -92,6 +92,7 @@ ranks_rankup__rankup_failed_to_assign_rank_with_refund=分é…阶级失败. é‡ ranks_rankup__rankup_failed_to_save_player_file=无法检索或写入数æ®ï¼Œæ‚¨çš„æ–‡ä»¶å¯èƒ½å·²æŸå,通知æœåŠ¡å™¨ç®¡ç†å‘˜ ranks_rankup__rankup_no_ranks=这个矿区上没有阶级 ranks_rankup__rankup_rank_does_not_exist=阶级%1ä¸å­˜åœ¨ +ranks_rankup__rankup_economy_failed=Failed to adjust player's balance. Could be an issue with vault or a cache timing issue. Try again. ranks_rankup__rankup_rank_is_not_in_ladder=阶级%2中ä¸å­˜åœ¨é˜¶çº§%1 ranks_rankup__rankup_currency_is_not_supported=ä»»ä½•å·²åŠ è½½çš„ç»æµŽå‰ç½®éƒ½ä¸æ”¯æŒè´§å¸%1 ranks_rankup__rankup_ladder_removed=已删除阶级%1 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 45cce31bc..97fc64c7f 100644 --- a/prison-core/src/main/resources/lang/ranks/zh_TW.properties +++ b/prison-core/src/main/resources/lang/ranks/zh_TW.properties @@ -72,7 +72,7 @@ ## be able to enable them. -messages__version=9 +messages__version=10 messages__auto_refresh=true ranks_rankup__rankup_no_player_name=您已經 @@ -94,6 +94,7 @@ ranks_rankup__rankup_no_ranks=這個階內沒有階級 ranks_rankup__rankup_rank_does_not_exist=階級 %1 ä¸å­˜åœ¨ ranks_rankup__rankup_rank_is_not_in_ladder=此階級 %1 ä¸å­˜åœ¨æ–¼éšŽ %2 之中 ranks_rankup__rankup_currency_is_not_supported=這個貨幣, %1, 無法使用於此 +ranks_rankup__rankup_economy_failed=Failed to adjust player's balance. Could be an issue with vault or a cache timing issue. Try again. ranks_rankup__rankup_ladder_removed=階 %1 已經刪除 ranks_rankup__rankup_failure_removing_ladder=Rankup failed since the player could not be removed from the ladder %1. (Players cannot be removed from the 'default' ladder). ranks_rankup__rankup_in_progress_failure=無法正常的å‡ç´š. 此階級ä¸å­˜åœ¨ 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 f634c3e15..4f042eef4 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 @@ -1279,10 +1279,10 @@ public void processResults( CommandSender sender, String playerName, break; case RANKUP_FAILURE_ECONOMY_FAILED: - // TODO externalize message - String msg = "Failed to adjust player's balance. Could be an issue with vault or " + - "a cache timing issue. Try again."; - sender.sendMessage( results.getRankPlayer().convertStringPlaceholders( msg ) ); + ranksRankupFailureEconomyFailedMsg( sender, results.getRankPlayer() ); + //String msg = "Failed to adjust player's balance. Could be an issue with vault or " + + // "a cache timing issue. Try again."; + //sender.sendMessage( results.getRankPlayer().convertStringPlaceholders( msg ) ); break; diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RankUpCommandMessages.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RankUpCommandMessages.java index 6c1a1c9aa..2b12a2ca6 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RankUpCommandMessages.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RankUpCommandMessages.java @@ -557,6 +557,14 @@ protected void ranksRankupFailureCurrencyIsNotSupportedMsg( CommandSender sender .sendTo( sender, rPlayer ); } + protected void ranksRankupFailureEconomyFailedMsg( CommandSender sender, + RankPlayer rPlayer ) { + + PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( "ranks_rankup__rankup_economy_failed" ) + .sendTo( sender, rPlayer ); + } + protected void ranksRankupFailureLadderRemovedMsg( CommandSender sender, String ladder, RankPlayer rPlayer ) { From a55925e2e43e94fde7460fae147af2aaf077c92c Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 8 Jul 2024 10:57:04 -0400 Subject: [PATCH 074/323] Rankup: removed unused code to eliminate a compile warning. This is a trivial change that has no impact. --- docs/changelog_v3.3.x.md | 5 +++++ .../tech/mcprison/prison/ranks/commands/RankUpCommand.java | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 6d64a8deb..ae1419cb4 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.18b 2024-07-08 +* **Rankup: removed unused code to eliminate a compile warning.** +This is a trivial change that has no impact. + + + * **Rankup messages: externalized another message related to an economy failure.*** 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 4f042eef4..42161c4a0 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 @@ -474,7 +474,7 @@ public void prestigeCmd(CommandSender sender, submitCmdTasks( player, cmdTasks ); } else { - Player player = getPlayer( sender, playerName ); +// Player player = getPlayer( sender, playerName ); Output.get().logDebug( DebugTarget.rankup, "Rankup: Failed: cmd '/prestige %s%s' Does not have the permission %s. [%s]", (playerName.length() == 0 ? "" : " " + playerName ), From c673a2211f34d29f58017b06e11ec604c76b535f Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 8 Jul 2024 10:59:53 -0400 Subject: [PATCH 075/323] RankPlayer files: minor change to how the permission snap shots are handled to fix a problem where it was not working correctly. When a player was online, it would properly populate the permsSnapShot array with the player's current perm list. But when they logged off, then it would be cleared. This fix ensures that the perms updated and saved, so they can be properly loaded when they are not online. --- docs/changelog_v3.3.x.md | 5 +++++ .../tech/mcprison/prison/ranks/data/RankPlayerFactory.java | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index ae1419cb4..ad34ebaea 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.18b 2024-07-08 +* **RankPlayer files: minor change to how the permission snap shots are handled to fix a problem where it was not working correctly.** +When a player was online, it would properly populate the permsSnapShot array with the player's current perm list. But when they logged off, then it would be cleared. +This fix ensures that the perms updated and saved, so they can be properly loaded when they are not online. + + * **Rankup: removed unused code to eliminate a compile warning.** This is a trivial change that has no impact. diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactory.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactory.java index 61e8a18e4..8bbec5491 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactory.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactory.java @@ -254,10 +254,11 @@ public static Document toDocument( RankPlayer rankPlayer ) { if ( sPlayer != null && sPlayer.isOnline() ) { // If the player is online, get a fresh list of perms: perms = sPlayer.getPermissions(); + rankPlayer.setPermsSnapShot(perms); } else { // Otherwise since the player if offline, then save whatever permsSnapShot is already available: - rankPlayer.getPermsSnapShot(); + perms = rankPlayer.getPermsSnapShot(); } ret.put( "permsSnapShot", perms ); From 06c5d082ea79dbc6aa9fb207cccb15b1d2dcd406 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 10 Jul 2024 01:55:26 -0400 Subject: [PATCH 076/323] Disabled the system settings component. It posed too much risk for something to go wrong, especially if the config file that it was using was eliminated. Now the server is able to more intelligently deal with file names, and how to auto upgrade them. This makes it easier on the server, and it helps transition over to the new format for the file names. --- .../prison/backups/PrisonSystemSettings.java | 277 +++++++++--------- .../tech/mcprison/prison/file/FileIO.java | 27 +- .../prison/ranks/commands/RanksCommands.java | 91 +++--- .../PlayerNewFileNameCheckAsyncTask.java | 209 +++++++------ 4 files changed, 303 insertions(+), 301 deletions(-) diff --git a/prison-core/src/main/java/tech/mcprison/prison/backups/PrisonSystemSettings.java b/prison-core/src/main/java/tech/mcprison/prison/backups/PrisonSystemSettings.java index 59df26e99..86563d77c 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/backups/PrisonSystemSettings.java +++ b/prison-core/src/main/java/tech/mcprison/prison/backups/PrisonSystemSettings.java @@ -1,11 +1,6 @@ package tech.mcprison.prison.backups; -import java.io.File; -import java.util.TreeMap; - -import tech.mcprison.prison.Prison; import tech.mcprison.prison.file.FileIOData; -import tech.mcprison.prison.file.JsonFileIO; /** *

This class serves as a way for prison to track major events and @@ -26,9 +21,9 @@ public class PrisonSystemSettings public static final String PRISON_SYSTEM_SETTING_FRIENDLY_PLAYER_FILE_NAMES = "prison-ranks.use-friendly-user-file-names"; - private static PrisonSystemSettings instance = null; +// private static PrisonSystemSettings instance = null; - private TreeMap> settings; +// private TreeMap> settings; public enum SystemSettingsKey { PlayerFileNameUpdate @@ -36,153 +31,153 @@ public enum SystemSettingsKey { ; } - private PrisonSystemSettings() { - super(); - - this.settings = new TreeMap<>(); - } +// private PrisonSystemSettings() { +// super(); +// +// this.settings = new TreeMap<>(); +// } - public static PrisonSystemSettings getInstance() { - if ( instance == null ) { - synchronized ( PrisonSystemSettings.class ) { - if ( instance == null ) { - - instance = new PrisonSystemSettings(); - } - } - } - - return instance; - } - - /** - *

This function should be used to add new root nodes to ensure - * that they are of type SystemSettingKey values. This functional - * also adds a TreeMap as it's value pair so it's ready to - * take on values. - *

- * - * @param rootKey - */ - public void addRootSetting( SystemSettingsKey rootKey ) { - if ( !getSettings().containsKey( rootKey.name()) ) { - - getSettings().put( rootKey.name(), new TreeMap<>() ); - } - } - - public TreeMap getRootSetting( SystemSettingsKey rootkey ) { - TreeMap results = null; - - if ( getSettings() == null ) { - load(); - } - - // Try to add the rootKey just in case it does not exist: - addRootSetting(rootkey); - - results = getSettings().get(rootkey.name()); - - return results; - } +// public static PrisonSystemSettings getInstance() { +// if ( instance == null ) { +// synchronized ( PrisonSystemSettings.class ) { +// if ( instance == null ) { +// +// instance = new PrisonSystemSettings(); +// } +// } +// } +// +// return instance; +// } - private TreeMap> getSettings() { - if ( settings == null ) { - this.settings = new TreeMap<>(); - } - return settings; - } - private void setSettings(TreeMap> settings) { - this.settings = settings; - } +// /** +// *

This function should be used to add new root nodes to ensure +// * that they are of type SystemSettingKey values. This functional +// * also adds a TreeMap as it's value pair so it's ready to +// * take on values. +// *

+// * +// * @param rootKey +// */ +// public void addRootSetting( SystemSettingsKey rootKey ) { +// if ( !getSettings().containsKey( rootKey.name()) ) { +// +// getSettings().put( rootKey.name(), new TreeMap<>() ); +// } +// } +// +// public TreeMap getRootSetting( SystemSettingsKey rootkey ) { +// TreeMap results = null; +// +// if ( getSettings() == null ) { +// load(); +// } +// +// // Try to add the rootKey just in case it does not exist: +// addRootSetting(rootkey); +// +// results = getSettings().get(rootkey.name()); +// +// return results; +// } +// +// private TreeMap> getSettings() { +// if ( settings == null ) { +// this.settings = new TreeMap<>(); +// } +// return settings; +// } +// private void setSettings(TreeMap> settings) { +// this.settings = settings; +// } - public void save() { - File file = getPrisonSystemSettingsFile(); - - JsonFileIO jfIo = new JsonFileIO(); - - jfIo.saveJsonFile(file, this); - } +// public void save() { +// File file = getPrisonSystemSettingsFile(); +// +// JsonFileIO jfIo = new JsonFileIO(); +// +// jfIo.saveJsonFile(file, this); +// } - public void load() { - File file = getPrisonSystemSettingsFile(); - - if ( file.exists() ) { - JsonFileIO jfIo = new JsonFileIO(); - - PrisonSystemSettings settings = (PrisonSystemSettings) jfIo.readJsonFile(file, this); - - setSettings( settings.getSettings() ); - - } - } +// public void load() { +// File file = getPrisonSystemSettingsFile(); +// +// if ( file.exists() ) { +// JsonFileIO jfIo = new JsonFileIO(); +// +// PrisonSystemSettings settings = (PrisonSystemSettings) jfIo.readJsonFile(file, this); +// +// setSettings( settings.getSettings() ); +// +// } +// } // public void unload() { // setSettings( null ); // } - public File getPrisonSystemSettingsFile() { - - File dataStoragePath = new File( Prison.get().getDataFolder(), "data_storage" ); - - File systemPath = new File( dataStoragePath, "system" ); - - systemPath.mkdirs(); - - return new File( systemPath, PRISON_SYSTEM_FILENAME ); - } +// public File getPrisonSystemSettingsFile() { +// +// File dataStoragePath = new File( Prison.get().getDataFolder(), "data_storage" ); +// +// File systemPath = new File( dataStoragePath, "system" ); +// +// systemPath.mkdirs(); +// +// return new File( systemPath, PRISON_SYSTEM_FILENAME ); +// } - /** - *

This function will check two things. First will be the config settings within - * 'config.yml' to see if the new format is enabled. Secondly, it checks to see if - * the PrisonSystemSettings has recorded if the conversion has taken place. - * Both have to be true in order for this function to return a value of true., - *

- * - * @return - */ - public static boolean useFriendlyUserFileNames() { - - boolean useNewFormat = Prison.get().getPlatform() - .getConfigBooleanFalse( PRISON_SYSTEM_SETTING_FRIENDLY_PLAYER_FILE_NAMES ); - - if ( useNewFormat ) { - - boolean converted = checkSystemFriendlyUserFileNamesConverted(); - - useNewFormat = converted; - } - - return useNewFormat; - } +// /** +// *

This function will check two things. First will be the config settings within +// * 'config.yml' to see if the new format is enabled. Secondly, it checks to see if +// * the PrisonSystemSettings has recorded if the conversion has taken place. +// * Both have to be true in order for this function to return a value of true., +// *

+// * +// * @return +// */ +// public static boolean useFriendlyUserFileNames() { +// +// boolean useNewFormat = Prison.get().getPlatform() +// .getConfigBooleanFalse( PRISON_SYSTEM_SETTING_FRIENDLY_PLAYER_FILE_NAMES ); +// +// if ( useNewFormat ) { +// +// boolean converted = checkSystemFriendlyUserFileNamesConverted(); +// +// useNewFormat = converted; +// } +// +// return useNewFormat; +// } - /** - *

This function specifically returns the value of the 'converted' setting for the - * 'playerFileNameUpdate' prison system key. - *

- * - *

This does not perform any checks on the settings within 'config.yml'. For a full - * check of both this 'converted' value, and the config settings use the - * 'useFriendlyUserFileNames()' function instead of this function. - *

- * - * @return - */ - public static boolean checkSystemFriendlyUserFileNamesConverted() { - - TreeMap pfnUpdate = - PrisonSystemSettings.getInstance().getRootSetting( SystemSettingsKey.PlayerFileNameUpdate ); - - // Unload the data: -// PrisonSystemSettings.getInstance().unload(); - - boolean converted = !pfnUpdate.containsKey("converted") ? - false : (Boolean) pfnUpdate.get("converted"); - - return converted; - } +// /** +// *

This function specifically returns the value of the 'converted' setting for the +// * 'playerFileNameUpdate' prison system key. +// *

+// * +// *

This does not perform any checks on the settings within 'config.yml'. For a full +// * check of both this 'converted' value, and the config settings use the +// * 'useFriendlyUserFileNames()' function instead of this function. +// *

+// * +// * @return +// */ +// public static boolean checkSystemFriendlyUserFileNamesConverted() { +// +// TreeMap pfnUpdate = +// PrisonSystemSettings.getInstance().getRootSetting( SystemSettingsKey.PlayerFileNameUpdate ); +// +// // Unload the data: +//// PrisonSystemSettings.getInstance().unload(); +// +// boolean converted = !pfnUpdate.containsKey("converted") ? +// false : (Boolean) pfnUpdate.get("converted"); +// +// return converted; +// } } diff --git a/prison-core/src/main/java/tech/mcprison/prison/file/FileIO.java b/prison-core/src/main/java/tech/mcprison/prison/file/FileIO.java index ce02263dd..e5d9f15e9 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/file/FileIO.java +++ b/prison-core/src/main/java/tech/mcprison/prison/file/FileIO.java @@ -13,7 +13,6 @@ import java.util.List; import tech.mcprison.prison.Prison; -import tech.mcprison.prison.backups.PrisonSystemSettings; import tech.mcprison.prison.error.Error; import tech.mcprison.prison.error.ErrorManager; import tech.mcprison.prison.internal.Player; @@ -401,19 +400,19 @@ else if ( !newFileName.equals(results.getName()) ) { } - /** - *

This function will check two things. First will be the config settings within - * 'config.yml' to see if the new format is enabled. Secondly, it checks to see if - * the PrisonSystemSettings has recorded if the conversion has taken place. - * Both have to be true in order for this function to return a value of true., - *

- * - * @return - */ - public static boolean useFriendlyUserFileNames() { - - return PrisonSystemSettings.useFriendlyUserFileNames(); - } +// /** +// *

This function will check two things. First will be the config settings within +// * 'config.yml' to see if the new format is enabled. Secondly, it checks to see if +// * the PrisonSystemSettings has recorded if the conversion has taken place. +// * Both have to be true in order for this function to return a value of true., +// *

+// * +// * @return +// */ +// public static boolean useFriendlyUserFileNames() { +// +// return PrisonSystemSettings.useFriendlyUserFileNames(); +// } /** * Do not use. Use 'filenameCache( player )'. 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 f65063f2f..e8891b651 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 @@ -15,7 +15,6 @@ import tech.mcprison.prison.Prison; import tech.mcprison.prison.PrisonAPI; import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; -import tech.mcprison.prison.backups.PrisonSystemSettings; import tech.mcprison.prison.autofeatures.AutoFeaturesWrapper; import tech.mcprison.prison.cache.PlayerCache; import tech.mcprison.prison.cache.PlayerCachePlayerData; @@ -2377,19 +2376,24 @@ public void rankTopN(CommandSender sender, - @Command(identifier = "prison support updates playerFileNameUpdate", - description = "&3This command will run a task that will check both the " + - "Player Rank files and the Player Cache files to see if " + - "they are using an old naming format. If they are, then the " + - "files are renamed to the new format. This command can be " + - "ran multiple times, since nothing will be changed if the " + - "file names have already been converted." + - "{br}" + - "&3Inorder to use the new naming formats, the 'config.yml' must " + - "contain the boolean property " + - "'prison-ranks.use-friendly-user-file-name' with a value of " + - "true. Failure to both set that to a value of true, and " + - "to run this updater may lead to possible player data corruption." + + @Command(identifier = "prison support fileNameReports", + description = "&3This command will run one of two reports that will show " + + "the old file format on the left, and the new format on the " + + "right. This can be useful to lookup players under the old " + + "file name format. The new report is based upon the user's name " + + "so as to be visually identifiable to a specific player. " + +// description = "&3This command will run a task that will check both the " + +// "Player Rank files and the Player Cache files to see if " + +// "they are using an old naming format. If they are, then the " + +// "files are renamed to the new format. This command can be " + +// "ran multiple times, since nothing will be changed if the " + +// "file names have already been converted." + +// "{br}" + +// "&3Inorder to use the new naming formats, the 'config.yml' must " + +// "contain the boolean property " + +// "'prison-ranks.use-friendly-user-file-name' with a value of " + +// "true. Failure to both set that to a value of true, and " + +// "to run this updater may lead to possible player data corruption." + "" + "" + "{br}" + @@ -2401,13 +2405,22 @@ public void rankTopN(CommandSender sender, "could result in ambiguous file names where all bedrock players " + "would have the same prefix. The whole point of only using the " + "first eight hex digits was that they would have still be all " + - "unique.{br}", + "unique.{br} " + + "Note: This command was intended originally to provide the conversion " + + "to the newer file names, but prison was modified to be more intelligent " + + "in being able to identify which format is being used, and then also " + + "automatically update each file when saved again. Both old nad new file " + + "name formats can exist at the same time, especially for players, but " + + "when their status updates, then the file will be upgraded. If the player " + + "never logs back on to the system, it will never trigger an update. So " + + "use this report to identify players that may not be converted.", onlyPlayers = false, permissions = "prison.debug" ) public void supportPlayerFileNameUpdateCmd(CommandSender sender, - @Arg(name = "action", def = "status", - description = "Only shows the PrisonSystemStatus for the " - + "'PlayerFileNameUpdate' and will not try to run the " - + "update. Default: 'status'. [status, run, cache, player]") + @Arg(name = "action", def = "player", + description = "Run the player report. Default: 'player'. [cache, player]") +// description = "Only shows the PrisonSystemStatus for the " +// + "'PlayerFileNameUpdate' and will not try to run the " +// + "update. Default: 'status'. [status, run, cache, player]") String action, @Arg(name = "page", def = "1", description = "If a report of 'cache' or 'player', then page is used if there " + @@ -2419,35 +2432,35 @@ public void supportPlayerFileNameUpdateCmd(CommandSender sender, // Get the PrisonSystemSettings for the PlayerFileNameUpdate and format the results: PlayerNewFileNameCheckAsyncTask task = new PlayerNewFileNameCheckAsyncTask(); - List msg = task.getStatusDetails(); +// List msg = task.getStatusDetails(); - boolean useNewFormat = Prison.get().getPlatform() - .getConfigBooleanFalse( PrisonSystemSettings.PRISON_SYSTEM_SETTING_FRIENDLY_PLAYER_FILE_NAMES ); +// boolean useNewFormat = Prison.get().getPlatform() +// .getConfigBooleanFalse( PrisonSystemSettings.PRISON_SYSTEM_SETTING_FRIENDLY_PLAYER_FILE_NAMES ); // msg.add( "" ); - sender.sendMessage(msg); +// sender.sendMessage(msg); if ( reportMode == ReportMode.cache || reportMode == ReportMode.players ) { task.playerConverterReport( reportMode, page ); } - else if ( reportMode == ReportMode.run ) { - - if ( !useNewFormat ) { - Output.get().logInfo( "&cCommand failure: &aBefore the player file names can be " + - "checked, the setting '&c%s&a' " + - "must be set to '&ctrue&a'. Once enabled, this can not be " + - "reverted because the player files (Player Ranks and Player Caches) " + - "could be corrupted.", - PrisonSystemSettings.PRISON_SYSTEM_SETTING_FRIENDLY_PLAYER_FILE_NAMES - ); - } - else { - long delayTicks = 0; - PlayerNewFileNameCheckAsyncTask.submitTaskSync( delayTicks ); - } - } +// else if ( reportMode == ReportMode.run ) { +// +// if ( !useNewFormat ) { +// Output.get().logInfo( "&cCommand failure: &aBefore the player file names can be " + +// "checked, the setting '&c%s&a' " + +// "must be set to '&ctrue&a'. Once enabled, this can not be " + +// "reverted because the player files (Player Ranks and Player Caches) " + +// "could be corrupted.", +// PrisonSystemSettings.PRISON_SYSTEM_SETTING_FRIENDLY_PLAYER_FILE_NAMES +// ); +// } +// else { +// long delayTicks = 0; +// PlayerNewFileNameCheckAsyncTask.submitTaskSync( delayTicks ); +// } +// } } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/tasks/PlayerNewFileNameCheckAsyncTask.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/tasks/PlayerNewFileNameCheckAsyncTask.java index 739603e41..9c28b0f80 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/tasks/PlayerNewFileNameCheckAsyncTask.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/tasks/PlayerNewFileNameCheckAsyncTask.java @@ -1,15 +1,10 @@ package tech.mcprison.prison.ranks.tasks; import java.io.File; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; import java.util.List; -import java.util.TreeMap; import tech.mcprison.prison.Prison; import tech.mcprison.prison.backups.PrisonSystemSettings; -import tech.mcprison.prison.backups.PrisonSystemSettings.SystemSettingsKey; import tech.mcprison.prison.cache.PlayerCachePlayerData; import tech.mcprison.prison.file.JsonFileIO; import tech.mcprison.prison.output.Output; @@ -27,8 +22,8 @@ public class PlayerNewFileNameCheckAsyncTask implements PrisonRunnable { public enum ReportMode { - status, - run, +// status, +// run, players, cache; @@ -154,110 +149,110 @@ public void run() { changedPlayRankFiles, changedCacheFiles ); - if ( changedCacheFiles > 0 || changedCacheFiles > 0 ) { - saveStatusDetailLog( changedPlayRankFiles, changedCacheFiles ); - } - else if ( players.size() > 0 ) { - Output.get().logInfo( - "&3PlayerFileNameCheck Task: It appears as if all player files have " - + "already been converted." ); - } - - List msgs = getStatusDetails(); - - for (String msg : msgs) { - - Output.get().logInfo( msg ); - } +// if ( changedCacheFiles > 0 || changedCacheFiles > 0 ) { +// saveStatusDetailLog( changedPlayRankFiles, changedCacheFiles ); +// } +// else if ( players.size() > 0 ) { +// Output.get().logInfo( +// "&3PlayerFileNameCheck Task: It appears as if all player files have " +// + "already been converted." ); +// } + +// List msgs = getStatusDetails(); +// +// for (String msg : msgs) { +// +// Output.get().logInfo( msg ); +// } } - public void saveStatusDetailLog( int changedPlayRankFiles, int changedCacheFiles ) { - // Need to log it: - TreeMap settings = PrisonSystemSettings.getInstance() - .getRootSetting( SystemSettingsKey.PlayerFileNameUpdate ); - - if ( !settings.containsKey( "converted") ) { - settings.put("converted", Boolean.TRUE ); - } - - if ( !settings.containsKey( "logs") ) { - settings.put("logs", new ArrayList() ); - } - - @SuppressWarnings("unchecked") - ArrayList logs = (ArrayList) settings.get("logs"); - - TreeMap log = new TreeMap<>(); - - SimpleDateFormat sdFmt = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss"); - log.put("run-date", sdFmt.format(new Date()) ); - log.put("player-cache-files-changed", Integer.valueOf(changedPlayRankFiles) ); - log.put("player-rank-files-changed", Integer.valueOf(changedCacheFiles) ); - - logs.add( log ); - - // Save the update: - PrisonSystemSettings.getInstance().save(); - - // Unload the data: -// PrisonSystemSettings.getInstance().unload(); - - - } +// public void saveStatusDetailLog( int changedPlayRankFiles, int changedCacheFiles ) { +// // Need to log it: +// TreeMap settings = PrisonSystemSettings.getInstance() +// .getRootSetting( SystemSettingsKey.PlayerFileNameUpdate ); +// +// if ( !settings.containsKey( "converted") ) { +// settings.put("converted", Boolean.TRUE ); +// } +// +// if ( !settings.containsKey( "logs") ) { +// settings.put("logs", new ArrayList() ); +// } +// +// @SuppressWarnings("unchecked") +// ArrayList logs = (ArrayList) settings.get("logs"); +// +// TreeMap log = new TreeMap<>(); +// +// SimpleDateFormat sdFmt = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss"); +// log.put("run-date", sdFmt.format(new Date()) ); +// log.put("player-cache-files-changed", Integer.valueOf(changedPlayRankFiles) ); +// log.put("player-rank-files-changed", Integer.valueOf(changedCacheFiles) ); +// +// logs.add( log ); +// +// // Save the update: +// PrisonSystemSettings.getInstance().save(); +// +// // Unload the data: +//// PrisonSystemSettings.getInstance().unload(); +// +// +// } - public List getStatusDetails() { - List msg = new ArrayList<>(); - - String msgFmt = " %-22s %7s %7s"; - - boolean useNewFormat = Prison.get().getPlatform() - .getConfigBooleanFalse( PrisonSystemSettings.PRISON_SYSTEM_SETTING_FRIENDLY_PLAYER_FILE_NAMES ); - - TreeMap pfnUpdate = - PrisonSystemSettings.getInstance().getRootSetting( SystemSettingsKey.PlayerFileNameUpdate ); - - // Unload the data: -// PrisonSystemSettings.getInstance().unload(); - - boolean converted = !pfnUpdate.containsKey("converted") ? - false : (Boolean) pfnUpdate.get("converted"); - - msg.add( "PlayerFileNameUpdate: status: " ); - msg.add( " '" + PrisonSystemSettings.PRISON_SYSTEM_SETTING_FRIENDLY_PLAYER_FILE_NAMES + "': " + - Boolean.toString(useNewFormat) ); - msg.add( " converted: " + Boolean.toString(converted) ); - - if ( converted ) { - - @SuppressWarnings("unchecked") - ArrayList logs = (ArrayList) pfnUpdate.get("logs"); - - msg.add( String.format(msgFmt, "", "Changed", "Changed")); - msg.add( String.format(msgFmt, "Date", "P-Ranks", "P-Cache")); - msg.add( String.format(msgFmt, "-----------------", "-------", "-------")); - - for (Object logObj : logs) { - @SuppressWarnings("unchecked") - TreeMap log = (TreeMap) logObj; - - String runDate = (String) log.get("run-date"); - int changedPlayRankFiles = (Integer) log.get("player-cache-files-changed"); - int changedCacheFiles = (Integer) log.get("player-rank-files-changed"); - - msg.add( String.format(msgFmt, - runDate, - Integer.toString(changedCacheFiles), - Integer.toString(changedPlayRankFiles))); - } - - } - - // msg.add( "" ); - - - return msg; - } +// public List getStatusDetails() { +// List msg = new ArrayList<>(); +// +// String msgFmt = " %-22s %7s %7s"; +// +// boolean useNewFormat = Prison.get().getPlatform() +// .getConfigBooleanFalse( PrisonSystemSettings.PRISON_SYSTEM_SETTING_FRIENDLY_PLAYER_FILE_NAMES ); +// +// TreeMap pfnUpdate = +// PrisonSystemSettings.getInstance().getRootSetting( SystemSettingsKey.PlayerFileNameUpdate ); +// +// // Unload the data: +//// PrisonSystemSettings.getInstance().unload(); +// +// boolean converted = !pfnUpdate.containsKey("converted") ? +// false : (Boolean) pfnUpdate.get("converted"); +// +// msg.add( "PlayerFileNameUpdate: status: " ); +// msg.add( " '" + PrisonSystemSettings.PRISON_SYSTEM_SETTING_FRIENDLY_PLAYER_FILE_NAMES + "': " + +// Boolean.toString(useNewFormat) ); +// msg.add( " converted: " + Boolean.toString(converted) ); +// +// if ( converted ) { +// +// @SuppressWarnings("unchecked") +// ArrayList logs = (ArrayList) pfnUpdate.get("logs"); +// +// msg.add( String.format(msgFmt, "", "Changed", "Changed")); +// msg.add( String.format(msgFmt, "Date", "P-Ranks", "P-Cache")); +// msg.add( String.format(msgFmt, "-----------------", "-------", "-------")); +// +// for (Object logObj : logs) { +// @SuppressWarnings("unchecked") +// TreeMap log = (TreeMap) logObj; +// +// String runDate = (String) log.get("run-date"); +// int changedPlayRankFiles = (Integer) log.get("player-cache-files-changed"); +// int changedCacheFiles = (Integer) log.get("player-rank-files-changed"); +// +// msg.add( String.format(msgFmt, +// runDate, +// Integer.toString(changedCacheFiles), +// Integer.toString(changedPlayRankFiles))); +// } +// +// } +// +// // msg.add( "" ); +// +// +// return msg; +// } /** From 59b336943e40f93cd12cd26f98656d19cae4a751 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 11 Jul 2024 02:00:28 -0400 Subject: [PATCH 077/323] Prison commands: Added two new command placeholders that are globally available to allow control of commands based upon player perms. The new placeholders are '{ifPerm:}' and '{ifNotPerm:}' and this will control the execution of all commands that follows those placeholders. --- docs/changelog_v3.3.x.md | 7 +++++ .../prison/tasks/PrisonCommandTaskData.java | 30 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index ad34ebaea..e84cd9d1a 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.18b 2024-07-08 +* **Prison commands: Added two new command placeholders that are globally available to allow control of commands based upon player perms.** +The new placeholders are '{ifPerm:}' and '{ifNotPerm:}' and this will control the execution of all commands that follows those placeholders. + + +* **Disabled the system settings component.** It posed too much risk for something to go wrong, especially if the config file that it was using was eliminated. Now the server is able to more intelligently deal with file names, and how to auto upgrade them. This makes it easier on the server, and it helps transition over to the new format for the file names. + + * **RankPlayer files: minor change to how the permission snap shots are handled to fix a problem where it was not working correctly.** When a player was online, it would properly populate the permsSnapShot array with the player's current perm list. But when they logged off, then it would be cleared. This fix ensures that the perms updated and saved, so they can be properly loaded when they are not online. diff --git a/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonCommandTaskData.java b/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonCommandTaskData.java index 3c4c20f8d..a7522b66d 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonCommandTaskData.java +++ b/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonCommandTaskData.java @@ -108,6 +108,14 @@ public enum CustomPlaceholders { "{syncPlayer} runs the command as the payer in a new sync task."), + ifPerm(CommandEnvironment.all_commands, + "{ifPerm:} Continues executing commands in the chain if " + + "the player has the perm ''."), + ifNotPerm(CommandEnvironment.all_commands, + "{ifNotPerm:} Stops executing commands in the chain if " + + "the player has the perm ''."), + + firstJoin(CommandEnvironment.rank_commands, "{firstJoin} runs the command on first join events for new players"), promote(CommandEnvironment.rank_commands, @@ -432,6 +440,28 @@ public void runTask( Player player ) { // was failing with leading spaces after spliting after a ";" so trim to fix it: task = task == null ? "" : task.trim(); + + + // If the task is '{ifPerm:}' then the player must have the perm to + // continue: + if ( task.toLowerCase().startsWith( "{ifperm:" ) ) { + String perm = task.substring( 7, task.length() - 1 ); + + boolean hasPerm = player.hasPermission( perm ); + + if ( !hasPerm ) { + break; + } + } + if ( task.toLowerCase().startsWith( "{ifnotperm:" ) ) { + String perm = task.substring( 10, task.length() - 1 ); + + boolean hasPerm = player.hasPermission( perm ); + + if ( hasPerm ) { + break; + } + } // Apply the custom placeholders: From 875b7975e873258be4adf3fce92a7a4dd1e2e126 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 11 Jul 2024 22:48:25 -0400 Subject: [PATCH 078/323] Prison v3.3.0-beta.18c 2024-07-10 --- docs/changelog_v3.3.x.md | 31 +++++++++++++++++++++++++++++-- gradle.properties | 2 +- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index e84cd9d1a..68aee4d71 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,34 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.18b 2024-07-08 +# 3.3.0-beta.18c 2024-07-09 + + +* **3.3.0-beta.18c Beta release - Please read!!** +I usually do not release beta versions because I do not want to expose anything risky +to any server. + +The reason why this is a beta release: There are changes to two different player file names that older releases of prison cannot correctly read or access. + + +The reason why this is a beta release: There are changes to two different player file names that older releases of prison cannot correctly read or access. + +**Since this is a beta release, use at your own risk.** +**Please backup your files**, although prison automatically updates all of prison's files when a new version is detected, and +before starting the new prison version. Those backups can be found in the `plugins/Prison/backups/` +folder. + +**Please wait and do not use this BETA release if you do not want to risk trying this beta, please wait until the next alpha is released, which will be in about a week or two.****Please wait and do not use this BETA release If you do not want to risk trying this beta, please wait until the next alpha is released, which will be in about a week or two.** + +The reason why this is a beta version, is because the file name format for RankPlayer files and the player cache files have changed. Everything is working great, but the catch is that +this is the first time with prison that you cannot easily rollback to an older version. It's possible, but you have to manually copy or rename files. + +The file names have been changed so the player's name is now part of the file name so its easier to identify which file belongs to each player. This also makes Prison more compatible with bedrock platforms. + +Prison is using an intelligent method to identify what the file name is, and it's able to use either the new format, or the old. Prison also automatically updates the file name to the newer format when the file is saved again. + +This release has been tested for about a week plus on my test servers, and it's proving to be very stable. But I would like to see a few more users to confirm there isn't an odd combination of settings that are causing issues. If you encounter any issues, please ping me on discord. You can even DM me directly. + * **Prison commands: Added two new command placeholders that are globally available to allow control of commands based upon player perms.** @@ -65,7 +92,7 @@ This is not fully functioning yet, but it's getting closer. -* **Mine bombs: Fix issue with the printing of the error message with the included json data since it contains non-encoded % signs. Setup regex comments on them by using: `\Q` and `\E`.*** +* **Mine bombs: Fix issue with the printing of the error message with the included json data since it contains non-encoded % signs. Setup regex comments on them by using: `\Q` and `\E`.** * **Mine bombs: More work on getting the new mine bombs functional and working better. diff --git a/gradle.properties b/gradle.properties index 1235bab9f..ef6eae228 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.18b +version=3.3.0-beta.18c From 5712a2a421cea0d879f2286a49862317c7b8805e Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 11 Jul 2024 22:53:26 -0400 Subject: [PATCH 079/323] Mine Bombs: cooldowns. Changed the cooldown handling by moving it to the mine bomb's core and created its own task to run to monitor it. Fixed issue with the older version of cooldowns not working properly with throwing the mine bombs. --- .../prison/bombs/MineBombCooldownTask.java | 115 ++++++++ .../tech/mcprison/prison/bombs/MineBombs.java | 41 ++- .../spigot/utils/PrisonBombListener.java | 270 ++++++++++-------- .../spigot/utils/PrisonUtilsMineBombs.java | 46 ++- .../utils/PrisonUtilsMineBombsTasks.java | 126 ++++---- 5 files changed, 384 insertions(+), 214 deletions(-) create mode 100644 prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombCooldownTask.java diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombCooldownTask.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombCooldownTask.java new file mode 100644 index 000000000..68b8a079a --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombCooldownTask.java @@ -0,0 +1,115 @@ +package tech.mcprison.prison.bombs; + +import java.util.Map; +import java.util.TreeMap; + +import tech.mcprison.prison.internal.Player; +import tech.mcprison.prison.tasks.PrisonRunnable; +import tech.mcprison.prison.tasks.PrisonTaskSubmitter; + +public class MineBombCooldownTask + implements PrisonRunnable { + + public static int DELAY_TICKS = 1; + + private static final Map playerCooldowns = new TreeMap<>(); + + private String playerUUID; + + private int taskId = -1; + + public MineBombCooldownTask( String playerUUID ) { + super(); + + this.playerUUID = playerUUID; + } + + public static boolean addPlayerCooldown( Player player, int ticks ) { + boolean results = false; + + int cooldown = checkPlayerCooldown( player ); + if ( cooldown <= 0 ) { + submitCooldownTask( player, ticks ); + results = true; + } + + return results; + } + + + private static int submitCooldownTask( Player player, int ticks ) { + int results = -1; + + if ( player != null ) { + String playerUUID = player.getUUID().toString(); + + playerCooldowns.put( playerUUID, ticks ); + + MineBombCooldownTask task = new MineBombCooldownTask( playerUUID ); + + int taskId = PrisonTaskSubmitter.runTaskTimer( task, DELAY_TICKS, DELAY_TICKS); + + task.setTaskId( taskId ); + } + + return results; + } + + /** + * Since this runs every 5 ticks, it removes 5 from the cooldown ticks. + * When it reaches a value of zero, then the cooldown is over. + */ + @Override + public void run() { + + Integer cooldownTicks = playerCooldowns.get( getPlayerUUID() ); + + int ticksRemaining = cooldownTicks == null ? 0 : cooldownTicks - DELAY_TICKS; + + if ( ticksRemaining <= 0 ) + { + playerCooldowns.remove( getPlayerUUID() ); + + PrisonTaskSubmitter.cancelTask( getTaskId() ); + } + else + { + playerCooldowns.put( getPlayerUUID(), ticksRemaining ); + } + } + + + + public static int checkPlayerCooldown( Player player ) + { + int results = 0; + + if ( player != null ) { + + String playerUUID = player.getUUID().toString(); + + if ( playerCooldowns.containsKey( playerUUID ) ) + { + results = playerCooldowns.get( playerUUID ); + } + } + + return results; + } + + + public String getPlayerUUID() { + return playerUUID; + } + public void setPlayerUUID(String playerUUID) { + this.playerUUID = playerUUID; + } + + public int getTaskId() { + return taskId; + } + public void setTaskId(int taskId) { + this.taskId = taskId; + } + +} 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 73457b058..7d6d54af1 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 @@ -7,6 +7,7 @@ import tech.mcprison.prison.Prison; import tech.mcprison.prison.file.JsonFileIO; +import tech.mcprison.prison.internal.Player; import tech.mcprison.prison.internal.block.PrisonBlock; import tech.mcprison.prison.output.LogLevel; import tech.mcprison.prison.output.Output; @@ -28,6 +29,8 @@ public class MineBombs private static MineBombs instance; + + private MineBombsConfigData configData; @@ -161,6 +164,18 @@ public int compareTo(MineBombs o) { return results; } + public static int checkPlayerCooldown( Player player ) { + + int cooldownTicks = MineBombCooldownTask.checkPlayerCooldown( player ); + return cooldownTicks; + } + + public static boolean addPlayerCooldown( Player player, int ticks ) { + + boolean results = MineBombCooldownTask.addPlayerCooldown( player, ticks ); + return results; + } + // /** // *

This finds a bomb with the given name, and returns a clone. The clone is @@ -201,10 +216,11 @@ public int compareTo(MineBombs o) { * @param bombName * @return */ - public MineBombData findBombByName( String bombName ) + public MineBombData findBombByName( Player player, String bombName ) { MineBombData results = null; + String cleanedBombName = Text.stripColor( bombName.toLowerCase() ); if ( cleanedBombName != null && !cleanedBombName.isEmpty() ) { @@ -227,9 +243,32 @@ public MineBombData findBombByName( String bombName ) } } + if ( results != null ) { + + int ticks = results.getCooldownTicks(); + int cooldownTicks = MineBombCooldownTask.checkPlayerCooldown( player ); + + if ( cooldownTicks <= 0 ) { + // Submit another cooldown: + MineBombCooldownTask.addPlayerCooldown( player, ticks ); + } + else { + // The player is still in a cooldown using minebombs, so + // return a null instead of the bomb. + + //String message = "A mine bomb with the name of %s does not exist."; + +// player.sendMessage( String.format( message, bombName ) ); + + results = null; + } + } + return results == null ? null : results.clone(); } + + public void saveConfigJson() { 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 9ee9d0a43..4ff98eef0 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 @@ -80,9 +80,11 @@ public void mineBombPlacementEvent( BlockPlaceEvent event ) { if ( bombName != null ) { - MineBombData mineBomb = MineBombs.getInstance().findBombByName(bombName); - Player player = event.getPlayer(); + SpigotPlayer sPlayer = new SpigotPlayer( player ); + + MineBombData mineBomb = MineBombs.getInstance().findBombByName( sPlayer, bombName ); + PrisonNBTUtil.setNBTString(iStack, MineBombs.MINE_BOMBS_NBT_KEY, @@ -135,118 +137,130 @@ public void mineBombThrowEvent( PlayerInteractEvent event ) { // it's a mine bomb so no other listener should handle it. event.setCancelled( true ); - MineBombData mineBomb = MineBombs.getInstance().findBombByName(bombName); - Player player = event.getPlayer(); - final SpigotPlayer sPlayer = new SpigotPlayer( player ); - - EquipmentSlot hand = SpigotCompatibility.getInstance().getHand(event); - - PrisonNBTUtil.setNBTString(iStack, - MineBombs.MINE_BOMBS_NBT_KEY, - bombName ); - PrisonNBTUtil.setNBTString(iStack, - MineBombs.MINE_BOMBS_NBT_THROWER_UUID, - player.getUniqueId().toString() ); - - SpigotLocation loc = new SpigotLocation( + SpigotPlayer sPlayer = new SpigotPlayer( player ); + + // If the player is on a mine bomb cooldown, then mineBomb will be null: + MineBombData mineBomb = MineBombs.getInstance().findBombByName( sPlayer, bombName ); + + if ( mineBomb != null ) { + + EquipmentSlot hand = SpigotCompatibility.getInstance().getHand(event); + + PrisonNBTUtil.setNBTString(iStack, + MineBombs.MINE_BOMBS_NBT_KEY, + bombName ); + PrisonNBTUtil.setNBTString(iStack, + MineBombs.MINE_BOMBS_NBT_THROWER_UUID, + player.getUniqueId().toString() ); + + SpigotLocation loc = new SpigotLocation( player.getEyeLocation().add( player.getLocation().getDirection() )); - + // XMaterial xMat = XMaterial.matchXMaterial(iStack); + + + ArmorStand armorStand = player.getWorld().spawn( + loc.getBukkitLocation(), + ArmorStand.class); + + armorStand.setVisible( false ); + armorStand.setItemInHand( iStack ); + + + SpigotArmorStand sArmorStand = new SpigotArmorStand(armorStand); + sArmorStand.setNbtString( MineBombs.MINE_BOMBS_NBT_KEY, bombName ); + sArmorStand.setNbtString( MineBombs.MINE_BOMBS_NBT_THROWER_UUID, + player.getUniqueId().toString() ); + + + Vector velocity = player.getLocation().getDirection().multiply( + mineBomb.getThrowVelocity() ); + + armorStand.setVelocity( velocity ); + + armorStand.setRemoveWhenFarAway(false); + + + + + // Remove the unused armorStand in 120 seconds: + final int taskId = SpigotPrison.getInstance().getScheduler() + .runTaskLater( + new Runnable() { + public void run() { + armorStand.remove(); + } + }, 120 * 20); + + + // Run the following every tick to detect when the armor stand has + // come to rest for 4 ticks, then trigger the animation. + final SpigotArmorStand aStnd = sArmorStand; + + + // Save the taskId so this task can be canceled: + mineBomb.setTaskId( + SpigotPrison.getInstance().getScheduler() + .runTaskTimer( + new Runnable() { + private List locs = new ArrayList<>(); + + public void run() { + Location loc = aStnd.getLocation(); + locs.add(loc); + + if ( locs.size() > 4 ) { + locs.remove(0); + } + + if ( locs.size() == 4 ) { + if ( locs.get(0).equals(locs.get(1)) && + locs.get(1).equals(locs.get(2)) && + locs.get(2).equals(locs.get(3)) + ) { + + + // Cancel this task: + SpigotPrison.getInstance().getScheduler().cancelTask( mineBomb.getTask() ); + + // Cancel the cancellation task: + SpigotPrison.getInstance().getScheduler().cancelTask(taskId); + + + // remove armor stand: + aStnd.remove(); + + // Start mine bomb animation: + loc.setY( loc.getY() - 1); + SpigotBlock targetBlock = (SpigotBlock) loc.getBlockAt(); + + Mine mine = getMine(sPlayer, mineBomb, targetBlock ); + + if ( mine != null ) { + // It landed within a mine... subtract one from the player's inventory, + // if it's used up, then remove from the inventory: +// iStack.setAmount( iStack.getAmount() - 1); +// if ( iStack.getAmount() == 0 ) { +// player.getInventory().removeItem( iStack ); +// } + + processBombTriggerEvent( sPlayer, mine, mineBomb, targetBlock, hand ); + } + + } + } + } + + }, 2, 1)); + } + else { + int cooldownTicks = MineBombs.checkPlayerCooldown(sPlayer); + + getPrisonUtilsMineBombs().mineBombsCoolDownMsg( sPlayer, cooldownTicks ); + } - - ArmorStand armorStand = player.getWorld().spawn( - loc.getBukkitLocation(), - ArmorStand.class); - - armorStand.setVisible( false ); - armorStand.setItemInHand( iStack ); - - - SpigotArmorStand sArmorStand = new SpigotArmorStand(armorStand); - sArmorStand.setNbtString( MineBombs.MINE_BOMBS_NBT_KEY, bombName ); - sArmorStand.setNbtString( MineBombs.MINE_BOMBS_NBT_THROWER_UUID, - player.getUniqueId().toString() ); - - - Vector velocity = player.getLocation().getDirection().multiply( - mineBomb.getThrowVelocity() ); - - armorStand.setVelocity( velocity ); - - armorStand.setRemoveWhenFarAway(false); - - - - - // Remove the unused armorStand in 120 seconds: - final int taskId = SpigotPrison.getInstance().getScheduler() - .runTaskLater( - new Runnable() { - public void run() { - armorStand.remove(); - } - }, 120 * 20); - - // Run the following every tick to detect when the armor stand has - // come to rest for 4 ticks, then trigger the animation. - final SpigotArmorStand aStnd = sArmorStand; - - // Save the taskId so this task can be canceled: - mineBomb.setTaskId( - SpigotPrison.getInstance().getScheduler() - .runTaskTimer( - new Runnable() { - private List locs = new ArrayList<>(); - - public void run() { - Location loc = aStnd.getLocation(); - locs.add(loc); - - if ( locs.size() > 4 ) { - locs.remove(0); - } - - if ( locs.size() == 4 ) { - if ( locs.get(0).equals(locs.get(1)) && - locs.get(1).equals(locs.get(2)) && - locs.get(2).equals(locs.get(3)) - ) { - - - // Cancel this task: - SpigotPrison.getInstance().getScheduler().cancelTask( mineBomb.getTask() ); - - // Cancel the cancellation task: - SpigotPrison.getInstance().getScheduler().cancelTask(taskId); - - - // remove armor stand: - aStnd.remove(); - - // Start mine bomb animation: - loc.setY( loc.getY() - 1); - SpigotBlock targetBlock = (SpigotBlock) loc.getBlockAt(); - - Mine mine = getMine(sPlayer, mineBomb, targetBlock ); - - if ( mine != null ) { - // It landed within a mine... subtract one from the player's inventory, - // if it's used up, then remove from the inventory: - iStack.setAmount( iStack.getAmount() - 1); - if ( iStack.getAmount() == 0 ) { - player.getInventory().removeItem( iStack ); - } - - processBombTriggerEvent( sPlayer, mine, mineBomb, targetBlock, hand ); - } - - } - } - } - - }, 2, 1)); @@ -442,26 +456,34 @@ public void bombPlacementEvent( PlayerInteractEvent event ) { if ( bombName != null ) { - MineBombData mineBomb = MineBombs.getInstance().findBombByName(bombName); + // We do not know if the bomb will be in a mine, but we know + // it's a mine bomb so no other listener should handle it. + event.setCancelled( true ); Player player = event.getPlayer(); - - //String ownerUUID = PrisonNBTUtil.getNBTString( iStack, MineBombs.MINE_BOMBS_NBT_OWNER_UUID ); - - Block targetBlock = event.getClickedBlock(); - - EquipmentSlot hand = SpigotCompatibility.getInstance().getHand(event); - - boolean canceled = processBombTriggerEvent( player, mineBomb, - targetBlock, hand ); - - if ( canceled ) { - event.setCancelled( canceled ); + SpigotPlayer sPlayer = new SpigotPlayer( player ); + + // If the player is on a mine bomb cooldown, then mineBomb will be null: + MineBombData mineBomb = MineBombs.getInstance().findBombByName( sPlayer, bombName); + + if ( mineBomb != null ) { + + //String ownerUUID = PrisonNBTUtil.getNBTString( iStack, MineBombs.MINE_BOMBS_NBT_OWNER_UUID ); + + Block targetBlock = event.getClickedBlock(); + + EquipmentSlot hand = SpigotCompatibility.getInstance().getHand(event); + + processBombTriggerEvent( player, mineBomb, targetBlock, hand ); + + } + else { + int cooldownTicks = MineBombs.checkPlayerCooldown(sPlayer); + + getPrisonUtilsMineBombs().mineBombsCoolDownMsg( sPlayer, cooldownTicks ); } - } - } } 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 5fd94f521..1cde4ab13 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 @@ -786,7 +786,7 @@ public void utilsMineBombsGive( CommandSender sender, MineBombs mBombs = MineBombs.getInstance(); - MineBombData bomb = mBombs.findBombByName(bombName); + MineBombData bomb = mBombs.findBombByName( player, bombName); // // Remove color codes from bomb's name for matching: // bombName = Text.stripColor( bombName ); @@ -1033,18 +1033,21 @@ public MineBombData getBombItem( Player player ) { String bombName = itemInHand.getNBTString( MineBombs.MINE_BOMBS_NBT_KEY ); - bomb = getBombItem( bombName ); + SpigotPlayer sPlayer = new SpigotPlayer( player ); + + bomb = MineBombs.getInstance().findBombByName( sPlayer, bombName ); +// bomb = getBombItem( bombName ); } return bomb; } - public MineBombData getBombItem( String bombName ) { - - MineBombData bomb = MineBombs.getInstance().findBombByName( bombName ); - - return bomb; - } +// public MineBombData getBombItem( tech.mcprison.prison.internal.Player player, String bombName ) { +// +// MineBombData bomb = MineBombs.getInstance().findBombByName( player, bombName ); +// +// return bomb; +// } /** *

This takes a player and checks their main hand to see if it contains a bomb. @@ -1111,16 +1114,19 @@ else if ( bomb != null ) { // SpigotPlayer sPlayer = new SpigotPlayer( player ); - String playerUUID = sPlayer.getUniqueId().toString(); +// String playerUUID = sPlayer.getUniqueId().toString(); // String playerUUID = player.getUniqueId().toString(); - int cooldownTicks = checkPlayerCooldown( playerUUID ); + +// int cooldownTicks = MineBombs.checkPlayerCooldown( sPlayer ); - if ( cooldownTicks == 0 ) { +// if ( cooldownTicks <= 0 ) + { + // NOTE: cooldown is set when using MineBombs.findBombByName(); // Set cooldown: - addPlayerCooldown( playerUUID, bomb.getCooldownTicks() ); +// MineBombs.addPlayerCooldown( sPlayer, bomb.getCooldownTicks() ); SpigotItemStack bombs = new SpigotItemStack( getItemStackBomb( bomb, sPlayer )); @@ -1292,19 +1298,11 @@ public void runDetonation() { } } - else { - - mineBombsCoolDownMsg( sPlayer, cooldownTicks ); - -// float cooldownSeconds = cooldownTicks / 20.0f; -// DecimalFormat dFmt = Prison.get().getDecimalFormat( "0.0" ); +// else { // -// String message = -// String.format( "You cannot use another Prison Mine Bomb for %s seconds.", -// dFmt.format( cooldownSeconds ) ); -// sPlayer.sendMessage( message ); - - } +// mineBombsCoolDownMsg( sPlayer, cooldownTicks ); +// +// } } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTasks.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTasks.java index fb6c2936d..82ce8a139 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTasks.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTasks.java @@ -2,9 +2,7 @@ import java.util.ArrayList; import java.util.List; -import java.util.Map; import java.util.Random; -import java.util.TreeMap; import org.bukkit.Bukkit; import org.bukkit.Effect; @@ -35,8 +33,6 @@ public class PrisonUtilsMineBombsTasks extends PrisonUtils { - public static final Map playerCooldowns = new TreeMap<>(); - public PrisonUtilsMineBombsTasks() { super(); @@ -85,67 +81,67 @@ protected void setDigSpeed( SpigotItemStack itemInHand, int digSpeedLevel ) { // return addPlayerCooldown( playerUUID, MINE_BOMBS_COOLDOWN_TICKS ); // } - /** - *

- * If a cooldown is not setup for the player, this will try to add one and - * will return a value of true to indicate the a cooldown was set. If a - * cooldown already exists, then this will return a value of false. - *

- * - * @param playerUUID - * @param ticks - * @return - */ - public boolean addPlayerCooldown( String playerUUID, int ticks ) - { - boolean results = false; - - if ( !playerCooldowns.containsKey( playerUUID ) || playerCooldowns.get( playerUUID ) <= 0 ) - { - - playerCooldowns.put( playerUUID, ticks ); - - new BukkitRunnable() - { - - @Override - public void run() - { - - Integer cooldownTicks = playerCooldowns.get( playerUUID ); - - int ticksRemaining = cooldownTicks == null ? 0 : cooldownTicks - 10; - - if ( ticksRemaining <= 0 ) - { - playerCooldowns.remove( playerUUID ); - this.cancel(); - } - else - { - playerCooldowns.put( playerUUID, ticksRemaining ); - } - - } - }.runTaskTimer( SpigotPrison.getInstance(), 10, 10 ); - - results = true; - } - - return results; - } - - public static int checkPlayerCooldown( String playerUUID ) - { - int results = 0; - - if ( playerCooldowns.containsKey( playerUUID ) ) - { - results = playerCooldowns.get( playerUUID ); - } - - return results; - } +// /** +// *

+// * If a cooldown is not setup for the player, this will try to add one and +// * will return a value of true to indicate the a cooldown was set. If a +// * cooldown already exists, then this will return a value of false. +// *

+// * +// * @param playerUUID +// * @param ticks +// * @return +// */ +// public boolean addPlayerCooldown( String playerUUID, int ticks ) +// { +// boolean results = false; +// +// if ( !playerCooldowns.containsKey( playerUUID ) || playerCooldowns.get( playerUUID ) <= 0 ) +// { +// +// playerCooldowns.put( playerUUID, ticks ); +// +// new BukkitRunnable() +// { +// +// @Override +// public void run() +// { +// +// Integer cooldownTicks = playerCooldowns.get( playerUUID ); +// +// int ticksRemaining = cooldownTicks == null ? 0 : cooldownTicks - 10; +// +// if ( ticksRemaining <= 0 ) +// { +// playerCooldowns.remove( playerUUID ); +// this.cancel(); +// } +// else +// { +// playerCooldowns.put( playerUUID, ticksRemaining ); +// } +// +// } +// }.runTaskTimer( SpigotPrison.getInstance(), 10, 10 ); +// +// results = true; +// } +// +// return results; +// } +// +// public static int checkPlayerCooldown( String playerUUID ) +// { +// int results = 0; +// +// if ( playerCooldowns.containsKey( playerUUID ) ) +// { +// results = playerCooldowns.get( playerUUID ); +// } +// +// return results; +// } public void submitBombEffects( MineBombData bomb, EffectState effectState, Location location ) { From d3b4faf5c21fdda9c45d0c2eed55e762b2016b7f Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 11 Jul 2024 22:54:39 -0400 Subject: [PATCH 080/323] Prison backups: updated some of the help text. --- docs/changelog_v3.3.x.md | 10 +++++++++- .../main/java/tech/mcprison/prison/PrisonCommand.java | 9 +++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 68aee4d71..96f853cea 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,15 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-beta.18c 2024-07-09 +# 3.3.0-beta.18c 2024-07-11 + + +* **Prison backups: updated some of the help text.** + + +* **Mine Bombs: cooldowns.** +Changed the cooldown handling by moving it to the mine bomb's core and created its own task to run to monitor it. +Fixed issue with the older version of cooldowns not working properly with throwing the mine bombs. * **3.3.0-beta.18c Beta release - Please read!!** 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 d012f5d9d..441e7cab1 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java +++ b/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java @@ -2107,7 +2107,9 @@ public void supportListenersDump(CommandSender sender, description = "This will make a backup of all Prison settings by creating a new " + "zip file which will be stored in the directory plugins/Prison/backups. " + "After creating the backup, this will delete all temp files, backup files, etc.. " + - "since they will be included in the backup.", + "since they will be included in the backup. This command will backup everything " + + "under 'plugins/Prison/' except for the directory 'plugins/Prison/backups/'. " + + "The backups will be placed in the directory 'plugins/Prison/backups/'.", onlyPlayers = false, permissions = "prison.debug" ) public void supportBackupPrison( CommandSender sender, @@ -2127,7 +2129,10 @@ public void supportBackupPrison( CommandSender sender, @Command(identifier = "prison support backup logs", description = "This will list Prison backup logs that are in the file " - + "`plugins/Prison/backup/versions.log`", + + "`plugins/Prison/backup/versions.log` The contents of the backup " + + "logs will be displayed in the console if this command is ran in the " + + "console. This command should not be ran ingame due to the amount of " + + "data and the width of the data. ", onlyPlayers = false, permissions = "prison.debug" ) public void supportBackupList( CommandSender sender ) { From 16db5d8c804512869baf9c5930a762cc259f8687 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 11 Jul 2024 22:57:06 -0400 Subject: [PATCH 081/323] Prison commands: Added support for new global placeholders: '{ifPerm:}' and '{ifNotPer:}'. --- docs/changelog_v3.3.x.md | 3 +++ .../prison/tasks/PrisonCommandTaskData.java | 25 ++++++++++++++++--- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 96f853cea..7cc3815c4 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-beta.18c 2024-07-11 +* **Prison commands: Added support for new global placeholders: '{ifPerm:}' and '{ifNotPer:}'.** More adjustments. + + * **Prison backups: updated some of the help text.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonCommandTaskData.java b/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonCommandTaskData.java index a7522b66d..933545589 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonCommandTaskData.java +++ b/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonCommandTaskData.java @@ -110,10 +110,12 @@ public enum CustomPlaceholders { ifPerm(CommandEnvironment.all_commands, "{ifPerm:} Continues executing commands in the chain if " - + "the player has the perm ''."), + + "the player has the perm ''.", + "ifPerm:" ), ifNotPerm(CommandEnvironment.all_commands, "{ifNotPerm:} Stops executing commands in the chain if " - + "the player has the perm ''."), + + "the player has the perm ''.", + "ifNotPerm:" ), firstJoin(CommandEnvironment.rank_commands, @@ -211,14 +213,23 @@ public enum CustomPlaceholders { private final CommandEnvironment environment; private final String description; + private final String exampleUsage; private CustomPlaceholders( CommandEnvironment environment ) { this.environment = environment; this.description = null; + this.exampleUsage = null; } private CustomPlaceholders( CommandEnvironment environment, String description ) { this.environment = environment; this.description = description; + this.exampleUsage = null; + } + private CustomPlaceholders( CommandEnvironment environment, String description, + String exampleUsage ) { + this.environment = environment; + this.description = description; + this.exampleUsage = exampleUsage; } public static String listPlaceholders( CommandEnvironment environment ) { @@ -248,7 +259,11 @@ public static String listPlaceholders( CommandEnvironment environment ) { * @return */ public String getPlaceholder() { - return "{" + name() + "}"; + return "{" + + ( getExampleUsage() != null ? + getExampleUsage() : + name() ) + + "}"; } public CommandEnvironment getEnvironment() { @@ -258,6 +273,10 @@ public CommandEnvironment getEnvironment() { public String getDescription() { return description; } + + public String getExampleUsage() { + return exampleUsage; + } } From 39ff3802ba3734aeae55e33f7ca0e110ece908b9 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 12 Jul 2024 03:29:44 -0400 Subject: [PATCH 082/323] Entity ArmorStands: ArmorStands are now able to spawn as invisible. Before this change you could see an armor stand appear for a fraction of a second before the invisibility kicked in. Now armor stands are being spawned elsewhere, set to invisible, then teleported to the intended location. At the point of teleportation, they would be invisible. --- .../java/tech/mcprison/prison/internal/World.java | 3 +++ .../test/java/tech/mcprison/prison/TestWorld.java | 4 ++++ .../mcprison/prison/spigot/game/SpigotWorld.java | 15 +++++++++++++-- .../spigot/game/entity/SpigotArmorStand.java | 5 ++++- 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/World.java b/prison-core/src/main/java/tech/mcprison/prison/internal/World.java index 00dece793..ca8b31344 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/World.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/World.java @@ -88,5 +88,8 @@ public void setBlocksSynchronously( List tBlocks, public ArmorStand spawnArmorStand( Location location ); + + public int getMaxHeight(); + } diff --git a/prison-core/src/test/java/tech/mcprison/prison/TestWorld.java b/prison-core/src/test/java/tech/mcprison/prison/TestWorld.java index 0be5d85e3..29b8981d5 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/TestWorld.java +++ b/prison-core/src/test/java/tech/mcprison/prison/TestWorld.java @@ -95,5 +95,9 @@ public ArmorStand spawnArmorStand(Location location) { return null; } + @Override + public int getMaxHeight() { + return 125; + } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotWorld.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotWorld.java index 6f55b4867..aba9d6b88 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotWorld.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotWorld.java @@ -284,12 +284,21 @@ public Entity spawnEntity( Location location, EntityType entityType) { @Override public ArmorStand spawnArmorStand( Location location ) { - Entity e = spawnEntity( location, SpigotEntityType.ENTITY_TYPE_ARMOR_STAND ); + + int maxHight = location.getWorld().getMaxHeight(); + + Location spawnPoint = new Location( location ); + spawnPoint.setY(maxHight); + + Entity e = spawnEntity( spawnPoint, SpigotEntityType.ENTITY_TYPE_ARMOR_STAND ); SpigotEntity sEntity = (SpigotEntity) e; org.bukkit.entity.ArmorStand armorStand = (org.bukkit.entity.ArmorStand) sEntity.getBukkitEntity(); + armorStand.setVisible(false); SpigotArmorStand sArmorStand = new SpigotArmorStand( armorStand ); + sArmorStand.teleport(location); + return sArmorStand; } @@ -309,6 +318,8 @@ public static SpigotWorld getWorld(String worldName) { } - + public int getMaxHeight() { + return getWrapper().getMaxHeight(); + } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotArmorStand.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotArmorStand.java index 8c4d94196..5a4a4e57f 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotArmorStand.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotArmorStand.java @@ -15,6 +15,8 @@ public class SpigotArmorStand public SpigotArmorStand( org.bukkit.entity.ArmorStand bArmorStand ) { super( bArmorStand ); + bArmorStand.setVisible( false ); + this.bArmorStand = bArmorStand; } @@ -29,11 +31,12 @@ public SpigotArmorStand( org.bukkit.entity.ArmorStand bArmorStand ) { // } public SpigotArmorStand(Entity entity) { - super( ((SpigotEntity) entity).getBukkitEntity() ); + this( (org.bukkit.entity.ArmorStand) ((SpigotEntity) entity).getBukkitEntity() ); org.bukkit.entity.Entity bEntity = ((SpigotEntity) entity).getBukkitEntity(); if ( bEntity instanceof org.bukkit.entity.ArmorStand ) { this.bArmorStand = (org.bukkit.entity.ArmorStand) bEntity; + this.bArmorStand.setVisible( false ); } } From 30c59ac1d6711d58097a056eb1740878738a6676 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 12 Jul 2024 03:31:35 -0400 Subject: [PATCH 083/323] Prison command placeholders: Updated the new placeholders for "ifPerm:" and "ifNotPerm" are now working properly. --- docs/changelog_v3.3.x.md | 10 ++++++++- .../prison/tasks/PrisonCommandTaskData.java | 4 ++-- .../tasks/PrisonDispatchCommandTask.java | 22 +++++++++++++++++++ 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 7cc3815c4..7f04693c1 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,15 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-beta.18c 2024-07-11 +# 3.3.0-beta.18c 2024-07-12 + + +* **Prison command placeholders: Updated the new placeholders for "ifPerm:" and "ifNotPerm" are now working properly.** + + +* **Entity ArmorStands: ArmorStands are now able to spawn as invisible.** +Before this change you could see an armor stand appear for a fraction of a second before the invisibility kicked in. +Now armor stands are being spawned elsewhere, set to invisible, then teleported to the intended location. At the point of teleportation, they would be invisible. * **Prison commands: Added support for new global placeholders: '{ifPerm:}' and '{ifNotPer:}'.** More adjustments. diff --git a/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonCommandTaskData.java b/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonCommandTaskData.java index 933545589..44d7f0bff 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonCommandTaskData.java +++ b/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonCommandTaskData.java @@ -464,7 +464,7 @@ public void runTask( Player player ) { // If the task is '{ifPerm:}' then the player must have the perm to // continue: if ( task.toLowerCase().startsWith( "{ifperm:" ) ) { - String perm = task.substring( 7, task.length() - 1 ); + String perm = task.substring( 8, task.length() - 1 ); boolean hasPerm = player.hasPermission( perm ); @@ -473,7 +473,7 @@ public void runTask( Player player ) { } } if ( task.toLowerCase().startsWith( "{ifnotperm:" ) ) { - String perm = task.substring( 10, task.length() - 1 ); + String perm = task.substring( 11, task.length() - 1 ); boolean hasPerm = player.hasPermission( perm ); diff --git a/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonDispatchCommandTask.java b/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonDispatchCommandTask.java index f041c6c12..6d67c3b34 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonDispatchCommandTask.java +++ b/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonDispatchCommandTask.java @@ -44,6 +44,27 @@ public void run() { long start = System.nanoTime(); + // If the task is '{ifPerm:}' then the player must have the perm to + // continue: + if ( task.toLowerCase().startsWith( "{ifperm:" ) ) { + String perm = task.substring( 8, task.length() - 1 ); + + boolean hasPerm = player.hasPermission( perm ); + + if ( !hasPerm ) { + break; + } + } + if ( task.toLowerCase().startsWith( "{ifnotperm:" ) ) { + String perm = task.substring( 11, task.length() - 1 ); + + boolean hasPerm = player.hasPermission( perm ); + + if ( hasPerm ) { + break; + } + } + // Apply the custom placeholders: for ( PrisonCommandTaskPlaceholderData cPlaceholder : getCustomPlaceholders() ) { if ( cPlaceholder.contains( task ) ) { @@ -52,6 +73,7 @@ public void run() { } try { + if ( playerTask && player != null ) { // double start = System.currentTimeMillis(); From 1dc9cdcc282ea69de88d6f13b506d7951a1309e1 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 17 Jul 2024 03:54:04 -0400 Subject: [PATCH 084/323] Mine Bombs: Geometric shapes and functions. --- docs/changelog_v3.3.x.md | 6 +- .../prison}/bombs/GeometricShapes.java | 64 +++++++++- .../mcprison/prison/internal/EulerAngle.java | 117 +++++++++++++++--- .../prison/internal/EulerAngleTest.java | 24 ++++ 4 files changed, 194 insertions(+), 17 deletions(-) rename {prison-spigot/src/main/java/tech/mcprison/prison/spigot => prison-core/src/main/java/tech/mcprison/prison}/bombs/GeometricShapes.java (86%) create mode 100644 prison-core/src/test/java/tech/mcprison/prison/internal/EulerAngleTest.java diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 7f04693c1..d99069e66 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-beta.18c 2024-07-12 +# 3.3.0-beta.18c 2024-07-17 + + + +* **Mine Bombs: Geometric shapes and functions.** * **Prison command placeholders: Updated the new placeholders for "ifPerm:" and "ifNotPerm" are now working properly.** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/bombs/GeometricShapes.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/GeometricShapes.java similarity index 86% rename from prison-spigot/src/main/java/tech/mcprison/prison/spigot/bombs/GeometricShapes.java rename to prison-core/src/main/java/tech/mcprison/prison/bombs/GeometricShapes.java index c19bf203f..c0bb4768f 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/bombs/GeometricShapes.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/GeometricShapes.java @@ -1,7 +1,8 @@ -package tech.mcprison.prison.spigot.bombs; +package tech.mcprison.prison.bombs; import tech.mcprison.prison.internal.World; import tech.mcprison.prison.internal.block.PrisonBlock; +import tech.mcprison.prison.util.Vector; /** *

These functions were basically copied from the following post. They have @@ -231,6 +232,67 @@ public static void drawTorus( PrisonBlock block, World world, int xi, int yi, in } } + +// public class Point { +// private double x; +// private double y; +// private double z; +// public Point( double x, double y, double z ) { +// this.x = x; +// this.y = y; +// this.z = z; +// } +// public double getX() { +// return x; +// } +// public void setX(double x) { +// this.x = x; +// } +// public double getY() { +// return y; +// } +// public void setY(double y) { +// this.y = y; +// } +// public double getZ() { +// return z; +// } +// public void setZ(double z) { +// this.z = z; +// } +// } + + public static Vector getPointsOnCircleXZ( double degrees, double radius ) { + Vector results = null; + + final double angle = Math.toRadians( degrees ); + + double x = (Math.cos(angle) * radius); + double y = 0d; + double z = (Math.sin(angle) * radius); + + results = new Vector( x, y, z ); + + return results; + + +// final int NUM_POINTS = 1000; +// final double RADIUS = 100d; +// +// final Point[] points = new Point[NUM_POINTS]; +// +// for (int i = 0; i < NUM_POINTS; ++i) +// { +// final double angle = Math.toRadians(((double) i / NUM_POINTS) * 360d); +// +// points[i] = new Point( +// Math.cos(angle) * RADIUS, +// Math.sin(angle) * RADIUS +// ); +// } + + } + // public void someMethod() // { // { diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/EulerAngle.java b/prison-core/src/main/java/tech/mcprison/prison/internal/EulerAngle.java index 321b404d3..e974096fe 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/EulerAngle.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/EulerAngle.java @@ -1,5 +1,7 @@ package tech.mcprison.prison.internal; +import java.text.DecimalFormat; + public class EulerAngle { private double x; @@ -14,6 +16,17 @@ public EulerAngle( double x, double y, double z ) { this.z = z; } + public String toString() { + DecimalFormat dFmt = new DecimalFormat( "#,##0.0000" ); + String fmt = String.format( + "EulerAngle: x: %s y: %s z: %s", + dFmt.format( getX() ), + dFmt.format( getY() ), + dFmt.format( getZ() ) + ); + return fmt; + } + public EulerAngle add( double x, double y, double z ) { EulerAngle ea = new EulerAngle( x + getX(), y + getY(), z + getZ() ); return ea; @@ -25,15 +38,75 @@ public EulerAngle subtract( double x, double y, double z ) { } - public double getX() { - return x; - } - public double getY() { - return y; - } - public double getZ() { - return z; - } + /** + * NOTE: These do not work. Not sure what the angle should be, or what + * the starting angles should be, but it goes to zero pretty quickly. + * So do not use these functions. + * + * + * The rotateAroundAxis is based upon the following post, reply number 11: + * https://www.spigotmc.org/threads/how-to-calculate-armorstand-arm-tip-location.331825/#post-3284591 + * + * @param angle + * @return + */ + public EulerAngle rotateAroundAxisX( double angle ) { + EulerAngle ea = rotateAroundAxisX( getX(), getY(), getZ(), angle ); + + setX( ea.getX() ); + setY( ea.getY() ); + setZ( ea.getZ() ); + + return this; + } + + public static EulerAngle rotateAroundAxisX( double x, double y, double z, double angle ) { + double cos = Math.cos(angle); + double sin = Math.sin(angle); + y = y * cos - z * sin; + z = y * sin + z * cos; + return new EulerAngle( x, y, z ); + } + + public EulerAngle rotateAroundAxisY( double angle ) { + EulerAngle ea = rotateAroundAxisY( getX(), getY(), getZ(), angle ); + + setX( ea.getX() ); + setY( ea.getY() ); + setZ( ea.getZ() ); + +// Output.get().logInfo( toString() + " angle: " + angle ); + + return this; + } + + public static EulerAngle rotateAroundAxisY( double x, double y, double z, double angle ) { + angle = -angle; + double cos = Math.cos(angle); + double sin = Math.sin(angle); + x = x * cos + z * sin; + z = x * -sin + z * cos; + return new EulerAngle( x, y, z ); + } + + public EulerAngle rotateAroundAxisZ( double angle ) { + EulerAngle ea = rotateAroundAxisZ( getX(), getY(), getZ(), angle ); + + setX( ea.getX() ); + setY( ea.getY() ); + setZ( ea.getZ() ); + + return this; + } + + public EulerAngle rotateAroundAxisZ( double x, double y, double z, double angle ) { + double cos = Math.cos(angle); + double sin = Math.sin(angle); + x = x * cos - y * sin; + y = x * sin + y * cos; + return new EulerAngle( x, y, z ); + } + /** * https://math.oxford.emory.edu/site/cs171/generatingHashCodes/ @@ -47,17 +120,31 @@ public int hashCode() { return h; } + public double getX() { + return x; + } public EulerAngle setX( double x ) { - EulerAngle ea = new EulerAngle( x, getY(), getZ() ); - return ea; + this.x = x; +// EulerAngle ea = new EulerAngle( x, getY(), getZ() ); + return this; + } + + public double getY() { + return y; } public EulerAngle setY( double y ) { - EulerAngle ea = new EulerAngle( getX(), y, getZ() ); - return ea; + this.y = y; +// EulerAngle ea = new EulerAngle( getX(), y, getZ() ); + return this; + } + + public double getZ() { + return z; } public EulerAngle setZ( double z ) { - EulerAngle ea = new EulerAngle( getX() , getY(), z ); - return ea; + this.z = z; +// EulerAngle ea = new EulerAngle( getX() , getY(), z ); + return this; } diff --git a/prison-core/src/test/java/tech/mcprison/prison/internal/EulerAngleTest.java b/prison-core/src/test/java/tech/mcprison/prison/internal/EulerAngleTest.java new file mode 100644 index 000000000..9bcd5a2cf --- /dev/null +++ b/prison-core/src/test/java/tech/mcprison/prison/internal/EulerAngleTest.java @@ -0,0 +1,24 @@ +package tech.mcprison.prison.internal; + +import org.junit.Test; + +public class EulerAngleTest { + + @Test + public void test() { + + // Have no idea what the starting values should be, which 0,0,0 should work, + // but they don't. + // Also not sure what angle is expected, such as degrees or radians. + EulerAngle ea = new EulerAngle( 1, 1, 1 ); + + for ( double angle = -10; angle <= 10; angle += 0.5 ) { + ea.rotateAroundAxisX( angle ); + +// System.out.println( ea.toString() + " angle: " + angle ); + } + +// fail("Not yet implemented"); + } + +} From fc32d179a6055fa6cae94dd980ba61a0449fd103 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 17 Jul 2024 03:58:28 -0400 Subject: [PATCH 085/323] Mine Bombs: Update to a lot of the core support for ItemStacks, World, Location, and ArmorStand. These enhancements are to help support moving mine bomb animations back to core. --- docs/changelog_v3.3.x.md | 3 + .../mcprison/prison/internal/ArmorStand.java | 15 ++- .../mcprison/prison/internal/ItemStack.java | 10 ++ .../tech/mcprison/prison/internal/World.java | 3 + .../tech/mcprison/prison/util/Location.java | 7 ++ .../java/tech/mcprison/prison/TestWorld.java | 7 ++ .../prison/spigot/block/SpigotItemStack.java | 30 +++++ .../prison/spigot/game/SpigotLocation.java | 29 ++++- .../prison/spigot/game/SpigotWorld.java | 103 ++++++++++++++++-- .../spigot/game/entity/SpigotArmorStand.java | 97 ++++++++++++++++- 10 files changed, 281 insertions(+), 23 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index d99069e66..cdcd16694 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-beta.18c 2024-07-17 +* **Mine Bombs: Update to a lot of the core support for ItemStacks, World, Location, and ArmorStand.** +These enhancements are to help support moving mine bomb animations back to core. + * **Mine Bombs: Geometric shapes and functions.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/ArmorStand.java b/prison-core/src/main/java/tech/mcprison/prison/internal/ArmorStand.java index 6e24cf080..3121af02c 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/ArmorStand.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/ArmorStand.java @@ -6,9 +6,10 @@ public interface ArmorStand //public ArmorStand spawn(Location location); +// public void setupArmorStand(String itemType); +// public void setupArmorStand( ItemStack item ); public boolean isVisible(); - public void setVisible( boolean visible ); public boolean getRemoveWhenFarAway(); @@ -25,6 +26,14 @@ public interface ArmorStand public boolean hasGravity(); public void setGravity( boolean gravity ); - - + + public boolean hasArms(); + public void setArms( boolean arms ); + + public boolean hasBasePlate(); + public void setBasePlate( boolean basePlate ); + + public boolean getCanPickupItems(); + public void setCanPickupItems( boolean canPickupItems ); + } diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/ItemStack.java b/prison-core/src/main/java/tech/mcprison/prison/internal/ItemStack.java index c49d47b4b..4dca23666 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/ItemStack.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/ItemStack.java @@ -42,6 +42,9 @@ public class ItemStack { // private Map enchantments; + /** + * Do not use this constructor, it is for unit testing. + */ protected ItemStack() { super(); @@ -63,6 +66,13 @@ public ItemStack(int amount, PrisonBlock material, String... lore) { this.lore = new ArrayList<>(Arrays.asList(lore)); } + public ItemStack( ItemStack iStack ) { + this.displayName = iStack.getDisplayName(); + this.amount = iStack.getAmount(); + this.material = iStack.getMaterial().clone(); + this.lore = new ArrayList<>( iStack.getLore() ); + } + /** * Returns the name of the item stack, derived from its BlockType name. */ diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/World.java b/prison-core/src/main/java/tech/mcprison/prison/internal/World.java index ca8b31344..cd8dc249e 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/World.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/World.java @@ -89,6 +89,9 @@ public void setBlocksSynchronously( List tBlocks, public ArmorStand spawnArmorStand( Location location ); + public ArmorStand spawnArmorStand(Location location, String itemType, + String customName, String nbtKey, String nbtValue); + public int getMaxHeight(); 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 5aed5fb54..8c01203f1 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 @@ -303,6 +303,13 @@ public ArmorStand spawnArmorStand() { return getWorld().spawnArmorStand( this ); } + public ArmorStand spawnArmorStand( String itemName, String name, + String nbtKey, + String nbtValue ) { + + return getWorld().spawnArmorStand( this, itemName, name, nbtKey, nbtValue ); + } + } diff --git a/prison-core/src/test/java/tech/mcprison/prison/TestWorld.java b/prison-core/src/test/java/tech/mcprison/prison/TestWorld.java index 29b8981d5..636c9523c 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/TestWorld.java +++ b/prison-core/src/test/java/tech/mcprison/prison/TestWorld.java @@ -100,4 +100,11 @@ public int getMaxHeight() { return 125; } + @Override + public ArmorStand spawnArmorStand(Location location, String itemType, + String customName, String nbtKey, + String nbtValue) { + return null; + } + } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/SpigotItemStack.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/SpigotItemStack.java index cca87d259..69b452177 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/SpigotItemStack.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/SpigotItemStack.java @@ -147,6 +147,36 @@ public SpigotItemStack(int amount, PrisonBlock material, String... lore) { } + + public SpigotItemStack( ItemStack iStack) { + super( iStack ); + + org.bukkit.inventory.ItemStack bStack = + ( iStack instanceof SpigotItemStack ? + ((SpigotItemStack) iStack).getBukkitStack() : + null ); + + + if ( bStack == null ) { + + XMaterial xMat = SpigotCompatibility.getInstance().getXMaterial( getMaterial() ); + if ( xMat != null ) { + bStack = xMat.parseItem(); + } + } + + if ( bStack != null ) { + + this.bukkitStack = bStack.clone(); + + if ( bukkitStack != null ) { + setupBukkitStack( bukkitStack ); + } + } + + } + + public void setPrisonBlock( PrisonBlock pBlock ) { String displayName = pBlock.getBlockName(); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotLocation.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotLocation.java index a6ad49e97..75b41866e 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotLocation.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotLocation.java @@ -28,24 +28,41 @@ public SpigotLocation( org.bukkit.Location bukkitLocation ) { public org.bukkit.Location getBukkitLocation() { if ( bukkitLocation == null ) { - bukkitLocation = createBukkitLocation(); + bukkitLocation = getBukkitLocation( this ); +// bukkitLocation = createBukkitLocation(); } return bukkitLocation; } - private org.bukkit.Location createBukkitLocation() { + public static org.bukkit.Location getBukkitLocation( Location location ) { - org.bukkit.World world = Bukkit.getWorld( getWorld().getName() ); + org.bukkit.World world = Bukkit.getWorld( location.getWorld().getName() ); - org.bukkit.Location bLocation = new org.bukkit.Location(world, getBlockX(), getBlockY(), getBlockZ() ); + org.bukkit.Location bLocation = new org.bukkit.Location(world, + location.getBlockX(), location.getBlockY(), location.getBlockZ() ); - bLocation.setYaw(getYaw()); + bLocation.setYaw( location.getYaw() ); - bLocation.setPitch(getPitch()); + bLocation.setPitch( location.getPitch() ); + +// bLocation.; return bLocation; } + +// private org.bukkit.Location createBukkitLocation() { +// +// org.bukkit.World world = Bukkit.getWorld( getWorld().getName() ); +// +// org.bukkit.Location bLocation = new org.bukkit.Location(world, getBlockX(), getBlockY(), getBlockZ() ); +// +// bLocation.setYaw(getYaw()); +// +// bLocation.setPitch(getPitch()); +// +// return bLocation; +// } // public void setBukkitLocation(org.bukkit.Location bukkitLocation) { // this.bukkitLocation = bukkitLocation; diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotWorld.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotWorld.java index aba9d6b88..3b465279e 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotWorld.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotWorld.java @@ -26,6 +26,7 @@ import org.bukkit.Bukkit; import com.cryptomorin.xseries.XEntityType; +import com.cryptomorin.xseries.XMaterial; import tech.mcprison.prison.internal.ArmorStand; import tech.mcprison.prison.internal.Entity; @@ -47,6 +48,7 @@ import tech.mcprison.prison.spigot.game.entity.SpigotArmorStand; import tech.mcprison.prison.spigot.game.entity.SpigotEntity; import tech.mcprison.prison.spigot.game.entity.SpigotEntityType; +import tech.mcprison.prison.spigot.nbt.PrisonNBTUtil; import tech.mcprison.prison.util.Location; /** @@ -268,38 +270,119 @@ public org.bukkit.World getWrapper() { @Override public Entity spawnEntity( Location location, EntityType entityType) { + return new SpigotEntity( spawnBukkitEntity( location, entityType ) ); + } + + public org.bukkit.entity.Entity spawnBukkitEntity( Location location, EntityType entityType) { + SpigotLocation sLocation = ( location instanceof SpigotLocation ? - (SpigotLocation) location : + (SpigotLocation) location : new SpigotLocation( location )); SpigotEntityType sEtityType = SpigotEntityType.getSpigotEntityType( entityType ); org.bukkit.entity.Entity bEntity = - ((SpigotWorld) sLocation.getWorld()).getWrapper().spawnEntity( - sLocation.getBukkitLocation(), sEtityType.getbEntityType() ); + ((SpigotWorld) sLocation.getWorld()).getWrapper().spawnEntity( + sLocation.getBukkitLocation(), sEtityType.getbEntityType() ); - return new SpigotEntity( bEntity ); + return bEntity; } @Override public ArmorStand spawnArmorStand( Location location ) { + org.bukkit.entity.ArmorStand armorStand = spawnBukkitArmorStand( location ); + + SpigotArmorStand sArmorStand = new SpigotArmorStand( armorStand ); + + return sArmorStand; + } + + public org.bukkit.entity.ArmorStand spawnBukkitArmorStand( Location location ) { + int maxHight = location.getWorld().getMaxHeight(); Location spawnPoint = new Location( location ); spawnPoint.setY(maxHight); - Entity e = spawnEntity( spawnPoint, SpigotEntityType.ENTITY_TYPE_ARMOR_STAND ); - SpigotEntity sEntity = (SpigotEntity) e; +// Entity e = spawnEntity( spawnPoint, SpigotEntityType.ENTITY_TYPE_ARMOR_STAND ); +// SpigotEntity sEntity = (SpigotEntity) e; - org.bukkit.entity.ArmorStand armorStand = (org.bukkit.entity.ArmorStand) sEntity.getBukkitEntity(); + org.bukkit.entity.Entity bEntity = spawnBukkitEntity( spawnPoint, SpigotEntityType.ENTITY_TYPE_ARMOR_STAND ); + + org.bukkit.entity.ArmorStand armorStand = (org.bukkit.entity.ArmorStand) bEntity; armorStand.setVisible(false); - SpigotArmorStand sArmorStand = new SpigotArmorStand( armorStand ); - sArmorStand.teleport(location); + armorStand.teleport( new SpigotLocation( location ).getBukkitLocation() ); - return sArmorStand; +// SpigotArmorStand sArmorStand = new SpigotArmorStand( armorStand ); + +// sArmorStand.teleport(location); + +// testArmorStandPlacement( spawnPoint ); + + return armorStand; + } + + + + @Override + public ArmorStand spawnArmorStand( Location location, String itemType, + String customName, String nbtKey, String nbtValue ) { + + int maxHight = location.getWorld().getMaxHeight(); + + Location spawnPoint = new Location( location ); + spawnPoint.setY(maxHight); + +// Location spawnPoint = new Location( location ); +// spawnPoint.setX( spawnPoint.getX() + 2 ); +// spawnPoint.setZ( spawnPoint.getZ() + 2 ); + + + org.bukkit.entity.Entity bEntity = spawnBukkitEntity( spawnPoint, SpigotEntityType.ENTITY_TYPE_ARMOR_STAND ); + org.bukkit.entity.ArmorStand as = (org.bukkit.entity.ArmorStand) bEntity; + + as.setVisible( false ); + as.setCustomNameVisible( true ); + as.setArms( true ); + as.setBasePlate( false ); + + if ( customName != null ) { + as.setCustomName( customName ); + } + + + if ( nbtKey != null && nbtValue != null ) { + + PrisonNBTUtil.setNBTString( as, nbtKey, nbtValue ); + } + + + if ( itemType != null && itemType.trim().length() > 0 ) { + + XMaterial xMat = XMaterial.matchXMaterial( itemType ).orElse( null ); + org.bukkit.inventory.ItemStack bItemStack = xMat == null ? null : xMat.parseItem(); + + if ( bItemStack == null ) { + + bItemStack = XMaterial.COBBLESTONE.parseItem(); + } + + as.setItemInHand(bItemStack); + } + + + as.teleport( SpigotLocation.getBukkitLocation(location) ); + + // as.setSmall( true ); + + + SpigotArmorStand sas = new SpigotArmorStand( as ); +// sas.teleport( location ); + + return sas; } /** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotArmorStand.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotArmorStand.java index 5a4a4e57f..c48c002ed 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotArmorStand.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotArmorStand.java @@ -12,10 +12,12 @@ public class SpigotArmorStand private org.bukkit.entity.ArmorStand bArmorStand; + private SpigotItemStack sItemStack = null; + public SpigotArmorStand( org.bukkit.entity.ArmorStand bArmorStand ) { super( bArmorStand ); - bArmorStand.setVisible( false ); + // bArmorStand.setVisible( false ); this.bArmorStand = bArmorStand; } @@ -39,6 +41,58 @@ public SpigotArmorStand(Entity entity) { this.bArmorStand.setVisible( false ); } } + +// /** +// * Sets visibility:false, arms:true, basePlate:false, canPickupItems:false, +// * removeWhenFar:false, gravity:false, and itemInHand. +// */ +// @Override +// public void setupArmorStand( ItemStack item ) { +// +// if ( item != null ) { +// +// setVisible( false ); +// +// setArms( true ); +// setBasePlate( false ); +// setCanPickupItems( false ); +// +// setItemInHand( item ); +// +// setRemoveWhenFarAway(false); +// +// if ( new BluesSemanticVersionComparator().compareMCVersionTo( "1.9.0" ) >= 0 ) { +// +// // setGravity is invalid for spigot 1.8.8: +// setGravity( false ); +// } +// } +// } + +// @Override +// public void setupArmorStand( String itemType ) { +// SpigotItemStack item = null; +// +// XMaterial xBomb = XMaterial.matchXMaterial( itemType ).orElse( null ); +// +// if ( xBomb != null ) { +// try { +// +// // Create the spigot/bukkit ItemStack: +// org.bukkit.inventory.ItemStack bItemStack = xBomb.parseItem(); +// +// if ( sItemStack != null ) { +// +// item = new SpigotItemStack( bItemStack ); +// } +// } +// catch (PrisonItemStackNotSupportedRuntimeException e) { +// // Ignore +// } +// } +// +// setupArmorStand( item ); +// } @Override public boolean isVisible() { @@ -73,13 +127,21 @@ public void setRemoveWhenFarAway(boolean removeWhenFarAway) { @Override public ItemStack getItemInHand() { - return new SpigotItemStack( bArmorStand.getItemInHand() ); + return sItemStack; } @Override public void setItemInHand(ItemStack item) { - SpigotItemStack sItemStack = (SpigotItemStack) item; - bArmorStand.setItemInHand( sItemStack.getBukkitStack() ); + SpigotItemStack sItemStack = + ( item instanceof SpigotItemStack ? + (SpigotItemStack) item : + new SpigotItemStack( item ) ); + + this.sItemStack = sItemStack; + + org.bukkit.inventory.ItemStack bas = sItemStack.getBukkitStack(); + + bArmorStand.setItemInHand( bas ); } @Override @@ -110,6 +172,33 @@ public boolean hasGravity() { public void setGravity(boolean gravity) { bArmorStand.setGravity(gravity); } + + @Override + public boolean hasArms() { + return bArmorStand.hasArms(); + } + @Override + public void setArms( boolean arms ) { + bArmorStand.setArms( arms ); + } + + @Override + public boolean hasBasePlate() { + return bArmorStand.hasBasePlate(); + } + @Override + public void setBasePlate( boolean basePlate ) { + bArmorStand.setBasePlate( basePlate ); + } + + @Override + public boolean getCanPickupItems() { + return bArmorStand.getCanPickupItems(); + } + @Override + public void setCanPickupItems( boolean canPickupItems ) { + bArmorStand.setCanPickupItems( canPickupItems ); + } } From 6438ba64842a765ad251919202c3d6e584e3c9a0 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 17 Jul 2024 04:01:49 -0400 Subject: [PATCH 086/323] Mine Bomb Animations: Added two new animations: bounce and orbital. --- docs/changelog_v3.3.x.md | 3 + .../tech/mcprison/prison/bombs/MineBombs.java | 3 +- .../bombs/animations/BombAnimationBounce.java | 43 +++++++ .../animations/BombAnimationOrbital.java | 121 ++++++++++++++++++ .../bombs/animations/BombAnimations.java | 36 +++++- .../bombs/animations/BombAnimationsTask.java | 48 ++++++- 6 files changed, 246 insertions(+), 8 deletions(-) create mode 100644 prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationBounce.java create mode 100644 prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationOrbital.java diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index cdcd16694..d96928037 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-beta.18c 2024-07-17 +* **Mine Bomb Animations: Added two new animations: bounce and orbital.** + + * **Mine Bombs: Update to a lot of the core support for ItemStacks, World, Location, and ArmorStand.** These enhancements are to help support moving mine bomb animations back to core. 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 7d6d54af1..b6ad51a56 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 @@ -94,7 +94,8 @@ public enum AnimationPattern { infinity, infinityEight, bounce, - orbital + orbital, + orbitalEight ; diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationBounce.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationBounce.java new file mode 100644 index 000000000..32fc04506 --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationBounce.java @@ -0,0 +1,43 @@ +package tech.mcprison.prison.bombs.animations; + +import tech.mcprison.prison.bombs.MineBombData; +import tech.mcprison.prison.internal.ItemStack; +import tech.mcprison.prison.internal.block.PrisonBlock; +import tech.mcprison.prison.util.Location; + +public class BombAnimationBounce + extends BombAnimations { + + private double yOriginal = 0; + private double counter = 0; + + public BombAnimationBounce(MineBombData bomb, PrisonBlock sBombBlock, + ItemStack item, BombAnimationsTask task, + float entityYaw, float entityPitch) { + super(bomb, sBombBlock, item, task, entityYaw, entityPitch); + + this.yOriginal = getArmorStand().getLocation().getY(); + } + + @Override + public void stepAnimation() { + + double speed = 0.35; + + counter += speed; + + if ( counter > 128d ) { + counter -= 128d; + } + + double bounce = 1.25 * Math.sin( counter ); + + Location loc = new Location( getArmorStand().getLocation() ); + loc.setY( yOriginal + bounce ); + + getArmorStand().teleport( loc ); + +// getArmorStand().getLocation().setY( yOriginal + bounce ); + } + +} diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationOrbital.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationOrbital.java new file mode 100644 index 000000000..dca1dc65e --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationOrbital.java @@ -0,0 +1,121 @@ +package tech.mcprison.prison.bombs.animations; + +import tech.mcprison.prison.bombs.GeometricShapes; +import tech.mcprison.prison.bombs.MineBombData; +import tech.mcprison.prison.internal.ItemStack; +import tech.mcprison.prison.internal.block.PrisonBlock; +import tech.mcprison.prison.util.Location; +import tech.mcprison.prison.util.Vector; + +/* + * NOTE: The whole rotateAroundAxisY does not work. + * So for now, disable this option. + */ +public class BombAnimationOrbital extends BombAnimations { + + private double angle = 0.0; + private double radius = 1.0; + + private Location oLoc = null; + + public BombAnimationOrbital(MineBombData bomb, PrisonBlock sBombBlock, + ItemStack item, BombAnimationsTask task, + float entityYaw, float entityPitch) { + super(bomb, sBombBlock, item, task, entityYaw, entityPitch); + + } + + @Override + public void stepAnimation() { + + angle += 25; + + if ( angle > 360 ) { + angle -= 360; + } + + if ( oLoc == null ) { + oLoc = new Location( getArmorStand().getLocation() ); + } + + Vector vector = GeometricShapes.getPointsOnCircleXZ( angle, radius ); + Location newLoc = new Location( oLoc ).add(vector); + getArmorStand().teleport( newLoc ); + + +// oLoc.setYaw( (float) angle ); +// getArmorStand().teleport( oLoc ); + + + +// Location loc = getArmorStand().getLocation(); +// loc.setDirection( vector ); + +// float radians = (float) Math.toRadians(angle); +// loc.setYaw( radians ); + +// getArmorStand().teleport( loc ); + + +// DecimalFormat dFmt = new DecimalFormat( "#,##0.0000" ); +// Output.get().logInfo( +// String.format( +// "Orbital direction: angle: %8s x: %8s y: %8s z: %8s", +// dFmt.format(angle), +// dFmt.format( vector.getX() ), +// dFmt.format( vector.getY() ), +// dFmt.format( vector.getY() ) +// ) +// ); +// + + + + +// double angle = 0.05; +// Vector direction = getArmorStand().getLocation().getDirection(); +// +// setEulerAngleX( direction.getX() + angle); +// +// direction.setX( getEulerAngleX() ); +// +// getArmorStand().getLocation().setDirection(direction); +// +// +// Output.get().logInfo( "Orbital direction: x: " + getEulerAngleX() + +// " y: " + getEulerAngleY() + +// " z: " + getEulerAngleZ() ); + + +// angle += 5; + + //arm.rotateAroundAxisY( angle ); + +// Output.get().logInfo( arm.toString() ); + + //getArmorStand().setRightArmPose( arm ); + + +// EulerAngle arm = EulerAngle.rotateAroundAxisY( +// getEulerAngleX(), +// getEulerAngleY(), +// getEulerAngleZ(), +// angle ); +// +// setEulerAngleX( arm.getX() ); +// setEulerAngleY( arm.getY() ); +// setEulerAngleZ( arm.getZ() ); + +// double speed = 0.35; +// +// setEulerAngleX( getEulerAngleX() + speed ); +// setEulerAngleY( getEulerAngleY() + speed ); +//// setEulerAngleZ( getEulerAngleZ() + speed ); +// +// +// EulerAngle arm = new EulerAngle( getEulerAngleX(), getEulerAngleY(), getEulerAngleZ() ); + +// getArmorStand().setRightArmPose(arm); + } + +} diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java index 485b26e20..d73874830 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java @@ -103,19 +103,43 @@ public void initialize() { eulerAngleZ + startingAngle ); - armorStand = location.spawnArmorStand(); + // Spawn an invisible armor stand: + armorStand = location.spawnArmorStand( getBomb().getItemType(), + getBomb().getName(), + MineBombs.MINE_BOMBS_NBT_KEY, getBomb().getName() ); +// armorStand = location.spawnArmorStand(); if ( armorStand != null ) { - armorStand.setVisible(false); + // Sets visibility:false, arms:true, basePlate:false, canPickupItems:false, + // removeWhenFar:false, gravity:false, and itemInHand. + // armorStand.setupArmorStand( getBomb().getItemType() ); +// armorStand.setupArmorStand( getItem() ); - armorStand.setNbtString( MineBombs.MINE_BOMBS_NBT_KEY, getBomb().getName() ); + armorStand.setCustomNameVisible( getId() == 0 && initializeCustomName() ); + +// armorStand.setNbtString( MineBombs.MINE_BOMBS_NBT_KEY, getBomb().getName() ); + +// armorStand.setNbtString( MineBombs.MINE_BOMBS_NBT_THROWER_UUID, +// playerUUID ); armorStand.setRightArmPose(arm); - armorStand.setItemInHand( getItem() ); - armorStand.setCustomNameVisible( getId() == 0 && initializeCustomName() ); - armorStand.setRemoveWhenFarAway(false); +// ItemStack itemInHand = armorStand.getItemInHand(); +// +// int iihAmount = itemInHand.getAmount(); +// int iamount = getItem().getAmount(); +// +// int count = iihAmount + iamount; +// +// armorStand.setArms( true ); +// armorStand.setBasePlate( false ); +// armorStand.setCanPickupItems( false ); +// +// +// armorStand.setItemInHand( getItem() ); + +// armorStand.setRemoveWhenFarAway(false); if ( new BluesSemanticVersionComparator().compareMCVersionTo( "1.9.0" ) >= 0 ) { diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationsTask.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationsTask.java index bb250f69b..ca8d0b858 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationsTask.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationsTask.java @@ -36,10 +36,11 @@ public BombAnimationsTask() { public void animatorFactory( // AnimationPattern animation, MineBombData bomb, PrisonBlock pBlock, - ItemStack item, MineBombDetonateTask detonateBomb ) { + ItemStack sItem, MineBombDetonateTask detonateBomb ) { this.detonateBomb = detonateBomb; + ItemStack item = new ItemStack( sItem ); AnimationPattern animation = bomb.getAnimationPattern(); @@ -58,9 +59,54 @@ public void animatorFactory( switch ( animation ) { case bounce: + { + float yaw = 0; + float pitch = 0; + + BombAnimationBounce ba = new BombAnimationBounce( bomb, + pBlock, item, this, + yaw, pitch ); + + getAnimators().add( ba ); + submitTask(); + } break; + case orbital: + { + float yaw = 0; + float pitch = 0; + + BombAnimationOrbital ba = new BombAnimationOrbital( bomb, + pBlock, item, this, + yaw, pitch ); + + getAnimators().add( ba ); + submitTask(); + } + + break; + + case orbitalEight: + { + float yaw = 0; + float pitch = 0; + float yawStep = 360f / 8f; + + for ( int i = 0; i < 8; i++ ) { + BombAnimationOrbital ba = new BombAnimationOrbital( bomb, + pBlock, item, this, + yaw, pitch ); + + getAnimators().add( ba ); + + yaw += yawStep; + } + + submitTask(); + } + case infinity: { float yaw = 0; From cd664e552125018dc2e99bea1d710fa8647ca5a8 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 17 Jul 2024 04:04:15 -0400 Subject: [PATCH 087/323] Mine Bombs config settings: updated some of the defaults and added a few new bombs to use the newer animations. --- docs/changelog_v3.3.x.md | 3 + .../bombs/MineBombDefaultConfigSettings.java | 120 +++++++++- .../prison/discord/PrisonSupportFiles.java | 38 ++++ .../spigot/utils/PrisonBombListener.java | 208 ------------------ 4 files changed, 149 insertions(+), 220 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index d96928037..3f36d7c35 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-beta.18c 2024-07-17 +* **Mine Bombs config settings: updated some of the defaults and added a few new bombs to use the newer animations.** + + * **Mine Bomb Animations: Added two new animations: bounce and orbital.** 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 512ce08c1..d16e64baf 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 @@ -206,7 +206,7 @@ public void setupDefaultMineBombData(MineBombs mineBombs) { MineBombData mbd = new MineBombData( - "WimpyBomb", "GUNPOWDER", ExplosionShape.sphere.name(), 4, + "WimpyBomb", "GUNPOWDER", ExplosionShape.sphere.name(), 2, "A Wimpy Mine Bomb&r" ); // mbd.setLoreBombItemId( "&7A &2Wimpy &cBomb &9...&02A3F" ); @@ -269,7 +269,7 @@ public void setupDefaultMineBombData(MineBombs mineBombs) { MineBombData mbd = new MineBombData( - "CubeBomb", "SLIME_BLOCK", ExplosionShape.cube.name(), 2, + "CubeBomb", "SLIME_BALL", ExplosionShape.cube.name(), 2, "A Cubic Bomb&r" ); mbd.setDescription("The most anti-round bomb you will ever be able to find. " + "It's totally cubic.&r"); @@ -302,19 +302,49 @@ public void setupDefaultMineBombData(MineBombs mineBombs) { MineBombData mbd = new MineBombData( - "DudBomb", "SLIME_BLOCK", ExplosionShape.disk_x.name(), 1, - "This may be a bomb?&r" ); - mbd.setDescription("The most anti-round bomb you will ever be able to find. " + - "It's totally cubic.&r"); + "DudNoneBomb", "COAL", ExplosionShape.sphere.name(), 1, + "This is a bomb?&r" ); + mbd.setDescription("This old bomb is a dud.&r"); - mbd.setNameTag( "&a-=- &7{name}&a -=--&r" ); + mbd.setNameTag( "&a-=- &4{countdown} &5-=- &7{name} &5-=- &4{countdown} &a-=-&r" ); mbd.setItemName( MineBombData.MINE_BOMB_DEFAULT_ITEM_NAME ); - mbd.setToolInHandName( "DIAMOND_PICKAXE" ); + mbd.setToolInHandName( "STONE_PICKAXE" ); mbd.setToolInHandFortuneLevel( 1 ); - mbd.setRemovalChance( 10.0d ); + mbd.setRemovalChance( 25.0d ); + + mbd.addSoundEffects( mbeSound01.clone() ); + mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 30 ) ); + mbd.addSoundEffects( mbeSound03.clone() ); + + mbd.addVisualEffects( mbeExplode04.clone() ); + mbd.addVisualEffects( mbeExplode02.clone().setOffsetTicks( 30 ) ); + + mbd.setCooldownTicks( 10 ); + + mbd.setThrowVelocityLow( 0.05 ); + mbd.setThrowVelocityHigh( 0.5 ); - mbd.setHeight( 5 ); + + mbd.setAnimationPattern( AnimationPattern.none ); + + mineBombs.getConfigData().getBombs().put( mbd.getName().toLowerCase(), mbd ); + } + + + + { + MineBombData mbd = new MineBombData( + "DudBounceBomb", "IRON_INGOT", ExplosionShape.sphere.name(), 1, + "This is a bomb?&r" ); + mbd.setDescription("This old bomb is a dud.&r"); + + mbd.setNameTag( "&a-=- &4{countdown} &5-=- &7{name} &5-=- &4{countdown} &a-=-&r" ); + mbd.setItemName( MineBombData.MINE_BOMB_DEFAULT_ITEM_NAME ); + + mbd.setToolInHandName( "STONE_PICKAXE" ); + mbd.setToolInHandFortuneLevel( 1 ); + mbd.setRemovalChance( 25.0d ); mbd.addSoundEffects( mbeSound01.clone() ); mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 30 ) ); @@ -323,7 +353,38 @@ public void setupDefaultMineBombData(MineBombs mineBombs) mbd.addVisualEffects( mbeExplode04.clone() ); mbd.addVisualEffects( mbeExplode02.clone().setOffsetTicks( 30 ) ); - mbd.setGlowing( false ); + mbd.setCooldownTicks( 10 ); + + mbd.setThrowVelocityLow( 0.05 ); + mbd.setThrowVelocityHigh( 0.5 ); + + + mbd.setAnimationPattern( AnimationPattern.bounce ); + + mineBombs.getConfigData().getBombs().put( mbd.getName().toLowerCase(), mbd ); + } + + + + { + MineBombData mbd = new MineBombData( + "DudOrbitalBomb", "GOLD_INGOT", ExplosionShape.sphere.name(), 1, + "This is a bomb?&r" ); + mbd.setDescription("This old bomb is a dud.&r"); + + mbd.setNameTag( "&a-=- &4{countdown} &5-=- &7{name} &5-=- &4{countdown} &a-=-&r" ); + mbd.setItemName( MineBombData.MINE_BOMB_DEFAULT_ITEM_NAME ); + + mbd.setToolInHandName( "STONE_PICKAXE" ); + mbd.setToolInHandFortuneLevel( 1 ); + mbd.setRemovalChance( 25.0d ); + + mbd.addSoundEffects( mbeSound01.clone() ); + mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 30 ) ); + mbd.addSoundEffects( mbeSound03.clone() ); + + mbd.addVisualEffects( mbeExplode04.clone() ); + mbd.addVisualEffects( mbeExplode02.clone().setOffsetTicks( 30 ) ); mbd.setCooldownTicks( 10 ); @@ -331,12 +392,47 @@ public void setupDefaultMineBombData(MineBombs mineBombs) mbd.setThrowVelocityHigh( 0.5 ); - mbd.setAnimationPattern( AnimationPattern.none ); + mbd.setAnimationPattern( AnimationPattern.orbital ); + + mineBombs.getConfigData().getBombs().put( mbd.getName().toLowerCase(), mbd ); + } + + + + { + MineBombData mbd = new MineBombData( + "DudOrbital8Bomb", "DIAMOND", ExplosionShape.sphere.name(), 1, + "This is a bomb?&r" ); + mbd.setDescription("This old bomb is a dud.&r"); + + mbd.setNameTag( "&a-=- &4{countdown} &5-=- &7{name} &5-=- &4{countdown} &a-=-&r" ); + mbd.setItemName( MineBombData.MINE_BOMB_DEFAULT_ITEM_NAME ); + + mbd.setToolInHandName( "STONE_PICKAXE" ); + mbd.setToolInHandFortuneLevel( 1 ); + mbd.setRemovalChance( 25.0d ); + + mbd.addSoundEffects( mbeSound01.clone() ); + mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 30 ) ); + mbd.addSoundEffects( mbeSound03.clone() ); + + mbd.addVisualEffects( mbeExplode04.clone() ); + mbd.addVisualEffects( mbeExplode02.clone().setOffsetTicks( 30 ) ); + + mbd.setCooldownTicks( 10 ); + + mbd.setThrowVelocityLow( 0.05 ); + mbd.setThrowVelocityHigh( 0.5 ); + + + mbd.setAnimationPattern( AnimationPattern.orbitalEight ); mineBombs.getConfigData().getBombs().put( mbd.getName().toLowerCase(), mbd ); } + + mineBombs.saveConfigJson(); Output.get().logInfo( "Mine bombs: setup default values." ); 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 e3bbc920b..1f05643f4 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 @@ -7,6 +7,8 @@ import java.io.IOException; import java.io.StringReader; import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.List; import tech.mcprison.prison.Prison; @@ -23,6 +25,8 @@ public class PrisonSupportFiles { private boolean colorMapping = true; + private PrisonSupportFileLinkage linkage; + public enum ColorMaps { black( "&0", "", "" ), DarkBlue( "&1", "", "" ), @@ -149,6 +153,8 @@ public void saveToSupportFile( StringBuilder text, String supportName ) { private void saveSupportDataToFile( StringBuilder text, String supportName ) { File file = getSupportFile(); + linkage = new PrisonSupportFileLinkage(); + try ( BufferedWriter bw = new BufferedWriter( new FileWriter( file, false )); // create file ) { @@ -208,7 +214,39 @@ private void writeBufferedWriter( BufferedWriter bw, StringBuilder text ) { } } + + + private List extractAllHyperlinkPlaceholders( StringBuilder text ) { + + List hlp = new ArrayList<>(); + + try ( + BufferedReader br = new BufferedReader( new StringReader( text.toString() )); + ) { + + String line = br.readLine(); + + while ( line != null ) { + + + if ( line.startsWith( "||`" ) ) { + + linkage.addLinkage( line ); + hlp.add( line ); + } + + line = br.readLine(); + } + + } + catch ( Exception e ) { + + } + + return hlp; + } + protected String convertColorCodes(String line) { StringBuilder sb = new StringBuilder(); 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 4ff98eef0..7794068f8 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 @@ -291,141 +291,6 @@ public void run() { } } -//// @EventHandler -// public void onMineBombThrownHitMine2Event( EntityInteractEvent e ) { -// -// // e.getEntity() is the projectile which should be an NBT tagged ArmorStand: -// if ( e.getEntityType() == EntityType.ARMOR_STAND && -// e.getEntity() instanceof ArmorStand ) { -// -// SpigotArmorStand armorStand = new SpigotArmorStand( (ArmorStand) e.getEntity() ); -// -// String bombName = armorStand.getNbtString( MineBombs.MINE_BOMBS_NBT_KEY ); -// if ( bombName != null && bombName.trim().length() > 0 ) { -// -// MineBombData mineBomb = MineBombs.getInstance().findBombByName(bombName); -// -// String throwerUUID = armorStand.getNbtString( MineBombs.MINE_BOMBS_NBT_THROWER_UUID ); -// -// SpigotPlayer player = (SpigotPlayer) -// Prison.get().getPlatform().getPlayer( throwerUUID ).orElse(null); -// -// -// -// SpigotBlock targetBlock = SpigotBlock.getSpigotBlock( e.getBlock() ); -//// if ( targetBlock == null ) { -//// Entity entity = e.getHitEntity(); -//// Location location = new SpigotLocation( entity.getLocation() ); -//// for ( double y = 0d; y <= 4d; y++ ) { -//// -//// -//// SpigotLocation loc = new SpigotLocation( location ); -////// SpigotLocation loc = new SpigotLocation( location.getWorld(), -////// location.getX(), location.getY() - y, location.getZ(), -////// location.getYaw(), location.getPitch() ); -//// -//// if ( !loc.getBlockAt().isEmpty() ) { -//// targetBlock = (SpigotBlock) loc.getBlockAt(); -//// -//// // Found a block under the entity that was hit, so stop looking: -//// break; -//// } -//// -//// } -//// } -// -// if ( targetBlock != null ) { -// // Process mine bomb: -// -// processBombTriggerEvent( player, mineBomb, targetBlock ); -// -//// e.getEntity().getShooter().; -//// -//// boolean canceled = processBombTriggerEvent( event, player, bombName, -//// targetBlock, hand ); -// -// } -// -// } -// } -// } - -// @EventHandler -// public void onMineBombThrownHitMineEvent( ProjectileHitEvent e ) { -// -// -// // e.getEntity() is the projectile which should be an NBT tagged ArmorStand: -// if ( e.getEntityType() == EntityType.ARMOR_STAND && -// e.getEntity() instanceof ArmorStand ) { -// -// SpigotArmorStand armorStand = new SpigotArmorStand( (ArmorStand) e.getEntity() ); -// -// String bombName = armorStand.getNbtString( MineBombs.MINE_BOMBS_NBT_KEY ); -// if ( bombName != null && bombName.trim().length() > 0 ) { -// -// MineBombData mineBomb = MineBombs.getInstance().findBombByName(bombName); -// -// String throwerUUID = armorStand.getNbtString( MineBombs.MINE_BOMBS_NBT_THROWER_UUID ); -// -// SpigotPlayer player = (SpigotPlayer) -// Prison.get().getPlatform().getPlayer( throwerUUID ).orElse(null); -// -// SpigotBlock targetBlock = SpigotBlock.getSpigotBlock( e.getHitBlock() ); -// if ( targetBlock == null ) { -// Entity entity = e.getHitEntity(); -// Location location = new SpigotLocation( entity.getLocation() ); -// for ( double y = 0d; y <= 4d; y++ ) { -// -// -// SpigotLocation loc = new SpigotLocation( location ); -//// SpigotLocation loc = new SpigotLocation( location.getWorld(), -//// location.getX(), location.getY() - y, location.getZ(), -//// location.getYaw(), location.getPitch() ); -// -// if ( !loc.getBlockAt().isEmpty() ) { -// targetBlock = (SpigotBlock) loc.getBlockAt(); -// -// // Found a block under the entity that was hit, so stop looking: -// break; -// } -// -// } -// } -// -// if ( targetBlock != null ) { -// // Process mine bomb: -// -// processBombTriggerEvent( player, mineBomb, targetBlock ); -// -//// e.getEntity().getShooter().; -//// -//// boolean canceled = processBombTriggerEvent( event, player, bombName, -//// targetBlock, hand ); -// -// } -// -// } -// -// -// } -// -//// if(!(e.getHitEntity() instanceof LivingEntity)) { -//// return; -//// } -//// -//// LivingEntity ent = (LivingEntity)e.getHitEntity(); -//// Projectile proj = e.getEntity(); -//// -// -//// -//// if(proj instanceof Snowball){ // All code for throwing knife will be in here -//// Snowball snowball = (Snowball)proj; // cast projectile to snowball object -//// ItemStack item = snowball.getItem(); // This beautiful method returns the itemstack that was put into the snowball -//// if(item.getType().equals(Material.IRON_SWORD)) -//// ent.damage(6); // 3 hearts of damage -//// } -// } - /** @@ -567,79 +432,6 @@ private boolean processBombTriggerEvent( SpigotPlayer sPlayer, canceled = true; } - - -// // Temp test stuff... remove when NBTs are working: -// { -// -// ItemStack item = new ItemStack(Material.APPLE); -// SpigotItemStack spItemStack = new SpigotItemStack( item ); -// spItemStack.setNBTString("tasty", "fruit"); -// SpigotPlayer spPlayer = new SpigotPlayer( player ); -// spPlayer.getInventory().addItem(spItemStack); -// spPlayer.updateInventory(); -// -//// ItemStack item = new ItemStack(Material.APPLE); -//// new NBTItem(item, true).setString("yummy", "apple"); -//// player.getInventory().addItem(item); -// -// SpigotItemStack sItemStack = new SpigotItemStack( event.getItem() ); -// Output.get().logInfo( sItemStack.getNBT().toString() ); -// } - -// MineBombData bomb = getPrisonUtilsMineBombs().getBombItem( bombName ); - -// if ( bomb == null ) { -// if ( Output.get().isDebug() ) { -// Output.get().logInfo( "MineBombs: The bomb named '%s' cannot be mapped to a mine bomb.", -// bombName ); -// } -// return canceled; -// } - - -// SpigotBlock sBlock = null; -// -//// SpigotPlayer sPlayer = new SpigotPlayer( player ); -// -// // If clicking AIR, then event.getClickedBlock() will be null... -// // so if null, then use the player's location for placing the bomb. -// if ( targetBlock == null ) { -// Location loc = sPlayer.getLocation(); -// -// // Get the block 3 away from the player, in the direction (vector) in which -// // the player is looking. -// sBlock = (SpigotBlock) loc.add( loc.getDirection().multiply( 3 ) ) .getBlockAt(); -// } -// else { -// sBlock = SpigotBlock.getSpigotBlock( targetBlock ); -// } - - -// Mine mine = getMine(sPlayer, mineBomb, sBlock ); - -// if ( mine == null ) { -// canceled = false; -// } -// else { -// -// -// // getHand() is not available with bukkit 1.8.8 so use the compatibility functions: -//// EquipmentSlot hand = SpigotCompatibility.getInstance().getHand(event); -//// EquipmentSlot hand = event.getHand(); -// -//// Output.get().logInfo( "### PrisonBombListener: PlayerInteractEvent 02 " ); -// if ( getPrisonUtilsMineBombs().setBombInHand( sPlayer, mineBomb, sBlock, hand ) ) { -// -// // The item was a bomb and it was activated. -// // Cancel the event so the item will not be placed or processed farther. -// -//// Output.get().logInfo( "### PrisonBombListener: PlayerInteractEvent 03 Bomb detected - May not have been set. " ); -// canceled = true; -//// event.setCancelled( true ); -// } -// } - return canceled; } From a2cd1ad05b5af8e11382c0893fcd6058cc3495a4 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 18 Jul 2024 16:53:25 -0400 Subject: [PATCH 088/323] Oops... accidentally committed code that has been on the back burner for a long time. This resulted in a build failure. The code is going to take the `/prison support saveToFile help` output, which is HTML based, and auto generate a table of contents with a lot of cross referenced hyper links. The intention is that if you load this document, you can quickly jump to any section of interest to help solve support issues. This will be updated and completed in the near future... nearer now that I accidentally committed it. ;) LOL --- docs/changelog_v3.3.x.md | 9 +- .../discord/PrisonSupportFileLinkage.java | 141 ++++++++++++++++++ .../discord/PrisonSupportLinkageData.java | 48 ++++++ 3 files changed, 197 insertions(+), 1 deletion(-) create mode 100644 prison-core/src/main/java/tech/mcprison/prison/discord/PrisonSupportFileLinkage.java create mode 100644 prison-core/src/main/java/tech/mcprison/prison/discord/PrisonSupportLinkageData.java diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 3f36d7c35..07566ba0f 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-beta.18c 2024-07-17 +# 3.3.0-beta.18c 2024-07-18 + + +* **Oops... accidentally committed code that has been on the back burner for a long time. This resulted in a build failure.** +The code is going to take the `/prison support saveToFile help` output, which is HTML based, and auto generate a table of contents with a lot of cross referenced hyper links. +The intention is that if you load this document, you can quickly jump to any section of interest to help solve support issues. +This will be updated and completed in the near future... nearer now that I accidentally committed it. ;) LOL + * **Mine Bombs config settings: updated some of the defaults and added a few new bombs to use the newer animations.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonSupportFileLinkage.java b/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonSupportFileLinkage.java new file mode 100644 index 000000000..15cf2b059 --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonSupportFileLinkage.java @@ -0,0 +1,141 @@ +package tech.mcprison.prison.discord; + +import java.util.TreeMap; +import java.util.TreeSet; + +import tech.mcprison.prison.output.Output; + +public class PrisonSupportFileLinkage { + + public static final String LINKAGE_IDENTIFIER = "||"; + + private TreeMap> primaries = new TreeMap<>(); + + public enum PrimaryLinkages { + Ladder, + Rank, + Mine, + Listeners, + CommandStats, + + unknown + ; + + /** + *

This will take a raw linkage String, minus the + * pipes, and extract a PrimaryLinkages from it. + * + * + * @param linkage + * @return + */ + public static PrimaryLinkages fromString( String linkage ) { + PrimaryLinkages results = PrimaryLinkages.unknown; + + if ( linkage.contains( " " ) ) { + String[] parts = linkage.split(" "); + if ( parts != null && parts.length > 0 ) { + linkage = parts[0]; + } + } + + for ( PrimaryLinkages pl : values() ) { + if ( pl.name().equalsIgnoreCase(linkage) ) { + results = pl; + break; + } + } + + return results; + } + + + public void scanForTOCEntries( String line ) { + + if ( line != null && line.startsWith( LINKAGE_IDENTIFIER ) ) { + String[] parts = line.split(" "); + + PrimaryLinkages prime = PrimaryLinkages.fromString( parts[0] ); + if ( prime != PrimaryLinkages.unknown ) { + + } + else { + String msg = "Primary ID not setup for PrimaryLinkage: [" + line + "]"; + Output.get().logWarn(msg); + } + } + } + + } + + public enum SecondaryLinkages { + toc, + listing, + listingDetail, + detail, + config, + file; + + public static SecondaryLinkages fromString( String secondary ) { + SecondaryLinkages results = null; + + if ( secondary != null ) { + + for ( SecondaryLinkages scnd : values() ) { + if ( secondary.toLowerCase().contains( scnd.name().toLowerCase() ) ) { + results = scnd; + break; + } + } + } + + return results; + } + } + + private void addPrimaries( PrimaryLinkages pLink, String value ) { + if ( pLink != null && pLink != PrimaryLinkages.unknown && value != null ) { + + if ( !getPrimaries().containsKey(pLink) ) { + getPrimaries().put(pLink, new TreeSet<>() ); + } + + TreeSet values = getPrimaries().get( pLink ); + + if ( !values.contains( value ) ) { + values.add( value ); + } + } + } + + public void addLinkage(String line) { + + if ( line != null && line.startsWith( LINKAGE_IDENTIFIER ) ) { + + String[] rawLinks = line.split("\\|\\|"); + + for (String rawLink : rawLinks) { + + if ( rawLink != null && rawLink.length() > 0 ) { + + String[] parts = rawLink.split(" "); + + PrimaryLinkages pLink = PrimaryLinkages.fromString( parts[0] ); + + String value = parts.length >= 2 ? parts[1] : null; + + addPrimaries( pLink, value ); + } + } + } + } + + + public TreeMap> getPrimaries() { + return primaries; + } + public void setPrimaries(TreeMap> primaries) { + this.primaries = primaries; + } + +} diff --git a/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonSupportLinkageData.java b/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonSupportLinkageData.java new file mode 100644 index 000000000..2de468e2e --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonSupportLinkageData.java @@ -0,0 +1,48 @@ +package tech.mcprison.prison.discord; + +import tech.mcprison.prison.discord.PrisonSupportFileLinkage.PrimaryLinkages; +import tech.mcprison.prison.discord.PrisonSupportFileLinkage.SecondaryLinkages; + +public class PrisonSupportLinkageData { + + private String rawLine; + + private PrimaryLinkages primary; + + private SecondaryLinkages secondary; + + private String secondaryText; + + + + private PrisonSupportLinkageData otherLinkage; + + + public PrisonSupportLinkageData( String line ) { + super(); + + + String rawLine = line.replace(PrisonSupportFileLinkage.LINKAGE_IDENTIFIER, "").trim(); + + this.rawLine = rawLine; + + + PrimaryLinkages primary = PrimaryLinkages.fromString( rawLine ); + this.primary = primary; + + if ( primary != PrimaryLinkages.unknown ) { + + String seconds = rawLine.replace( primary.name(), "" ).trim(); + + SecondaryLinkages secondary = SecondaryLinkages.fromString( seconds ); + this.secondary = secondary; + + String secondaryText = secondary == null ? "" : seconds.replace( secondary.name(), "" ).trim(); + this.secondaryText = secondaryText; + + } + + + } + +} From 31c5efa6369fbd60ffa22b199955c9d9e87373a1 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 19 Jul 2024 23:53:45 -0400 Subject: [PATCH 089/323] Mine bombs: Hex color codes: Setup one mine bomb using hex color codes. Hex color support was added to minecraft with spigot v1.16. Older versions of spigot will not work. No changes were needed to allow the hex support since prison was already handling support for hex colors. This is triggered with a prefix of '&#' followed by the 6 hex digits, such as '&#a1b2c3'. As a result, this simple hex color code will be translated by prison in to the code structure that spigot and paper will recognize: '&#a1b2c3' is converted to: '&x&a&1&b&2&c&3' --- docs/changelog_v3.3.x.md | 11 ++++++++- .../bombs/MineBombDefaultConfigSettings.java | 3 +++ .../prison/bombs/MineBombsConfigData.java | 23 +++++++++++++++++++ .../java/tech/mcprison/prison/util/Text.java | 9 ++++++++ 4 files changed, 45 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 07566ba0f..a566ae6b9 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-beta.18c 2024-07-18 +# 3.3.0-beta.18c 2024-07-19 + + +* **Mine bombs: Hex color codes: Setup one mine bomb using hex color codes.** +Hex color support was added to minecraft with spigot v1.16. Older versions of spigot will not work. +No changes were needed to allow the hex support since prison was already handling support for hex colors. +This is triggered with a prefix of '&#' followed by the 6 hex digits, such as '&#a1b2c3'. +As a result, this simple hex color code will be translated by prison in to the code structure that spigot and paper will recognize: +'&#a1b2c3' is converted to: '&x&a&1&b&2&c&3' + * **Oops... accidentally committed code that has been on the back burner for a long time. This resulted in a build failure.** 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 d16e64baf..49ca3b1a9 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 @@ -408,6 +408,9 @@ public void setupDefaultMineBombData(MineBombs mineBombs) mbd.setNameTag( "&a-=- &4{countdown} &5-=- &7{name} &5-=- &4{countdown} &a-=-&r" ); mbd.setItemName( MineBombData.MINE_BOMB_DEFAULT_ITEM_NAME ); + mbd.getLore().add( "&7Hex Colors: &#e81416Red&#ffa500Orange&#faeb36Yellow" + + "Oc314Greenǧde7Blueb369dIndigo𑋡dViolet" ); + mbd.setToolInHandName( "STONE_PICKAXE" ); mbd.setToolInHandFortuneLevel( 1 ); mbd.setRemovalChance( 25.0d ); 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 99d8f9006..6aa1e85a2 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 @@ -66,6 +66,29 @@ public boolean validateMineBombEffects() { } } + +// // Check all lore, and if it contains `&#` then process the hex color codes: +// for ( int i = 0; i < bomb.getLore().size(); i++ ) { +// String lore = bomb.getLore().get( i ); +// +// if ( lore != null && lore.contains( "&#") ) { +// String hex = Text.translateAmpColorCodesAltHex2Code( lore ); +// bomb.getLore().set( i, hex ); +// } +// } +// +// // Convert hex colors for bomb names and tags:. +// if ( bomb.getName().contains( "&#" ) ) { +// String hex = Text.translateAmpColorCodesAltHex2Code( bomb.getName() ); +// bomb.setName( hex ); +// } +// if ( bomb.getNameTag().contains( "&#" ) ) { +// String hex = Text.translateAmpColorCodesAltHex2Code( bomb.getNameTag() ); +// bomb.setNameTag( hex ); +// } + + + } return results; 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 c9af8c48f..972567829 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 @@ -432,6 +432,15 @@ public static String translateAmpColorCodes(String text) { public static String translateAmpColorCodesAltHexCode(String text) { return translateColorCodes( text, '&', COLOR_CHAR, '&' ); } + + // NOTE: It's not needed to remove the '&' +// public static String translateAmpColorCodesAltHex2Code(String text) { +// if ( text != null && text.contains( "&#" ) ) { +// text = text.replace( "&#", "#" ); +// } +// return translateColorCodes( text, '&', COLOR_CHAR, '&' ); +// } + /** * Strips the given message of all color codes * From bbfc37d391aa1244962f08eb4f1c4b82d544c009 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 20 Jul 2024 00:49:53 -0400 Subject: [PATCH 090/323] Autofeatures: Use TokenEnchant fortune levels: Added support for the newer TE API "ITokenEnchant". "TokenEnchantAPI" is still supported. --- docs/changelog_v3.3.x.md | 4 +++ prison-spigot/lib/TokenEnchantAPI-23.9.0.jar | Bin 0 -> 65615 bytes .../autofeatures/AutoManagerFeatures.java | 32 +++++++++++++++++- 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 prison-spigot/lib/TokenEnchantAPI-23.9.0.jar diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index a566ae6b9..e72c4db4c 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-beta.18c 2024-07-19 +* **Autofeatures: Use TokenEnchant fortune levels: Added support for the newer TE API "ITokenEnchant". "TokenEnchantAPI" is still supported.** + + + * **Mine bombs: Hex color codes: Setup one mine bomb using hex color codes.** Hex color support was added to minecraft with spigot v1.16. Older versions of spigot will not work. No changes were needed to allow the hex support since prison was already handling support for hex colors. diff --git a/prison-spigot/lib/TokenEnchantAPI-23.9.0.jar b/prison-spigot/lib/TokenEnchantAPI-23.9.0.jar new file mode 100644 index 0000000000000000000000000000000000000000..a5556d0340886fa5e71017fc9df6ac4fed199bc7 GIT binary patch literal 65615 zcma&MV~j39x2?O{w!PZ6Z5wafz1p^I+qP}nwr$%w-@fPE_;=l`=%|Ff4BRS~3>loO+u6_k?{6IE8BlNEcEotl)9rlp&Q zlcuGbnVM}>Vpw9{I{^NpAPoU&GejPM^`DCv|0#w4>(k`_IW@AirgyPqGPU!dce1rK zwlTIbGBdDoqBpQJrx*P9&(?;{$jZRcaaj{eU28S@2SF1*%oKL5f%cGfN5Bt_y9UE9 zOW$gA2-D~exep5I4i=aYNmBo?O)`TkGLy}GVcBM}Nfu{g$@-86^T6bsNiH+pCB>!W znkKttF`aI)dof*ZG35Q$Qy$p=F2QGaioIpt)8lr_bB1@)_s8?TvX=js$j{k9Y>?l? zs4zq{<7#Zgj*ZP6(nLD^Z>jt04eOZ2YepimqHbzTNzefAd;x&CIE&J`KiM^~tKI@fh6={j zaTF;Aj&`Fw@45}|KCYWY9RKK;}B;k6FFqmsXWTffbhMTvWLzX z*8>+pe1eP=0$9=xixzh~gqq^pdw}f5*$))kYYPN;lzP?;EN)%RCrW-@gR{&i_gxj8 zbdgx9$(PXZjWt(Au}Q<~Ym+lGQBzGFKQc3y@O=9t3Tk#&u0c7Qk?sI zWJZ9tR;)^C&=(SVL{IC{-uivS4@q)qRA^qEg0YQzZPafh%8q5t;5hIPutoutv*$s$ zJ`Iu@jH>%9A>MB|f&B){a8^LUDr&2Yi(5vk(a1gn9HfFI57MQryoeEQv!PTHQ?Nwh zal4y(MjEkBzgxEbQq<=(SC1bjuxSuNRT}F{YkDH4w&{LbFzb^}95k5!!A7~UAwc|C zIp z3)B{gBSJcj2oV~?&Uot8jz!Ki4cqw(oZf7$QmRZY4o`}*&Evte#-+amHl_KWP>c+k zCQbyV^LMwkm{l&5L|vKNMMc7Kf17)eiUTWd@gC?RxW_;~o8<*azg-z|+MY~%xS91+ z7*Zwt2pqx>d~11=DL$$2i{<&sQ2F8MTEUi&)F}HMOn+ARM`dS#$RdNX<|vIh;v4n{ zakxUQ{a;js`JD<#|J5LkkQ-^Y08&$tB_WyJIsb+Ht@qgsFR8s;!+ITVXnAaCVdUvyqlN2ufLm>zSHSo+Nyxk#R%Lds| zJ!*v~6N`x;X4g(QuH|!sb+6;P`e5D?k;K7{EviozFL8gQ%W{2()(FodpRZK9Sm{wx zymCy@3}WZ5iWJB6wrp(*<*N;IC96kchD6$_(BZ>I&A!ILs^Dw!&1gRAfydG%N=n6P ze6&4n4n`Bk5UB5%J3?A6mpu!-=eI061Veb?=+W?(Bo&*F^1O+dtm)dcO0_i4WRqeO z8_jV^W)aVcM3c&I9jV`>I6y?uMI-F$gYZuABNuD6yU84&$60V^A*-yV#naw(KhIRO z`%D_3FSOy6HhhZ477A1wX!@?1)?z&TMiaoxe)im%vdzLC zw|r<}so~}cP}9|lT;U^jH5XjM;2;@ogj)q17Ko}5Xuh3XaYJvyPeH3XbF6wkc2;ts zSKCNoC!maRcUZ3X2M5kbPx1enoL)yt*`|4RU7(vveh1)~hTu+WZuz$>>aF21!nM## zKAJ)_M2S|uvVlI{tTh+)_|reCqF2Lqd8KNq2y5y7o4@ebpFmH(wuVi@$w>}HcLHqh zt2-+X)(0#E9Bm}KnMbnE9k}Xk)^!nHQ8nz~TFhRipRaMBuA~Pp^XkBr$kh@F<<8I3 z0|7R5`qcqKiSPg1$DicIwCif#B8bbG^fm5_mBb~Fi(XKM$QvV6sX6g!BP1?X`RG?2AI0v7?%BB2s!aM$2I5B1RNUNz%?@6-~rKMZ;(+oxa+=qHGXE z&7gtuNe)wp6MI#5dr|?tmfW1yI$SNqkg7a!BwE(#+d1j}W@k;>rs3vqjNPmB9PhsK z>dZ~av`3`d5rVR7O&VTWc1QB2wYFvPNEM6MEA;|9^y==454q5#Wa7?KDT!P@!F&h< z5sCDj|1vdt$aErT2(y*1;l%=uhy$uq>mky&SV|DHnwm-2Invp(ddwy9&5OJep!gAC zUvXr9jX7#tSX$$T%V;N(yp8u&Ox;PO9n|;PSyWif7ly~#LW%N+QkuFiX7sxvQ7AH+ zV)Mf_))X+J%Nk+u$nD^iGcU&Vg>?v(<&tu5?e1D@YydKvNi+P&&4vOp}!PD-P+}#S%53 zX=7155}GD<Dry~73Ja`UuV256C=k=K@9Om>{eLGkVLqHuf32F6NU zrjM}@97{OkDpXK8^Y;_c$z^H(9g5D{5`kFUvd)8`NG!)lt34jyu{U2*n$QT_XHqP7 z@{Z)S!+0C%PsZ%C#V`R+eSTkXn9148%8pD|G;(bSj?&w&T5@I(=9_d50e&R@01*(a~AK*^s1&TX1c?upi>##tIE}J4=gqnJ@}4vLVu}e$%8u z|ED{XNhh(y^xkw0*U~n?0$MN6g*Qyq=y>R~WkZZ_+B;7wf34I*3A&!{os}&@w6@bo zk8Z{8M57Wq;|soVYdE}WwP@Vg23pC)k}8v}R6JyAE@l6C#N4P&nX38Rks>w>m*5Y# zSo=YA6!9cvGelWqzWIU&__Ta&&LD}DbUU|Dd2u(U_nd#b*R~+=P|f!0h|sD)+Xk2} ztMbiYx9S5&O;5zBbeLICcjj?`Sdjn$QiB`PnzO>!ksb?0WGbsnO*b|ddUkSR5ZN(^SamyO>i%Ay-oq^sl z=J-8YS{$PKZ1FbxJ_sUT?GN@|8-arj0a(ZpxG@zFK*3VX<3Odei{>+%8O!aLug+iG zH)PAT*$%o(22Ibd;4S5|8~T|@H7Z$Gess6}ln62VwLArrp-C^gIv%KBZOPIq@*2r6 zn-c@l$9If?So=d?MasUD8sFH z5Jz^F%TaoNnl5opmJ9v-ZhJ>QX($g~ZROv5P)sVP(Guc9b~2eK9k+Le8X4TukU`-#S&fy6fnkiq8XXoU5ztKDRLJ=1%cP z4i?7%hQe#_2_HW%(9@;&Vms^s);|VbPhF6vo_FS3YWw%@52n?4DcsYqUGS66gAWF| zo+3BYPH#;}S6prbq{2qG-1ISI@IG9eRJPZg?oBmb>L$5jK=j_F`#jvBuECF1`Ko2f zv16UoS<21EnG;!s4FU{Nr5uX;8}`jJid`BC`w#6_rMe2PC2Fr_Xz-KvbR*XuK%N=6 z!80Rdrui)Jhp%YsJyv{4WTCmUQaGWX-j1YKKZRW4i&|MLJn;w}HdnwuszSrpMMg#}~W_a73AdrTL{7T&B{ z{9Hj|)9pypIX_c-zs#$^H!K@uylEyFTBRuA1~B$Xxto73g@Bhs)pi2BroR-o0-0Ij zon5fPJre4w<{!`xIINnVTn(%$;ZX)aEV4J`19zS85`pi>tX2Sm+We1KyJ!Q>)<;T4 zCbY&8){6=>6^V9ZT&J(*DuMkvbb}LOA#G@CF&D@N`!42f-hj zh)Llw#a@$U!ZHweWvk`Iw~wHV!Bqg`eR{8x3ckype*R!>!dVrRG;AU2nnC8E00?17 zb*2G~5u-xrZtYsrMtJDU?3;UAHj4kmbp@nK9?WD>zv~YU3kMz4rHG0dIST&=C zEQ9mMBI}6+Z%yl}Tc6lT@nZG7nB}dq^3&10#2&>ntkUdtx@vP$$yW%c`S}OQcD{_| zYi^?WSFpzHIF#?XBPNA07FzV)%A&eA{w#YmhKi2+4=jN1f|vgIz1@W|d(cz&L0LfS z6PL%Q_g4eI@iGH!adRq0;G%7UB$<+YA>dvbs?oC{qQ2cLm5J*PR5d$p6|N*ap3 zA$S|rMK1pPuW|Df%4`nN7pUH=be}`(SH#WB-MOu__&tf>l7D$< zv5QY=>(dKbxf4rnPqJhb3;cJHf>cU3bk<=>V_XGA%ihMuH}_tCK1I4 z{&gRWXJ{SYz&Pt5Yw!)YS7&cK^-ffmesA)PswW_K5AcPp$Ba@1$7z(cGzhx5x3mZF zBdJ`1!!m^iJ%v)V8)Pw*T0o@%B+M{kUo)Ykpn9NPRV4b9+zhD9R5dDEy|{C(9Px)X z(QS{}7d)sb}Rbn9_Q-z}Z3eJE7niww<&iF(avP z;;Z@tqtIT&hLO#@k^c`-Gl z$w#NILl&dnX}({K15<;e(hX~L67FKMyWKUQrb?AyYneNo#n-ZOP0-!At+itZ=drd_-}NG)xAC2Mq#!O^zc0gSQR!quD$iMAokOe25u zM8s8d>mH(N`!YvLuxXvF{d6oIOq~WsapDqN!-^^wBt72z!f+VVM|{dDVcToC z1)u`6SP!O$C`M4>a4;eFhv51=%^HUm?}p13jk@F36U^TwQ=c8@ zPCmaV2Y3bFm7q|c{~K|wU+7F^X!p%hABTh86>K4up0tNo7}n9K*eb5Z6D*V2J}&D# zXQif4Ky}!PNT!g4u#xN=^kLEhS0EAJOBK9%RaT*A@xS;+p}mMFw~q9@p849E)<`D*Yy6lQVS_hf+ZZx;?buAmvmduI@-EuS2B3Ocm^?u+T0Y6I zw?#7{hd?hzaDp|M9tQu=p55c~$dlCigat={-*>vK!?p0JU#{QT-njC@wU*U=&3D#y z?OAyxSyh0$jIG#1`?`N5*MG6oNAYbrn#CO`_}WACde0%8nz_XqnEI*~zB@vh)OoM( zBv|(ypsk)RjrT5dHnS>gUcdD5x|)ByV{6SByfEOI^QcSC7#SJqYN2!1WA7Qn+y#nq zG>e6DorIF4PTD;`&@f7aX%+fc3pH6G^*|HWf*)1^ZaW{v^~^a^!>`C8y&WBIS_EfT zW*JOX)HF)>$oLyxz-?Z;Rj%fB`sMo|x3Ft|cw6E)PSx>i!;DEEz6u*U#z^h*3-Vvw zx7x|Ixe)EopDl*}j{8#nPq;4$4?!EY3?Cs zakIIy=@@cRTRyyqyKn?=QcLDLm0DSRz~z>^Qn$YLk?LM{$=Z;- zpn7Sn7D>USomn7lLY+`eQKFz!fDX*vW(V5{r<^Sb8)qS?C<@*8sV};tfChFg80Op6+Yc}e@?Xw7< z+iClK7=)BUCdq40vd4dPAIh^6)2-;+=Wp;87UH|IkJ}ZMx5z@$G>;n+nkYrg-Pd(7rB-vPfr%RmM z=%+6Zi7dI@Y>17R$8b){xgK-3WYEVAuUf+;Jiaf7ZI=V;1VJpCfz}6Poy7b*Fn_Pk zmjwN#9x=zjx9_fLu9)$iQC1m~u-_=&%&dx*F+a?^4e1F+P~hyn!zDi`|FK6erP7q9C1fkoRQ82eso)?BbH zDPTYjZZ}vVsVIcZh{p5XMaS9%(SLy3<#D+2T+f%7e&K zFnvD;A`ga|U9K%nT!B6wkzFY~?;Et>zfXMuLr8;R9#paDLq!x|DIwD!HMI59*q97; zhUUo*iiLa5t%y3xWjOcjBd-$T7_6hHX~*17kbJY*aQniU;LZ7JnAEZ3dNy-~y#QbT zUqSV3*!dXYP^cYBL{&#$AQ9(@MXWSAJY4dMA0^}hWVEm+Yqsc3q?OjRFm`*xI1dL6( z27HkAn!~|Stsdv26DH{t<))rHI)d-C|3w)mZT=v(Is$JbMj}BG-!5J=#(y)14dq`r zh>co+1!c7oT;q~=)qouJApX4<$2QszV=T(A2?v=FlNI~Na77R+^+A6GadKo`FR;Xq zf5&`oiAuIH-d{GEN6)av$bktH3O7zLGZTYvEB@KXI_)ijKQf<2j~K6f{el38B?x!3 zI>a%lTLH;N9ap2&CF`YGI!Ik0GwM5vGls13k`rm>0EwIsAmcWtPp!Z~^Xfs}#f3X~ z3MF8~1k1#G=b`m27)TsvwlFk3lynG(3?<1*OP5PfvDS46%EAncp2BWyv$(c}iH-AUkE7(vLwP3_&4{;47*dS! zUppWWClABtI}2-IA!f$S|_M~G+!85<1Q-)>+O)U^P~4*Jy-_C#%r zJJ8gDz1x1cZ(E+QMx6N)+W|x(qdp-v|d+~;k zE25slImDRzA#rx`5LJ>{yPJXzJ_^uiDCFl5q!->t!5>MDVni0f4zCE(P164<5rNO+ z2|Mpu#CVAoT{xANBvp22VB)ZV9hNZ2$$k)wrFRJ0ZwL^c5zd13$aLZEjnk2l2C!iaZ%c&c@ubWO-wXmK_#T3!_MB+kyP#0Agpxi?QVD0*Wzn3r4Z1Qy1O^ zD@#c#^b8avrkTVH%*uNrD$(aS{f|)uZ6}JEaR4Bx*X6pmKjeug9C#UlADh#^MngO7{Hx zY%KR3S77z!L{l_)!5}js!8;~`!-dHr(yLmzcTvCTGfo zShv~}2B3W6P+meO3J?-mS+=(p%!36RVkGwyQ>H|%S{^Z+gV+mwc=zD0?ziR9(4{_f zsOw8`6)+C%xl4x1_ph2Mn3T&{h)HqUgl;-10u5p>A*0g|MWU*ne7r`52#+pBIF7`? zzEg7AyAF@ZjzsD9ZjG3yQG>g?5-nguBLRo}MnL{xya6H_mXw3yAAWl0k2D4tC`o^u zt{=XlX~pGP+u3Lxtk2Ro7LM$yYANZQmSD50=%`0BwTKEmmoj-pMOkIJYbGiC;rt5; z>*q8KI?d-ale8+~KCNE5n5-9X3P-o$W8e2b9-3}cSEt!yV~>(`S`23E87rSNsyl74 z9g>f08`0G0_1f~SN7I@Yn|rLqDN1Fmtaj}=#95BX$B){M=YXM|{6CJ}wOpSG98gcK zINA=yCYe5`A%K5)RlSXVV+1!3N#d zH1-o~JKy)*oYTkF=X?kBwlo?>uVs>@;p$BR%0d3J0Cz*;Xkj%Imd-McBPG(m?2cLf zakdi61xeJC(OpRG-)adF15oF~C=R)P6z|h#`^dkIkd-IN5aT|($1sjRg+|mn@>%}m ztY4_)V7sZ|?zQx12%r>GY`@RtQLvLRiHU~9JpC~HLC!TX%l3G>rTc7n^oL%C`&$pw z7HQ{{ky%wSoW+8nq=v;Yqx$Njw*%Zo4zew9XVH+Nt&ak`wX01<>XreGbek< zotbptq5i4acRV(K`tg|2BovY{{9Um|O3=MMZ zvs5W#RS(Q!xOKUF6Pj1|8zB27`Z+`1h;9wA8(->3qRJ=IxD&^6M{_%;As&C7WA!wl#5GcrT_){1V+{s%(CIDBi8A84 z3`jEee{%Al7XQAILZAAyjA39o96_|Pv36C;7D*SuuP4{*I$%_Q?8u@=Xz}zU&SnWS zj&tI|M-LBH(ON|XlfmNQ?{_#YT1x0}04RGDx{i3AQ7pK85PZaTJv%aRI$m8^M`w5b z(I3Ynu}wl8-J}6C)*n#v32RqG7SiO>>Vt|G3|-(Ag#Ic2#~z!K)|BzaKEjy5 zEngMoEVuJT1pNNFT#^!R};^xKm`Qoro z$cISaN+{QbNT@yaBD2oc9~Cvref2m5 zgrC^9-fm3A6|;=XZ>XuKRdnx@Z?^keWi!DynpoP87%5lksDV?;JZd zk<<(&Ot(&JlY^CGTepH`0wB-_FpI5|5-HB9JW0}gjKljo zsUB_QmsV1zd{ci9B@?J`ZGP9>`V`hP17qW-2;xymzHf%Vj{k51E^f-;e<#RWrQO6? z9#zE_C|l@w-ULfBRq=8L0Vdl7mdL;CSovCd2nOU2k@!0nPh6{V@Ix)i%-P@f?bYgwjUC@?e%j9zrU zGxD|Ztm;KgnGc=~O~|Qa%mq1e?uQiugJ51086Sz@$J`bJBE!uBcy^fA`G0@8#6pqn z)iEaTaN7ZeRW52Ke1+0{tMm7Ne`EBWReMQ@uUf)QN-6q{<-9uA1a{JuJ}Dl#_R2Vl zTDa)KkVQ!yH^HI)VVHb$BPzaBJY4|rE3v)2vb6_1=;9xP0^k%IZYex_*g0^e_>C=1 zZIRg@;+5z$RPjS!KY$qz*nwOx-(aXlDL{Tw$k2(dsB&9hq`^Yo@p zNS@ZG`N8(N3A!e^m(`s3jYZvHwxIMyvEJXcoaj*OmL8V^IMQ)lCdK7p5%uJYf zff+!H6Qt1Yh^S?HEsCv@nlWzb!K)@f^#L@LE?VRcmsKTh?Py&QsR0l)5HP$DZSiDp zR6^Cu*0f{kLOgJqKzv?3Lmx~g}2^IhWxxhA0@L33Y^%>RAv6TKVTiR zeKtMXlc{7qSNRx?3UDn&A@?n6mIrGzmN`5AdGt>KQ_kw?vMhbr?xjS^JM8_lMKPo2 z?M#D8i&g^<3K=hf|4wcXz8iM^ItDvIr8vA6ynM3XzdY}%y7(zt6n1T(>a+#Epm^0D zMI;FWZj%3X536*^?|YZ_n|PmfHJmUjPONiJa?uX4Pojhd4E>FD^fT(*8c*dA4tP z?sI9LSwAfSsgoeV5Dhun-C9nwbt@U?vdK0;kR4JXyOZn%8gfVq7(lnV_4w@;Uy?Uk ze<^3Y<95-Q@>H0drq|hbqqp3=GgN6 zcD;XNJ^r|M;dbcR{)gp$A?OC#k)*5&s0;!#4(&+fKjpjzZgW9#Mls6h(`YCNLtp%f z99meGSmdiNK{6`AbIn-nCPFXg-W2emPrOwt=k^M^WjO$LjJ)pazQt+3@a&WxZO%fCKQeV5-Ywc}~b2}LKd>;|aLt85OcE?9d8TDrlPy5snWx?Fd%xn-1tlikDI$r#hQW2U&)+SYVtB8(dHc zAkq@|%tN%r|IxUm0r&Sbq6Wf(o);r^_#BWgJn0(@#UO@0?N36=9reIXtpUOh`pbT# zLq1&G=ES5W>pdSxBTGf{m}X!p2kJz#)(M>&HT za}LokkE}LPR!`K@M{Cw`>-X@&k*gq26-ytpT1l_$ORL;fwaGd5(9VYORX&i|%(wyFUtE} z7lq$0BHXte>U>$`zHvS155-nlcyXFI>wuDCgrx|U$B;u6QtCdNJ?Ba!V2x;HuBx(p zPb=`c0Qfb6>I!4oO+uS;-V<88@h(q@w1=cIW)XXt7$Y8Rvh9ltF9F*qvn% zVCO4)E0<#BpssoyNH_wIflzKwSX|SV(lL?fP-1$4r6DP3Pq;}HlC%_kWSmeSC?ReE5h^f zv2T)J$%wjv#m0>N^(YaqKxAx5Oy6m&L(p##iEeZqm3vSq*wp#_`0TJz)7)%v^aC#d zc#a};T9JUW`%yinKV0fypz{JFbcx5a(trgN-K@*QGMi@ zZf4EZJ!1wY%v$3V-3w4-fPN#lS}#FhM64rCpG~7)Q*bHhRl9xzN7i3M%3rDE(;^j* z)fQj&SC4aBV~qof?t>w^*W}0^1EZZcQHYUq36^xZ@{GRNtdT_^$C#X^k!1ia#iXp| zD&RR#@Z@kbEZ&Zqv%s=KvepOO+Ox>lI zu1C+3hGq;7Wgj};IStak8cR7t`Xj2lV~qDjhDCuX%2Y=GXupdOD52q{VJB!%6ihkc zA!yl0?w8X07JXz#07rV=dJA-|bI;3GR}MI=Hw2aLJ^8r%HiUNoMR)^TIYzX4t914r`zYJ91G`GF;g zHkcIak3a3Gc|t3vT?nbHSvqRzIpKnnmn~tcZ*W_!HLn`uNsLct1!eUP&avKJ8`nNb zdRRzXZk3rTrtANqd?Qw+5D3N}kJfEGD7P&z5gRuL8rPCVisX1DbH2-xAj|i>XPsSF zR?zSgZ&+BH?oXJvg)F#lvh--pSwoxLlCD=&NNENa-Xo2do$W~we04t99ds_}MCaHdH) z(MNQ-kCYL>u1yXISr;p>6&w!UIPwbng6g&|;460_HUMyn1VcczbB1nxroxuNQ;Ats zjSF8@c)l$P1(ENIX^`%Znv>KxmSM$(9{Yc8MF*h zrQ{8dhlb<Kb))ofxXZ!=36II;BYxR?9!)RNb{d;; zS0ALWX3mrkU`sum%FlcC@s2``RqqbIc3@%({gv%lxK4%Z(`142=J1;-rI1XNs~>1 z-e(}p3+g7kHFdMe)e(NEFL~xNUydUtV*v9r1IV1O^V9C~duX`J!zg)wHa`ng-> zcI|mIm~Tcg2}Lo;aX|(L$0V54!y)c_+D|dQrLx{Sa_w36^Y1vfjCbjDcW0aw1v6QN zzVH{4+iyz>Hr$~5yjwHQ;8C7!_XZqm$-A5oR*Ii+Ro>}s(I;ESFGjmHL9?E3^QSM+ ze?`l@feIAB_<#PSi2QfaGVT8~TK<1C|8C`NITS(EpOByV22E7O$N&Jeb?aR5keMMI z269xiXgDU_oka)UM*gNo1GhEs?cQKo6QjpI$Q!KK?vR@asT3@kcK!HFE4S&)YqsM_ zRxLljFVG$0CG7ck>SnX}a`S}|3}8x~;;(go|2L`)BWh;Nu4_p5^UQpB;dhRLP`ge| z(_m~-WBYSJWea(L2X>^oQ5YD=FvI3k;D5S{Cl4iV+1+E!kBS)v&Ldqxi+R(wkI`n2 zvCu4ob0IF+_r@(HxZnjJyDOG3XEn!Gai)9OURoIeSIh?4@}Ww>UebWpu4AZ;b)}lq zP$lP<;F}NYkk?`uGI!Msr(!-A7apIl*yFA|>{HbvoyDUYH*M#v)oS7W3lI0${X8d0 zp<$R}oiYuIeX_wRP8QfmQ&8bn>J5+w`y5dmTX3oLipQ^gehUiH0NL2kd`McF zKDL!(N}fJY;en?P0?-;aI$nePFjDXpiGHblaN&upd#}`uYL%VFx&RX4hjJAq z+blMXOiP;$_hf^c-(i-4#-oZ(CK`oT7pc!wmG>)um90c_L-IQvq!5-6MI}QD9vCcb z#{A*9QdYshjI12CU|`5`OhQ?+AeI`W1vF8K<-f5|9+7SE87vZId@q4a9T>xG!InYx9S=+=1?S+^8>ZQ;ZwIyE1 zYvdFb3-`-p)0r&J$t=#@^uyYpuLCGQwl0(Yt}tPAScatOs3_eFGaK_B8p8ruVBO|{ zAU-IUCZ@60B)H*Zr6y7}l2l0xX;?8^4@F};@`cKpXtdXb4Lmiv?gER76m`|6ENKnt zj;L2GHEbY$T_nmF$qw1^n?R zin}MJMiR#Oom#r`?pL*eXp($9Q1GO#(e1 z=LYw7>(3Wg)I0-!c}aQI#^QM@PEr;ljikgh0FD-9(vt8YgNhvWw6Ad7<1hx582QB8o;(9BByE$W)-*q8> z2y#|a@G+$ZvG}rIqkMk{(rINH?{yg!b-zxz9lMoU&Y3h0YtGI%Kev~5;Ekl$G#VT_ zt+sPc>i?SeR<{q*_m4!c;~}ZNwJ>GIr_??UmQSY0;28MDmmOJ^ z`9jXS8^Vy^+Tsw9Q3mB2p!@U_?yD`G<+CR~p*^Jp@Cqgo*f{uvoXfvted0`)ItTV1 zqP9(GymFT05)A4=2kjal|HM^y(I-8PKF#^btv`?kr5T`v5;Go>tq?ITl6}RexucX4 zG1{XT#itpgY{#d`XqgZ-so}5Zg27bm(Rr{>p_mc|BecC<*fi!3st+6H(~5A*G^~+7 z?HE^;)2Z_J28YFsdR24k8g*IzyO+@U_Nr7dOzpTx)kVEyzj#ElN8YOZ96 zKe*BN1h=mxw&e>)&0^jXB2^;UHZ6xWw7oFS_8~?P)bhpr1Bph*zGmq#f0|r&&q`u{ zC`(p$SD9Slp*qTRS3mxTPsaHR|nP|7#yB{N!*&%|1GxUqY z)k7zhd<6~-uE^R_0_B}-lh*zx#C`~lsz$Na`mvhxs&Q+o2A^!S?GqwTDN|aT`mvbv zs(x$AhHWnDNSpQ|8#=JpOKMG@8kk3O z3SQ?^?4Wr;UuS=fcVdq`e}nlJF|+NYgxQxK)H;6toAz76(VBt`J8P`rVA~(bQn)3c zH_K9Am8io9f$RUr2@qADDvQAW{27P-@0@`3f9wRpqQbV;*8drc``ht?~kK(660~4gjtCO1{FI$2R3LKt%6cT}C27JHOQg3<& zn5Dbm>^z`deia?0JaeCI&KC0E#1kX;0Cj5AUU+pWf$49I38iHOm`?BitckFO7AqA>$tAM`7}@V+5{cJbO$m4E}z^FoukV$!5ej87A;h& zr@E5ue{j=edI3ukVY-}z^B>y^LdJhxNIYyv-ctU3lB>4?y$^SP3|&}Y^K+M zx2csf4FK)PkNLEX_K z$JR!RY!Z^4j5P=XX-e|J0sTVXdGAA8KdqSVffnrTwA26VKENBM{FC|?*o$OovkgX3 zPl)}PRukL|MLTc<>0?I`Nj=XhRqQyc+hEe^K^TL3IFKlOb4eg1Zykxwr(^ zi#uH0-CYvg-QC^Y2@V%`cXtggn{WTE+S-TxYxjNL=1kA@neINRULOAJ35rq5gr%fq zVlgudvYQbkGrpv`Z$DL@!+Z}oVUh$zFaO?zQTk8j zzlRX+za#K}7lN|?f0RGa!WL-Y{=bB}aa&gCLa4(%30?c??!|S@O;zGHHght8nc>F) zf<&@(SQ#(5-yUq7Hgs#ctfd_pdV7Su6|RMPVa0MV68-)Ce)%PG;m4@;!EHLQHQa4H zk6)Zm>23LbX$_|(?eXpLc-DGXdgtkNR43t7&rswEp2Kxlr|*lF=>RO$21Q}wtqelYLsFy2SfKYcC<4*7A+;; zB)d@|CMOa%n>hD363Z)p3ku2Vs;;>Vj;mLczOJ|1%ZyTn+DTuX&E<&axh86CP9jDR zk2>&DvJ)-W<|H!!R~2(k84-~~%jz!*O%hC5I&(acxb)0DJh)Xub;x(MHWW0@ek9M= zQMrj+#R~YbM+AM+Zj-Mgy5MZN+7l&=rjB=>Z%?h;WCE0enV+wS1&qcW#_O}Tc`*ZO zzTRnsO(At6vHC10d$>fX8tPROZaZJ_4rOb=Qu_{$>(#xcab9n)U?FMn1yBm)QV2M@ zBG180ZJZNywE8cT-3}wcey336p^dvA8C-K4gpGuO9tf)Tz zCnvUs{O>C1{~btyCXQw%Ks#fT|0<_>Iv1+%DmNswP#xi%hb@ST_6-xFlCV9o z)#+GFxz(OcUHR=*B)YnYa60m)E8bYVLhEtWSK_XTZ4gA9nd-)*H2?h);GTr> zTMlM)R;_3Ed(U=1d;ltnk5n6x_9QFbf@n$`#lT(TG3>QAaxL`$8T^TcLi^Wx?b-9qfc zxW$Z-NN46W9bo-4n$eVBau$fHVuv+GpW2?&g!x&pq|9jl&|4zY3vO^yHx!{ zuhJKK>b1S(E{PS|CJ3E@LaTngIx{@D1eQ!9`+A`dx?f)a^fdO@f!zo^P9%>M>lRfv zi4LTVjiRrc32WP)8cpSQ zA-nIGPvnf5jW78&@}p|n7AMe~tycR|o`XuesUEeytZ9 zrZcziZ&nta;e}_dy&By`XBBO}AUxa71t$favYjJqLaQ=$O#?M>@r8VCmZMZmF({t) z;?q(!Y$PoAM=!0Pzph}H)BWuW)`Bn+xn*%M-KjT{k7aAHtprlNXA?{a&;14p3JPU1 z@blYIfpygldxoo&Jf2`zVCp21QB!orN)-Lnf;qc*dfU_Ekc^?5&NaetsyFiB?7448 zk&9;fv75$fViEUSeo<7{&r|L~GqoeGpST={#k?j_>CCc)elguJHb3DarBI)*Q6;BK zIwE3_S}i6#E0bVUKZ2{G`~cG;gnSuA0e=oe1LC{6uWAoZ5}{C@viOp{Yp;{66a5TU>%S5xIzyfV2=2rV}nx#1t#or-I=+n*JPSW7NrU=qMDRT=yluz{SCu)87m=Yifu>L- z#&{sNm6y+u>ytyDxJ9-07Xm?&czKC_>e&NKiq?oXOM9Gnm% zROtD(wErEOeKKKK2dGPdL;5~`FLzb+UJ)Jo$RQz*)ab0O3fIR>Nbi8SW&dTuM;fR^ zTa&zAAKf6((r&SDZKxX65*gIF;iwVb6f7LKV;X#{DQLU1x&GA!c#0!<({RCwr92&^ zO)w^e%YUu-F2Q*?F-sy;B+T~gqTDiul_cnVcxatDnK5MT;k8g}sZc-fE(m>6+#rF2 za?J>B-mRE1=dH$c*B?wTYPr_Y`t!jcp2z$!r4uF3KaKPFIfx<{k>98K5_v^_m)za* zfyhnO))2(xaD%ig^}5Cf-{lLbt_6iZ4opb#PwZ0QhdzX-xtcT;D zp;vLmSzGBwOqf<#8*`Rc*&6eEe01C82~{0Ai(fESMFNJ%F*@q0Q!#HeA*(8vpH{jc z`-#Y?%Vy<)3RBjLz!}CnU2hpZHQB<-FFxvZkT~zYS(TaZROJ)#shGgKKy^CBr^=%s zzL}m+gz+qe2<3@Vb@e%oiaV@drf^0o0KKmlr;tT>ull7Zpu%!d=;wy>bmb{B-ap{tT6mxH|?_%#_8kFBMm~z!-zWxKE(3@etr!<_3 z{4BMNF;In)rbH#*TUEHY|I-F-)~5GmjZ$jCS$>Bc=kqw3lxn*d7%?HHy{-X-6qxgaKD5@dI&;J>T_9{P=P4EwcRQ_8G`sbVbZzIvf{wp5s z|FmLt!Fl5kVsgEix~kF1SZTX@i%Mn2uGMAXAi`}EJh>9+gTQH>IWxmFXK35sAF6NP1DWKgL8`Ln)$Y-WH)t-M9VgY*5lZJGp7_$8@j92eG(>30`<`Y3a<>#bgOQ<_J^QWJPyt zrEaII4N_MF1vOZ>Jz{!xw0NunMhr+ib@+*3EOW4L=AJ#{3<6^29buAfHgyS7g`_>5 zrs>ODF6~<$81z(%>)edCJsprBc^@Pb&NdEC2lPOf0!tj~Ryi$hHA7~s_S<_+S??Fw zm(uDj2sD4T6Srwvq>W#^Kt4ovZVw#tCA=L_g75)$dwhxhr$~5HM!7BRJlY6do0A+@ zm$tw%)7l?h`3q}FT@~adU1oZ&IW7Gg7nimhm#3FwL!&0x_*?27?Q1-7AH7B$9j|;o zUJXmG?GL*N#bSS1z!Gm<0Z(!@6;nEdx>F5wH<69uFTa6v`Sl-uxt~DZG8vS`qas|9@cCyc# zss;8ZZ4)zAb}{!A_FDx~O4igbH!J7_u~XQ#CxSRw#Lgug9NZq=MlsLsAD$Jqzh~|8 z&|E7E<66KW72K)PYwxY$>b!iybg4x`Yc}bGAS5Dkqc8na#Aru#5T1;XG`VziG!<-a zob~4bF09?xD`hY!(>g_&%ugL>i`{Ji10CZ`IZtp%qpKaQo2G19{#Gv z)BCxaejg6SKVvQje!H|V2qJ22!*ni-S{^L(VjG)8kGEof+uK1v*3`D?voks&(CXGn zep+@Ut5r3kVg6fSZzRd-#p&_AH2}jGsXC-3qPO|}2CyhP#}q+*8+Y%49gMLR zNx3Uq&eJEsh8|M0Uc0a^wbNbeC&p8qOio5&v|WXb)zz)F2vEnwfpILrql4`Vqj6EJ zy*8W;zydU@vgY!(`OHzm1F~1R!XOMKV6(2oThZQ(IpTl*^pFW*!$cW9Hk_we19dlD zZZgJ9Q2|D0LkU*SDCLBe8@&}p)k9-TXQ9ph@(_Q|xTgA~@euZ#o5#`FzsPRp;AH%e zAE}c1cAEQB7d6u-@U(TxY8?Io^R;er5|ajzRpe*^{m%e)Am-}LrrM*U5e)*UTi{%D z^`R-dTWx+zW_DPq+Ipt7d0+^oyvo%j&yg6+#zL(me^k?elZAcDd%nxlt)SjQd#qJw z>RhA6yHTxsTLcDUiQSSGM{d$>&Yg0|62FjjI6GhyuwlkK^LN?U#>YazM2M8|XE#?m z88irpwk8q(U6bR^YuDxUtmj9pr=k-0eS=F;EK$3zyeeyF!v-&r151c9|2Ez?DN1we zY;;A+9cWfO2xG!Wvi-sKrSpjan5T1r&h9{gQRzPsk&S zEl)Q5(uIVtaxEC!A`p!%R$-uQs~D?o*tOwOT@`99U($h6mPMeL?fiYLCockjG^^25 z_EQ_1s!sQWJcgAE&X+>n(0aKyE{$*}cEpC3C#S*kCGH7i+xSY913Q5YWbf%%TccVc zi25-$y_^y1Q?V6odwrj$zrx=wj7>Ws*XT|fsoT=E)RBQmI;8X+HPX0CF)8!R5*b~$YlQ!?%ctZ&`@-zp?e5?$2o*2Kvy(IGR* z8v>ydN3cfrFyvsq7f(l2%vipB;x(?4guNrHqwa7y=)~(~E37o--D&^!4(}C54A#wx z*Hna##k+X?>(L>(&J&^I!$>B8)YZSy(v+ehum%7Vuc&Tzmw!x79&os7WCb4z^4F*R zX$`LG|3?2)yWekN!35mmq6TJKe4^xuK^GM6!aR)}#bI0f1|WwAFyN;%Z8-Pr=dVo9 ze$*J$M>=iPfj zerz8y%C{i5T$>`v%|ThhB=x}};%4Doog;zCacsR@+>Ufr=)mGo1Dj{zE;lmpZB@RI zWoO`FSLch4SLH0lem@UfdHSfU|R!&1U{3vv-73 zRQ%fB5L`KbSGHO_*@1UfNkd9fTwGkt#ktRBK?CJ1n!F<+WH$KL9f3Ryaks1Qf-zEx zr>krKS9Zaj#DH2R#u46H*v^rL9=U#zcvdts#5J4dcNm6U0_oA*hNX?If}1wUX_9(; zh&VySh6bWKVRZ9gLl)G>OUDd{Z}qKq9d2%lwas6gW0BsA>1rT7zXyFsO_lWS&*#;G zxzUE9>1Q~8>5Rnd>|4dC2XN^n?^{PlqV>6-vc?)r;lnJGc}DaBoI(~B0Cw(2-kjw8e(+n zi~W4|pF&E|I5~N6{_7S6<3Ib8lk}50+$=E(L*e1x`BE%N+;pCW=a*o*9!{7O8I(;U z*Q-M4FiwHMBT=Fr)9FC@2P4LVTvn4}uJjYMMY^XQmB8XaN4t6a@62>TEm-l-#SoTA65G4{Br=<#rP82hf>D;NwRoI zv@Yc=2`^e!sHdbM>b5}jBmvA1oK4<7PS!0m8KvV267c=LtApQ;+O&PlaR0k`uf5+T zy;KY^Yr`db?5e0ge{oV6*>9mYoOoi$!B^U#^285)74d^&H}w~c89K4)G7aZ1h$l~g z`ccFRu>ICfT(jvuKfhi~jA!7^%jK9%m9jm~h^FKI@5ODYKu+SG3Kn;|9(#97=nUB_ zpe>{%4^!HXQAZ`lQc~Knd+I7zd!6?clx1FQ$kVlPF)Ms}F3>C#Qbs_CwMc8kFY+9B z{}Cauh%YpRqvJfH&W9IN4gZY%CU^>yC0Oi?vudZ(dpu44;;be`PEi=bt8N~j^iHvs zskSF*-t*)8-*y(*bSEGq(g<@UTubu%aJR36Ovpm9ru(H{q>@dvhW#wBB7f3N~D zk-1#xLE#6`fBW|-XxTM|;qdfaP+m?6vU0^{+NmoFcn_gQGJ&+PVyn{!Y~voX`hu|! znf6&FV8R@m>W|6pH`JKe)E61hTWpU(BWtJHElz9#-G)F;#YPpK)HN(GVyK^jT4i>t z+ES967&NW6i2m4WM_1RSaO9N2&$y>1oPqd+GE>r~A4=$Pl?m1B13Hc3iWuQhW=_r& zhrwXY6x@B7d{8_GMbxw^R!G_M1!MicvtWBIHiTrDCB=V*sU;BMJglyv8|k6IZ-y) zRC~oi_eDRCwv;OXU?U2NP&q8jm8Y@uWp}tbmg^B_Tj}lGTH>7z4!K4!+cWD4LXG%ci0#3l}p}jgoC@wLMrIyn{RL< zS1qcgi6@^s<{KuuxMSs?ky`4C5!3buh2YCC0VZ*W#?<}HQpg^Gh$1vWx@nsF+QSY} z8O}FEZkDv=7fA{0K@qi-l54*!?zHB`D%8 zepzFpCnm(8tS$ZQnmq(vT%PA;wXBJ-epZ0GFXBt2QcZrX5l$oVyvc3+Tp8Nq`6Q<& z3%4sK?64N~Q|g$~F{n8K7yJ@6S!m>Dlj^1=?}_@lPsWDeuO;Duv=WLbqnEx*1(Gsg z%+R2^G-fGrvAyR=9#U-qxb3S>wg76l%|MDGmgR$*O*TepAUCyE8Eq_%1-o-|>%~)P z-gNLB0ZZ3&c5;0pP>jCG33%0hdoT!uCIn(WY?NVYFQv%VL`SL9)2pwPQ1tGGta4lU81=WO%HKdB)Z$4=mnYfL?df39lKq?Ms*pmF0Gq_FM=&w60X@ z*fkHX7)4F<7(cjV9$c-ZsV%BcwU!Dw=Tp3@Y^rw`3C(PIwVkj$5oizCye-F#O4D6#w^>M}TL zbV1E;sm|so=|0ED(eE`Gc+||)P|9{VsHIktI`VkXhEJ=+$>F(9Iao*e*Auk4$yd?T z*;>v&dCKLb9alqF;Bxiw*XBaA%1g)aDmg!^-Kn4@ICv!#0qv@i$IQo9>G>tz245Sk zJVMES8p&fazwfJ^@>t){Vdpy`LuJ_yUp>{U$@mlKzt69a+kEL}A&v^5x$JmwBCrGg z0kA(sU%8U{-KYt>#=>qhvALzz@{?yqWfm*Nn9Q10DQCaJ-7MRzUtC)R*lo6Px!*TL z!`AeoB(SuosN33f#2#aJ7Mw;;AU2`7+TKi7MZLMw=(b^NrfCq?Ve!~_yDR#oN^7)Y2D zRrQeiX`7r!KfN;~AyERNHet@R7Bp8BwJfZx%&RO$>C4L;SEM;Tvydi>fup$JXEs)M zH`LN~HjjB~>Son8E6*(%q|$M>v}n~cTMO&#C$e2IqYRItPZ{9KD7_M-l{kykOxSH? zbwLd*Y@0n_`9(|W@it=gM?a7}T+M#B6!HMU(j)Bje}j&y^~_ox+sj=qwOeaiIt*fT z^_u-ab1%g&6IBk2P#A%S`M84~BLhhfLoW-PT!}Nmv+n!ri=E*8q1K1KXr!d*-9tya zFsd$9C);!C(IqRm*W6}6QS+>SU$lnEGA$lQ^AR?;giF9g7@11`Bd6*`18h}gQER!4 zjYYkU#M`Kp4aF2L$78x&=6v>xshxj=iPha0$JzS3z1YI9NsdWahp=}s#MFpYYG zi&ZFwh6>B)rR`?L=}v{OR#R#6>ebp|is)uE9ds>ZEKeT3KCXfbKUT}%&;Dku;Y~R( zoULx^db?W5T5e_+)>{ldTMeGF!>BT^D1Ouk8qrHrx#p*jt%Pb{gjRa{*T|BeV={e7dY8Bo6JX z%i?Ilk}Er#Dmg?`XzjmR`LizQwb+lHle+w zS%QrXFw50SIc27aB<5^6OyczqWHUD~eLTooQkYSgpU$kawb9ZPYTzsz{EY=pHFgv? zERr;C1F%4l;{*gwRWvrulNVFIE@3jQtMt@afySVIFj6)(7Ub3&xJ;xs7Zx{yfefYT zv*k*KA>tDdWiXP@$)nw8uP%(RR)h8D@R zP$GIKeFZ72tIH?YRgRhqljNLgxOoM))Ib0 zVUpNj%8&v*JLMTqN)fzX8$3PmL(CdoBIJ-Es^A|)jb&}Do}7#(Cq=DwCFbP`Ek%Ef z>uDF$LGIGyLjt0E%TDz8FDwF%Jc0=sjRH8j(-&4rq%?!8|Eg1e&X9tN=o@cE@YlvF zY%CkhlV+6f3$6EkMBxA0W17jqXvs`J<1yF9jv^uc_$Y&@cu`g!o`k3_c~4 z3gG+c&@3d;H2$T!U8Jy(kl*-`!Xm%D0$Z>2tAL z7rW?6KF8P{9qg6Zt+M9T_0B(nqDMz4$lEx>SWr!|R>_q2Wo8JuFDGhT(V%XfelZaS zu_TdOGVEVZn>@!5s6A<(=~f?#&|h00vQ3k0gQF@xHo}QJm?Y0GvyxQgT zj{KW0ekQccKRP`#LQ=g{+FE_!>2%n122SbMvbEcX?Dvu5 zRM&WegXlrfpGcOAl0zJohP1U^dHvSzImu^c!CWzmRy0bpyFQ8bD5>P-^J_*SL0=c} zwf%R$tI2~7F6c;uh)P8kp8oQ9Y0-z%--<;jP~}?8McoMxfy%4walJHEJ{jh8xGv*I z%fNlR(meE{@NWd=0*&N%c6ZJ#3pQ?JVWasxDu(~so3xMF0;}RrOtkH4EoqT|rFM{1 zHVUpW)iJ9lYs%>uS9KIXAY1jtFrGp=dB2=EEechfegR`>_c;lQh(Q<9tYtInJDPxV zlhss)CHLQq?V4X5NeO=9mESq+z6-c@uiw(-qHWFA3?9a*bT%z4WXXHQw%>+w{n0nQ zXW!%E9%m)wU{QIdlAo1(4wLuFS25$7P?_?okMhKD-f<;8QXIvWPHV$psVXp|G8JF` zUFl@Qu(@Y@AyGkGKla^GBg*mk=p!TUR=$q?Z7KZKe!P}&Ty;Z!M*oID+ zAruo@xkC#|8{3>2c+a!OfKXT0j7B8!t!j`Z`}lg$ z<7_@xDzRlnFalQ|Puk;2$&Bx(lk>JA)Za~Z)skjq+^XV`w!qfhJiTHx8>`!80_UD^_W%2n7^D-)c#|xrcCgB6~`C}7Kqy<&h z|DAU?_JD^sgYTW~2O(ULtvb0Y+wi>DsKLQAMB~jqhizgscs~Uyib)Ttft_pE&wkYY zbA+XGAt*sl4w^7W;hnjhwWo}<=r0=&J+=iQ+4@{sxw*N^OQ$2q<;HANcE@I^a4H#K z@vFMDptilfzTMKvz+~nyeD`G+epPr(1U7L)E|_GN20bJ7s~FBxFBb4kNO^iAhud@* z3$p%VlOy2#kh}F%*U2f{l)DYB%u{pj7{4fQsG7X{q#+D~T3irdNkghsQrb%4=OacK zq@D-ROF*inu6%UvsCemUZudHi6oEnBi_DpdfE-oA;fa1^!Z$9*@^~t2t&mW&y2)^H zfcwmw{DAkH_7Hdr3WsMbgyqb&+<|L%^gm5!zhf^DD*6*#IoZR6lJ?-SG&dtraGC4# z7SH7;ZaluZYCO^ONxw{+HnaThr;GFQ7yf}+;0fYlv^$8%#9dKRgG6e91XI^e!Vg7i z-kWEkUFYmp7Qk~@L!v;OeLE#z;0IPhkWXpu3erAj4EKCKUD>%w)`9}GDp_C6 zV_QH4m0}2XO0wlHWdmmc5ri)lQJ&9bF4(4=x2f!JElk&}^L*BRY`o>MFgo34-Y-b8 zA_?`~1-{H|z8H~mNEnv`+9vAr^VTv%NsrtX`J;R_aqclxVW8fbtDCkUW0wbWG#cI* z&1$y__LVY(xA69_Pjelnk&A^DC;#u#A=c-D)?ez*Z=L7lc+S+DkHO0D!G1EstNxff ztGwPtp%3BjR>lfhvISZ^@&#IVBS92%_}w#-aeZkSE(coiamoQy@*ffmp4BSht={Jbk_~)P$Y~i z&mf*gdJb2#Pgqagz2Ftn8JDUZ=I`>rIfEq6AF8KrO*WVLj^g1eR_mcQ+EJD3ruZW> zM8z8U8X@$Ta|1cnmHvW3!O;D3J$t5Hf98g;L5`xUB6JnPUl5tr*lUFb32JL zVfgh<2E|??G;#fHgM4E6niE=5X{DRQu5%_qwZ|wP-rfi<<>?dH){Ut=6d+(s<@16MU={h z7Ry5yaJ9Of1Mjhx4^`k-L@YQU5eTuggEuQyxKQ{j7LV-?cZk~%FI$Nb*4bCEtA)hy za6&J59^<)F9HU*raQ%QoZIUI|3qv7jGAocc7+%A}V*KQICSU&qE@%;kE%iIv*%Dah z&#qFVN5fD;tQD_`#a8DGUbhET0%<2uT~}ZIj2Q_;<&w25mwv#JbwKBWM{HPYa$CaE z9Std(n2lRCf|Oj`oW*(>Of0tjmnv5F0 zn>LwX)Zc8M;!Wh>nAx4piV8Lhkvwx9UjEaAQ{FBcKj9t&K4D=&eYXVdPqBXg=z@oKNYZufj}J*j=})zs z^Q8ITc1_+k;v;QNX&NM$O_jj0iV8La$I_ z&>8M&$+cc6g%&uR#1X{9)6v2sWFFMDN>Vt7S^zEVmDOQ(V@$$EWiGhBthm`*_|RYU z-rvnuPv64hC(f40?jp3=TSMgN-hZmoS?K*B72UyA;iBxa?qo~ZJDQY=D0#=$y5_0_*C+Y>kJ5We|-h<4G~Xk zCb8Cj=AAAcC4AxRfz1N;1jh+)=FMcgrp*Sk@9NW#>K08&n=e?jyMw=^QK$GA$qQ zXoCgk77(R(bZaITJPMYJob>%>Js=5RJyCrEXH@TUCYB6D$Mcs6BAHVK%R~d}=szA+ zdSTCTL44nM70+IWY-gB9(#~gcXF&A4I>nXt(=^$oj4#HwbLbcM=DUH#;}X4>xB;!> zy(&`VPP3^{J?pV7i;M1YySeRy)!CJA;c~DenQ@i%xlA9|IxqOFQZk!lZ$Gj9%#a(c z^WeUJ4jJsfU$Cz3cm#rprllBW76`!}Mi1dS$L)D5E*<;5h%BnuD7^=G^P_hnHjWvx zM`zDnJa+yB&NjJ0x}OS>*{99l7z2yfe{h}+A)QX}D>NFMB{uD2>q!apIj^2ou-u~O zz4rCm&9PE&-0Ms}(avA*!{a6b-A`SWcp-t3vTDP@a9bYjPrn{urqZtwb??C(7<;jX zKOxNsj+A^us?P(JC&;Mo8q03FC&{t|do5Bl+VnyY9sjWP^r^*73Lc74+}h?pyRko| z+$6U90qnYpx=yf{C45B;|~0>7=dc+RQM1KPd3)TlEnXt8fQCSeL+*%H^D&Hf}>JjIG2 ze)9zWfQaWLuQ>|GXjj4|2b~x*F@G5OtA7Me>Fqy)UzyS`6j0x$cD6`He7=1EkN&*% ztgyblOK6B*99J1T7qv^Y$K#BCB&WV-+eFGsxrfPjvM^?mrR>$D{1ZRG-9G1xAEg~O zO&rIJC;E9`4!+*?`IZEI6ibI}Z{2?tThUAN09kHJP(s|gMR9+??MVk^-*TsOJin3M zJ%${1UK-)=H@PIry^&eF(fUa~C{M}7T@wzyo!HbkcAtoQg_oPWiYEy4A6|h-PDE8_ z;=7N>z}@n2X(%ObU*_CA3*dBZ_9I7p4JDS~2$r|DlFW?#g5HqBhUKH^o&(TgS|*N` z(jJ)rJ7^NGibMev;NjQjsHT7@4lD~DPqT6YPG#MaIK^HoLFT6TF2qR98+ANSBg7iZ zp#npixDXmQG_SD?N-o5`Fe9O7iJjatRP(A?7A%!EGJ-}TzjsL;TmMNRLwnC;miN+H zL4sdRqa9lim}$Sl3|w8H0xuqeTzqi8>yF#v&AA*Zwvuidb3$dbvVAT46|Vg7W2iq zd{t_I@pw0|NBqT=9S5M!&SOFe_{w-3C@0#4JsEU&(~iIxEOP@sXmlh+7S!uM!T9O# ziBza@st@yq40pp*KF7K3?2hjBFD~wy>e#=fF2!y8>l3~XjGub4(U@~>G|8{>-oJQW zdI35>?n(ocTJe4sQA(d=a7}^eUSrmGgWm(e_KrOfP(CPP#05C$AM^?btW#uPc^9Qm zO=FGYNywWxQ0lLOoiRcvzC5AwzHyER#?)ryl;V$1Dp-w{+_AA;LPfM*xgXB;dEwB* z`+7;c)3L!kyEOza(87pVgMHA*k=PwjD`UUFxdY5o$x_~X+#i)gL#9Z+3xudV3C~Kv zDoQh`&B20ao5F_)yh#-yYi@So7FJ8AHJU`;%9+ayahMcE%{h1=Z;HgJc5Zv@SP>?4 z>ft}Dd&vT%echSxeC4p^#T9>&z!(Tay9O`#3r)*GDTf%)zT49j{eP z8B-+8warzGco*55-Os;O-M61ZRZ1G7$$YBVxq9Nq#JKlMMSl*$#b#vkMwt2H@!L1h zd)8}WGf;{BH|cwWef?tUP}B2SOn*xqr))j9iJtq_POZWEH+v)|w%$!~V|sU+u@QoO z4h+19X@}Wis$7nQ>V89ViPc2ZyqGeYC}%tIRioVo9S2!ii*e`h;lwki1yTW@)OY9& zW0zEbQzv4d=e*&QyT%Ryhos9x>^?gF3kIyiiCHf}XSF|Y8=hVnMgaN{g6_rHbrCMC z65+7kcEmteW6(1<{vz;iC3bVYZ(AZlZ+);@UABO@KBb1_?_S{{c7PbVvV!42uRJBh zVZGZpO-m}G3!0qf^DwEssWCF$mI3p~q#zWJLHO@rPaPI^F;>~6bTXvbzE+DGQBvf2 z7`(1n0cLCcQ^b#S?pd@{J=11^#el~PIswSmkYKg zrH^R`v$GqX_z&#wBpRV8Q(%CX#glnmzpd)r<~wB@>{r{tJkW(NVEj0iv;p(-jsDBTl#(&PR5IFM`lXa3^|Dd%n{m5h z>UZ;R9(`Zs@otQu3VC{nn%pwx10(bFC>ZZ)uJUo1uJOT|GIjmNzi8Ijh|sr0`de87 z5`9Dygc7q&+OZ84xT0xMObE~+qhjiw3heFfU3n*5!6e%Di5qByt>aK~DzHg&A&EZn zLYJtYgNjAWdpPU{37pZiHKG?JG*tRK$h~Q$O9cT}w*md(1|Qja8KPG48T+!1nU)+0 z1fy~i4pNSl{Wpk|n4exE@1=IPP&H9Qa&pOj&NoLS+** zGU9zdZYZ|toDV~dwg?Cxsr~+1kX+@l`y#5KT9bzB&+L+wLF?JV`k0=>c%~2Nat)3x zYrt&>M6DVFk#PmAcsKVK1k|E%5oWOmg1xI12R`@0u+o$->abHCQlHG-65 zdrFKunnOk9Ufr8&kEN9h&kYNjT%GGfW8khOde*`hXIRG-Lsys-oSXTl_EsC_)=k)C zBg+m;gmo0Z<%r7~CNG-yNR;?|e7ZRrV?I$_W)sj` zo01AlP+EV5mj4H6arOv@7bTvYyZ;%M#r}~D~EEbZ56)6HznNHRJ(8O!f-hnk? z8zHG*f+ZnB!W7{2H6<|0$>r8{S1FXM^y~R<3jCVxd|3Kpu(&Lu?#keS+yZtpQy~#; zyQ6@wTl$u(=a4$0eqjD^wXT>Qf^l5x*U=l_?S(lZS24^w+U`I^ejj6~e)AISeYK<1 z{LsR8JiF1}7~6E(6N7`zQnoJk<(9H>JVV@&Jk!umR}D}k1@>p9Rwe*3M>?RLpeki+ z1xevCWBEgi)uP4>YOglLe%k5B&p$PnXaSm+z0^c8#0_ z^oSpO9c@i`t+110sB;Q*vN^>mo?ZArWQYki=W7S5YC-og{tS;cj_m2bvmuY1AaOr~ zcw4PQkjwaDC2|cF_YwLul!Y48yn}SIkMxt)XE=zti{<2k5AX#RQLic>8@cy0IM*7| zXYjDUR-F+^$LDMK3G26<0%Gc%`iys7f{$O;kj`IBiBR}9@ZaWfW;Fp{MjZ)^&6=}* z@5oB1`VRK)TSUXRk3$V^!a+Ll!`{m=>m+S@GB28Q^nZ_BkF+25+fj)zPEM+-e51@EQvx!W(8+jcefrYM+DlX*orC zjrw{uTphFK!o6wRg+>?9d3Z37Oyee@m~^sJ?kLSzE?r`Zry=tB4*xgj7HWz}P2lhv zeti#i660%t!Omi7Z3$FA?TVs-k%;~lf-&sBs2eq2@qXU?dANEi zq3=X9qlLPRzIV#5$h^&Aa#_?SHfeu|ch8AXZa85KEzu-wG;9>E zrEgD8!qHIf65}ZG56MjJ{oN zlu^cvu>ioqII7u0g%8u*RV9=4%V2?xwRi^f{0|7^s5wcY9k*@%1IQzcfH4$``rmPe za6bfzREzP{9l#{s|JI*3a_^DxB8OR@uP%%><}Yj)-R+~CUoi7v1}^@ExNtGw9>aI| zn-g2P)0j36@!ZCefGdVTL@8K0$0QI*1b2=c7lut7jC($OPWTY5C6qx;uUn<>x5xHu z-Q;g}^HulPQqB$Mv$kc>GL`Q4nr)YgW9)bLDm2C&CA!2Iv3N=0)*g6}z83)4rPhU9 z<7O_h8msl)Nost7WvP^L&2kN5O{nP~b9$G0ow|8xe24aUSIViG8a|`)%+@Vc8(@fB z!);Nn3Vr9ZHCo5&+$4I{J@<0oz<<>`zq%-K&%1H0Dgc z6!WJ03G#+Zu1_49LsF6SrqE6w`8v2p0)#lfC_bWcWfgds3<6Fl9CSON&jR`N=7bu_T zZwOy3Zwy~FZ~4iC{2JCP>0_-ck$12VOd&2xLugL)7<>4&(c4ZjX9rnXe@qsX?Ntz* z^}5q|7S26$y!jF|u6Lr&>bx4o4yn?9)d6RyuQ?KHvDUY>*(GZM>6&m) zOkblvw6WE=abC~untP(JYs{ZmUQNHp?#y0ZyFNI-e7^U7Q|jseBz344n9ROlxRHCx zzej&#crkx-ctL;5-Z1;(*|z=)ZC&j>u-_bOJss`RGw9>{Tj?8-H{AIsyj6;^`#bgd zByOXeV8`!oN|!-E)b*0VvBj|Ud(Milzr8KmHbG}*KEe7ZL*(XoFOm;WFXt1SKjV|Z z``pU(>rW?`SB`z%_g`)LpEYgwFK$i=x99txQwT#8cYs@#m$+NB_oJ7`cb{AS&yN?s z_oWw*_xP8P_m&r#*W6o;o1mBMSG`+?+s^&3;cF+_gJ*8*SHF0;K0;l&h0=KTI2xMDdPNF=4JjOTz8O|7iB*lSz*@~lKl)tYkP|J7a zDE52Pq#L98a-Pv&l)LHgq5}jkE>Hxw`Q+L!)5s|=_feQ9yR8AxTTuu-H z>uyh0Vyv`UwV7x@2yc^`*m_$xxM^k>Ag&)xxG@S0hgG~ z{sVh#3m_zpIHcpUpFpv%Bp#y@JE|nv(};P>Z{%&@?fYyq5}ml~bx=)?!A3BStV}<2 zgX6-O0$(6W6U6L!E#Dw*ImFeflfcsi@h>9fSg#;;I8TkxxOR+4mmx1>1LD+`fW?3i z8}w1EO8?NOv?qZqCkXCo*cXZd!uLtcK(i?L6pE)S2pgxr`a!rGL@yu{0`EBK`o-VM zkPSB;^LPfhi%BXv5GW^!sbWyg z48BQV2EQRmC`SUP@X`=N#m)ETC`8mFMZ)<^U0su-ITbjc$n8Qpkuvw z@ZQk=J%O(21rz3Jke6e)s{Z2ZaTg zY`^nNb(|$x{0`AkUx&!WT_ziuI*A^N(nUN$JWe=oWDbKNCz|-Wv=Dx5(zRq4fSErY zrp5|A%@JY4_lP~lN&UJOdL@M46Q-F(Ek>pTPo>tHi&O?o#j9RSZtPC95eR5V6oCiu z0!qA5xqYOIH`p?d%GKHVl_C^RE*iVG7}Z7Z41*E zo(=U>V2LhPlK0_#>NcI#W0E08PD=M!{~?OZ-mQ15^s6z6ugP)TdOr ziugSiGE>0|YBvU$Ddqjaf2h=Mcn<^!)NL|nT6Qqs7f)PNosXRrXdoe`8m3I6Kzw+Q zl;Swl9=B2=W;Ap$}jpTC)4e>#;w}xo=%9?Tr^>76N5d4bI z_aSbmaCYF__6zO3uvP*E^+$#OOXaVRqXefK76gq-!OuhdgJid$fwQKKGPzn8Sua^^ z3{$G?3%c*(8hjx#_=V0zl2)Rs@0uqb*UQXoX+FARY=tr>%N;X$!danB8}`=B^zGG8 zIsK0ytb3NJ`j&iz?Fc-bKZc7Sic3HFkw}*&kd$$us0F>HnYftAFC^)E3AQJ8n8rud zXX&ru=BSfk!A+Z`f;&U;Bf<@?!CtICAbYIVfRD#9j4bG{iCCc*yTq7;D zIY~*GTqR5JjqQ}VG)XxE0-#WL0MW)BL<=Lp`3gX?x~ z;?-o5Rvt^GW?)I7l3eVf-xFE3xlTNq$u%?xnu_gRv`!_#OF4=@)Jw(cRl|#`Krmt; zwbCRx)LApw93nxMLB?GM^z1Ue)1W_%O#+N6%Sx=?S%1ml1yvftb;iJ$(JBvExNZf1 zrVGtqMzUEPXBxWO2wPaF&AjQNvvy|_+5It!{0Y{r?wc0M(u1~l-~ok8V&ShkMw8`nhkVEXf!#WE?6NX^14PhfHP>t4EpnnmL-hjX!)zlw$ zb7|aLA_Ek9$xWJtdUdLkE%KQaF4hvXQlNCfn0J=2DGGYZ%BVre~o2*%8% zTB*%TJ{EIp*)^e(E4mdOqRZyoK${$Qua{G2EiZeDdA##jxj-D}_n!P{cHYaKg^VYM ztltM`(AHfwOb4YXfgg$k5$C-lhF`TEbbK&dLa=bWDk<$J)pI{=h0P z5dF4NwA&Co&YdB07t%4jwMpz1^d)e0qEWtJ&!D!CV0D6^&g4lV1yLlv8W23UuRwVY z)Y*X1Fd{&RdNWew1sWajD{`7(gVN4Yi|$(W_Z0@aFgoS32>kc`bm#Lv@3 zusN0wcd4B9l88_6;C=E~M|oM~eZk*nddNdJkFj5K#`4@c@4z^R7fgF50%71N>_MK{ z?gRTknke9K3$i%6TVa;d_uH_G6M3Oh5oX%lXvd%u&2<`KTnwDsw?RXBBi4p@?$q`r zR|}nj-lDEGlsj?xhmJe_U>@v9;-R*`MhSM+$7hep3L$OHTrv9|R+G+pxGNU8owNIqQe25p;l6!4EDb zUt)2T)JaPYePaLpkhD746{>ZEEp4LkO z^9cwDwDUvMwlx5%fu28>FLjb9)c)i6IZF_aYZMc(uSl?~NDv{qQo*R+U`t}W2Z4y# z4b2`=5}(G+A+glMLx!*+e5@tRf(mYw299wwz9IfAA9i1@$s%jXY7qz)JM6Kk0$*sW zjl?A}pLOI&<#(Q~kW?x_73wegK2t3ZFuQc0ZW-;sPD|$SQvn;|E z`w=oH0Ak|jRmQv94ZI|~e-zEE1rI1wkxt<^J8!*p%-|5=n1UrwA@38uV=O{PO@91?5{p&aI`UW8$yLw$c2nNjI%L$eo zI=H4eawf$RnP;c2Q1r?jzXV&T2{qITHGlVcFGABV!mq30bu4JERQ>7qUj&9=O7#}Z z{UNbn>M11`^t@Pklf)fIb>^B@FlETH$m*WVEx|kloY6`~iGrF~82I>8zIOAfAeVme zi!lq?1zQZdwJc#Wpv-LMc+XD@{OA1DL2T(w(Zyfu5=^Vc*$L~7RsZv z;KRTnVN#A08wx8MjPinQMok_rIgDfsq;gpoajEPRZ%}Hbh2gb@@%1>s8+|nBU9Fod zY<0FwaKmSt(*$)FbBOcLSv^xhdbjxzf3RP&#y~Ls?*ZAW50u%C)H=-UE)`p3x~3J$ zhD^)VKT=zj=SYR#q7_8Kckoa9EAsAnTx0EJxjIA$3?+xK4FQ>}pX5(rB1iYci?Tu&1GrbR2)brV#W$%vQb0!Qkd zu@U|N6n_W_WuAd_u0cdu3plUXk0?L?by`7Ao$rEUs}sYGL;UNH)T1vcf$buCkWZSAfR>N*6nTcGiy{8=IsUWQmXj+txO2-N>Cks<+q z9??lNpPADj7|lo+j`GR5w3a*qgL-D`jZJL^(}%m}#q$wu$Q>rh7i-d35PG)P0Gj!y z1rT#Qgb4i;$QU_jrk(K7FD!XAygi?U#y2>C4Oo?IZmY13VVvomL^r(FlXs-hPyBLx z@uhCy{5K zPn)2T3ib=$zUey4%b08qms$PQG_I=4$-y#OM1frccSRQ$C2zYi)1o&U=AyTjyqfpo zeTfF$wiOd?78WAc?uAHw#+6D1dje%(;Cw~oD_k^?L*L3`u!3znI;-u#iqMFVfo-=o za10XQr>9+*{>gBaP&{=;@If0!s5gP;0z{%4K``l~QARC((CZmVy(S-Y)q+rk20@6q z8>aT6NxjGiu;(I0frcNp4>x@0ZHIy%`jk?Dt+*#s^9M>Jon?}Mpf*g2(b&m6L*#Ui z;AU(Be;BG3Nsw*DM0^I4A4AS+zJ$OU^%QJZd7#t>a$Pm=fPVtM*wK7-#0e0Q_zv98 zS+=3t7f{2Q4zk6?g-fIvVH*UWbaB(7`TNfSYO0#s8=}Zb-{?o!CO+4W{la?wuV}xX z5b6^LNdZ7alXAWk>H^HI##O*uzej_{7<4Iwcka(uR$X)TM{|C#bhvw((~AL}pPt3k z=R{ODP%G!O%^xm~YUW_aG7Ha68widY2uhEBpe_pvh_5!@s^#V7L(Rccq&?~|4-^zm?g~KoQU5xBA_DpCQ7OtN^ zsS#*yP;=NSc=6a%$-r^COJ8K=@b1);s&5L7ohmr*yE)&I1}KVancvq^>N&XEK1deO ze`>|^JDY068kl7qa`LtPNn}X)kp%=H0>2zhCb6he?6!%>>9Z(6>F@TabeKL{00T0^ zL&hq~<^S{05=J5{#&U-Rpt$QGk$a+M)K-sEPEaK3f8wr?W)kijB%K;>4MY+LG@%?A>JwryqOGJuA^MAnGC(%ARA^uH@_n??&_Xw242-NVfs5w z>q2~7>LMbI%ls@NU?A_OR;gk>iiua5t=JH!IOc*1pt>kbKi)+$7emP2|5XsvlHI+B z2bppL20|}dP%Wt>i2(s4>F`9djbwLBjI%cE?C2QenUH7irv z?XYh|!A#njD|H}i=F(vtd?yV&vVm1NtrRLvC#!H{?uS|$UHw$!qHN?hGNabc2}0r& z%OY;v0>REP0%!jc8@~K;=M85WePozg*2*;G};kQPyQ_Y4@RQE`6{V6Z`enC(HGakl#Pe9TX?ESn?RN{Dy&R__%Xk+T<_Ix9kg?c3JM6FMkxCVRfBOwi zNm>r*FOkF%*FSJn+v#$|J&C4nq3ly_qMf`;j>vw1-66boClO!nr?9+h#(Zi7INeYL zG$?m;KbC$+YzG!i^!%tZBfRba!V)#-ccaL0)dLc2D9+hb!{>Yz=n*$-Kpq2|o^nB8Ck1K+`M|4+Gbkawi<5Z{qI zMgeoKf&6CPf$yh7HO^1CvN%GIIflPL%<$}PKtEq(*vy1j&*11l8B0_rXi?W;;uRs| z0ty-se%60d$9;AT2QBST+&S1gW+OGfqXcHFZ6l{_rT~>8{rGsE8~#E4l&va)9*X$| zZ6eeWQjsa87GPk+?fYX62mUuDLcsat;fWamx%T5-!aU9@4W@ zA0_PmCqr&X=&;TxJGu+Ede2-y=v61RQ!sEI*>DF+_4-#M_3V-+7bU$WIW85=%NyvQ)qE=}y#jh`a2}hT;zqNv;Q>d~!1fIOnj%(U*eo{p zqJ-x=&_=yi;xQ|KJCv(5z(_#ZL(J-j z_6}#?39}1(2GA?&8et#VS~Nf4#?=GH<<$Zxeyb6X&bxPs9l2tDqeq)!j*+;ajnf9T z2PteC%nTd~v^^0V$_MO9F;ZiqRy8l2FXNc%8Huz$5?}JqfVE8pbi#u9wLo79@kixC=D_6hkNT^r!%$ z{tE1afvMLJV#kF=UqGs?4D9xZI;8;6@fX-XF`PgA{E$lJfq*m{{#6Vo^Z&01y#H3l zsBgNUsC~z8vW~Wl3WK0RgF#C-Nd0Y~Q|E^*U@cS55-v4h1p~0R%ca|U?3=4l`Ky`! zvG7ZQfG}f?cc5%mHLsuM=h_e04|&|!B$R4U_G3)xUH^^miy(yK;Dj3 z=yI@bl|lVi#kqR9!)G&5daxP*srfM~m7!IwN%b}(o2Ovrk}8;uXtmk{IUN=_vyn{X z`FUQG1lj{H+B@9RjL;yUjvFMv(*c{CzMAXe2o<2E6ssK*Fy*)i1=z@<7>5K)yW-*A&lQw8?d>)kDhZsf@|Hu4Q1V2MWM{YKd&A0ORPM#Ei5HjReiRvnMot{~1s zKe7^semh1sG1?aHbtgA@+%DvW&_RUPqLvMliv>jusQj8*)ijkIAQl0j98<4S?i128 zH`|6kBf~3-CujBRJ;hb1a3l0ZupIQ5uWT@r#*V#!ZZiLnjK(GujC~n`6yEpV?-rAr zhSqQW%C=?nWHVVyb&}0!hb@}VMrJ0B&(@l%??jFQSesSIUV)&QA2Bym4`{^iQJTq$ z0PB1Cba}#Qe_1Ni(C9H8}3{l{+JTk9L3nt(f(1sl@D3c1l%-LLd zq(S`VXgdosP^>3)3;9qPr(kh1@u-!GJ1lKLc8A8FACddiOkB8`u@E=tho>umeEqsCj z%^$!6vmXeKoE@=$d`K-k!}9#I`g=-_i4Mki0!ZHRvtklv*pRvv-Zo|f2pIT9ov=O+ zM7lbI@nG#}FrNaK-~)o-HA>CF$N?m_nVRBf5U#XF6?RY!WC!U547p&pDuywI#ZxEk4DlI{_o$-ZHXZ&{5l>CvY+(l4#`T2S*PO*mU@ zYiCI_BudYw$(&-miZJ_7g6ahv!Ew_qEDBI=0!7843iC2Aj(biWkNMDw4vq6W4mnffO z&(e`9IF=;i^nIsb{H)lhK|gyzNpC+BkcaV3D?>#e6*fQc;s&Rl!BB07_4~iWQVfb@ zgXp=BK$H0ce*Dw2H+&=_RlaorUjNdV!SHWdwv?)ajhX#_WtaYE#Cx}mVu{*<@k z=?-Pr71ah)r6(8T(G`P3x6BeQp$ijELWL_&nP+rmMzJ6-9pa(hB6yI?*By^&)8+Tn zk`Y_JyE{wi9fmmPw+JU6N-W!Jv|HjhWj6KCttp+IW@=R0EX&&ZlNTTtLKSyu9{~LOp<({{7Ihdlk9wdc| zB|ogbMx$AHkewzEL$OCQX>pR_C|yewE+->e50q|HzKi^rRkfzHJz!?86@OzvWQnaFd3snAtCOOwbj67uMG@#r8o1ga5tA( zC<_96p_jDyV%N+pdOtwWD(y9of5<*9!>#-{wS~wKTtT&dl`p=wJzcr~(h*W$` zf?n@CEZWRxm*<~yOe6zlceK}h6X!Ewot6qAFAc;8Dl@Uhn*nXTL&m>>4+6AzVt1A> z8D@lr?e`UP3k7w(y?@O~E^rhKPyn7*8i6RO(@)2FC7PZVT=d|UO4Gqxb9{D2=2c3! zF0OK6F|Nf4)Zu53G<~T@3&PB;F&FCPqX#Gf+{TV04<#bbD5aU-IJ7YP*jX)9$y5~9 z9!qMt!Ffte=dN+Da%7|jn@Qti3vwvPfx9KSZNK4+H52i3_fJVkIlx8I(-G(B;G98%r8a#Y4E9HEU1>-<{7-xsejg@Ce&@JK4T+8uzqS=a?jLX;R zVm!{uL_L!_OZYX)eK;bQL+W&Pm@*M5KPQjKt-xZlEJ-waO_#g%-)Kh3%=IeP)|S-7 z-sd_(I5t#XqNuu*`)2EO*lv|@C1<@tNrG=NxN>f*`4Fj;?-M;Gfpwt4*L} zoQljiJe{_eno5p{X51)b!}>2sYJ^%R9Cd+hDMuBU1i&oZuWC8~&f;{*jdP=NvnsU( zjyYNy{aMVdd$r5gfLJ)TQ`pL|iY9u)l>}2Hr?7sFI6wox5Y<(zKNF?(;rj#-s`jdA zhpjuBOvZx{jzQE>U=6cH4IRG3bj1l~Lm_Diwe*B}5QlzWRVbPIvAFdZMogGasw#Uv zrN1=fAU?h%C~Z^Sf_t++oR~A#4pztH)EgVGA8djNH~J%cfJjC$K#r|f<%5D{J^0tj ztB_uz0)T8ik)p;VF*Pr3MO7I|=;u?KgpM3E&@%iA)RW=LW&vBjS*=vst9Q1=LD_RU zuhW)OjV`r?axf`f|K@`4tTQhf1`f5AZs}j?@ac-2M0a;(sc|qdH{CX{`IPJUSy?W@ zn3Jjw6e;PJ8pl~(%Zx(VUr)SRE#Dh9GTVN^EYJSd;wHEnnYPE%1N)0BG05Q_={WEKDQ4z92E;(h66Z zGt52=VJ`|1FD%_rY}YfA&Qobu>O!RrPl3u8=Q^}aWS4dh+5l$wtzO6obr_XDMl(`@ z#uv;74PUHjfX!27cU+Q+HzH1S2%WhNO3V7(^rhyB%G$?MWAfgScyL){qtp>W33G=n zY#8vlzk<4#I1s~GR4*`?F6=+G(_Q-Uq~gPur}4p$uPB);XL7kBjrsCiIMa(Ku;aZg z*R>YPpvEdm(K3d_F6KfJ>A{xobtbn1c&x6BeR5z@{G+pa?YJ{Ay~-A4TlUJL+cD#F zE9js~<1cid4C$|Z(v-sQ_b|Ko#YE^A8FW&{+#|NBn@W=93?A6IBGk4J@s?Kc4 zvHu3r%@Mi_A+7OG?{NQ2z8QVY&RlRHAUx!MwXE>}yUAzoZe(j^`oGRUF;5dS zN7rw6z<&-xo=1meesFMb6mWiV@F_|M0}&QJ5Iz@ia3#3>>cK|QkDS3S*N>g#qKPh7 zn@L7-@R);l-H%4w;)h`BkL34@g|3CJgV@0?v9Q{L?`2|=RW_Mjl(Dc@Y?<$wWiBwWG;{7%0)74S zC%RO7=Qc_fiV_D&6QRX?<7Yu$<067mf}(_yg1{{KAsK%VNrGCUC6ehFi#J`0x|KHjn-hWd`xqpNU_7%bw|#N#-64d)M}O zZbp_y#?0&pcASn*R^DM2{19dR5-9rUf_y*s7$OrL$X&w*z(mF33``3GB0>Ct2S=J2 z#7kB{DVZZDi0=SWcJnuMqXxaX1I{<+Y|)VmyYjOt94B=Gp8|{3RSt%RUQ<%>&#MZ+bK__ z^yv_UvmInB z9CHXKxD>Ar%qQkek7iYu5=dv^CqqkHUa?DJqYgbI2Po}Sv z0L|GgY35=K2KXYru#fI+DD~!fla{;DleVlm9JJrkB)8O#4H4B2kzpYrc!JaNe_6-w zT9Iq7_!<&S)-xH&kKdEAT6@pu!vG`SFB^cUCv)`UZ%q@SG=5UUK^>28=;j?xwZlo({$AD!`mC+;5govsgDGkfZ`lSe9_Fq z#4JBz+^x&;+K_hp=JE)mT6%-MSy}NBHTxU zB#(=Hi}fe6Qy4(QzZtikS8(PcaU+@w7~FTF8nXQh)91? zPYhY7&O_BoB%1Pm$L#)Q?EUK$n;J)eMUKMFhgvxNHhq(+vzijC9=$cO z=?YxRxNc_%#ZxFycArujdP8U+5Jopgw*9aB)rA%ZmxC`&CJr|ik@c>k(U`-yR9#l; zjNJ!++p8e#Qp|>j1KBGa_D_oJ-rBZkddqM~;M?p58bt{Tz;8@o3>1n6VBdpD-O1wDvJ(&C!Q~XdIT# zIupJcLqXKw?pNH9EOC6U%T75W*R^l7ZNY5Xw{PTd+rSQiv^o+7dxnIFFL13VT#`@2 zRf+lo_dSa$s5Sx}OoAtfuez;=g_-NjnE~GA4lId;4X$UGxn*E$P@$i8Zzv=v>i4ER zF$}7+Z1zsx#bqPtD+Lr=ztzR+DuaPr*;c#F%ty%-mbH2J8sCAOW>kjSElZyg*8kFU z(7cdq4K=)+mw0WY$!h8oqIs-d#kJeY7v7L;qKJH$u<=6tcnFQ{1?lse3UX=rQFkv5 zW^bVYhBuXs*31=x#+frsUC*7~^Z7KD7DtA%-S5w!RjHN?m3}F9`KEy>McO*6B1YYw ztXsLDe#V<*SJtOhT(X9V!Z;A&Rv>->#RHTiHeQSE)SxptsKM6ER+aU7QK$5iwO<{i zj3F12J;wH0l(gwx!L(Y7{9=S(bX2LxGz|mqrtJFd=ILnr?LqtBcI8DaA77nEx3AAye2p}F+ST|y9}^z(HumIw(E~H$ zb-6tXrG3sn?DEx|PNuKgX=F0d_~h_2%GjC`M9qcu+){-h%ynUQyxb-LPgk4HpR@Eb z8tNUtY0kGct8DS?AS{nP%!ZRmIt8B<CRxgW$Sn6iWKimdqfMwGEt6w3W=YiMz?cjmyEE&PX!bEnlU_(|oLAmE(FcIznb8}~$z|KXH znEN6JknJ&iUnSHO8uSlu%tMW0EA%E#=@)h6tY()Wo-HAl3+~UnuCg8N^t&~kAyCH= zYnh6rcV$+k_nZBhg{i)eH~SLGu&)VKBCV)F)IMXeXB3V_cOdLwS zjT9H)MK6daQVGb^ID~bM{|Wz+Y|VQD!@7W*FCNRP#IVi*P7d7#3s9)YU!&yYPhn9oA6e~9Rl?u z)v-ivP{y=G)S9!fGLGh$2e~JdEi_8ZvsrYX#5zZa;8|>>1Pwl6IECbpQKCWyK$UBz z<9|%k?5yR@+$6|rbqzrad4f;SH%ZOVi z#+LdUj2n9HVm2|SOX87GmyC3$8#73SZJoYBGw%qf-V6|HuT#BE0S0^}FR`3z8 zf3?B&By;z0dWFypcFmD#Uv`M`e_!@Acs`KVI)!sf=Rps2OXeOB6ilvOrfjoRtICDkSqXM33HOs{s?&gW^f4^F6Dw6 za_QATZiGQos@cTreLIqc(%*qc^Q!XX&B!b@%ZHus?3H{LdIT1OIa9rc4HqHBlj#Yl zVJF(XQd2)y2q=PnVNJdhAIt z=|v1NV)1M>YkMx8uH0UmZV*$4RuGOwYA)nL9(D(slz0P6vukf?PC3Oag@A{gYk6?+ z+cl^(ZsPaoLz-!`+XTk)Kx3%DP%-i+CKCNrZ%S53(kvxcT1Z3-)Vt!~c{*W8wN|i02dDQkU^Xisrm;&|Yr;$) zX}i@BuVbG_ z&+1Zatxk#FkOD8C6N!Rg6DydvFnAU7_Wmmr=cXXCnE34VFh@e$i}p<-yiASp@?Gpx zYB?H-Dh#H!8t?kI>b-aF$40<>=x_Z&LGp~b=I(f zY4ykAhV6>jA0%=R$yN&?!&Uwb|^`)6Ae0 z%Su-ce%LE%_m1v#Vi8U5PC3_kLSSFWU+?(WE!%KVv-Fu7QmfK5robmXGt;57zQ8x& z$EX*pnyuu7bnbj;LWas8qS8N5uDIW)Xb&Prmro*x(&|EK$X=GYBrevh;JiDgC|`~p zo}t=>{FE2Lkg_?7Pac&tw;d!3|LtY{OFXZJx5|tr@3jj#x?W;n*fDrH+)lfK%EPt# zDVM2Q{KqKMC+TY=7>*)!A(V%5e|G6IR6tA9hNQC83uGR<3G#eb;#bJf7!A$e`C_X% z4Eah3iAvOwL$rBcr+zXn4kV7GW7!wsU*LnFr_q4t?U%zQ6+e3S(Y);;C8)TQQA#=m zwDRm5rAu4uy9kWE%jispA=hfYkh_YWhQOIGC>Hu%g;<}S-+piU-uKw2Vj&zSaz1z; zsQ!G~tS49q6s*S8h`kCt28FxaCq_lTQ``&yrbDcIEHk~9%L>Jz2-X~nlf`ln{I%I) zx410bp)m?f?eYTC&=1X9bA}^peakqaV$D(OM>px|Qq(xHGNf*zCMF;6U8H5a zH2;-W_AeHu{sN!8hh5R}+@@#T7VZ4QwhheRUtyVR+?rA@?roASHd0qLB~5q_L-MS} z_|!y)_;dKnix7sADA~e#M+sInk=y&fyx`uvn$mX@BIkrL*MtPvgvO}*TAg4r6H(2r zC5Z4qH}Pxh>Bi8z%NV*}c(*JWzx}eD5mo%FN_w>Xj=)IfB^?PPs?gJncDyOJ0%$OGc_PFW(d+{4e3A z;59B>OGXCWqW&UG*XU9YCu%D2ZsJF3u%?v@eL!c`rux=LL}x{O-Oq(vG9Nqxs_u!5 z?Qvqb|{qq#12_pqK32fZBi<=&iWu`ZED=z(;5@=UwZ7UtbFQ*LLp zdR5UCw03!IGJD0krk<@YG(ql=14h&B?ycUUb5y5zODCRlWoOGueN}Dqn)6r4OHfxh zq5&z5bKFIuln2SN;Vwp2zlMRTtn(z+s*`vvA4>u zk1}okUJ;45%ef<8Z{31ZeE!MAZJM3LMlbkLtLkNSGP5S*JirC-XLt*%SgMn7*lfr- zN5XPSk2E&B%K_pctqN;vWfIL&EC`n6OXG@G?V!Z3nRs_XBbVjw-bGFBIWgZ5qI3HG(8Rou$}LVHFA_S14p5 znRJmif;Bj$yHzYvYRmPJ+@Vo%z^WAKI31(9r?!k8l)m(yP@YuI-c}%C6t9gyY!m-> zS7$#e_on=A@>^JLAa9BIYu)nmvY@Rszj4GXtCwzr+&A`Ri)e!;r}VSPKE2k7>4}*| zd*u2#(T78 oL?ES9?2h+r)W!0)OOE~Sj+5;XQYT@0a6m`>|N(i7|Nt%+BJ>xWr4 z5OaMy2NLpvBz8)$kGVC7$d~4)3J0fRf5(DFa$#Lj4PR^v3!FB9*@-9Q&hTfo7_w=Y zsXtFVlrM(T2aD-R?iVXP(UiVea(6uH8y5NMIwzT?Q`62M-2ndv^}`NefXP>sGbjPN zb$6fi&}tWcgJ>g+C+y8J{f3aA$QRfH#z0uv6ZqE+S}Y_3fI)XqYnN?5y62Mg`Bqwtp&**v7D%{%%I7G z0~2x6d(IqcNP2_e7Xs~ykIC#%>8-AO%ec5zPTwC7A0P*?&v8foF|20OwuK%9dSZPo zNt1NuR^GmB{;iF^>;cxocR&4jt3%P*^Bo`D>8Gm)1!^ ze_2zKY;%&$NM+C$@rCdY?LJ8Yhc|!+0xH4%zuIB{mt)@l8J-mf-~DgM?YA6#un?R) z@y<&R&JM2rKjF1NwMqYg+LYX&sH7ko&faE9u0=W)il4bbVM#)&00<)`M=2$9{f^(} zm?R+Ca_0KxQFtUFsOlh(f?5BGyT9@Giy!m7@`tobigJuFa*DGu);~yA9t>EV5OfWW z)GLse44jLRWcAB)D zswnB<>03@!${!g{ba+zIkBltt7Ba9VSm$N)-Vh#osrWpMti^`0cvK9p+mG`Mwm+t} z#t8yGp3wU!)paGuEj;?}` zU5o20vCKu+>BP0~T@Vc@PedcjPmBz$z>TiP$q=w=kvhVL9(3bP8S^1)7(FpuU7EUj zO4OS1HWz4oVB>v*g^G}W`jCsf-Su4>THBaW?KE33CqrKuW?=k{>}OM=M2jop8bXxU z1GU@;!IGtx+@%MQHRbF)Qlni~2GdXFWKhe@6Js?gv$9)iQJ?+^Z&+2Ng> z!hi->w4wMdyu%Nj6?ZL<4$rH-s#XHCt0`H}HrPcJc?ErL7oz*fy1(NBOkhQcV5|oP z6B37-8qlb@S%0qds*p>68x!8Ev4>?`#N8s=a_qIT+Aw3OiW)Vt3%1_GTO9ZQW;UdAX+Eq3-}!HO_LMS3aObR}M1| z6?do8?y&^wXVN#+@P0b;A1~@D5PZg~#~YRHK@RZQKOSdWgMb`UqsKGGrFi(-nrq`0fvKNTXr`YtvIr`5fCVPPm zyFEEyQg8@(=nMK%k5LfBDlC4V6zx#?_ZXA_Kekv|?MDF~O_n(~X2p6$PL6twtk#

H|8?O9!&jkvf!%d7QdZu;61=1NO;P4Zy!iZ}+`Dwk`;O$Pc!r`~L zF!<~EF!pk=R*#9`lfR$Chaj1iRRVxV&EIEf9cL-|%lX|x?rMAkA=vhn2@4n%%jX}H z+`f4}A`|e@O1qFUb%^zBMAU0p%S$;**&rkUNkAx>CcZ>q4f_EX(Eb>*jtA z9d>gAbGBbKFP};J7r4Dlx5w|t<|FrfMP*rVR+XzT^cXu~PcXu}&x(;1}fOMynq;yG2 zgGfqAmvnbZ2?+Qf?|a`@^t;#V9pj&jGX{sjdY--Zo^!>VbIr|Us$=>Qho?VBohHP>IE?kELy`ZrsFswPdH>UPAR7EabJ zP&x68qH!UmSIy*sr8%+xfCR?m)YOs}m*_d~xc{zRK z-ZJKIgd)Gsh0cu=Ur~h{Y5P&KaBxD{>q}H>eAxR&(UglF^^ENF-ELKp{;SrZ>QpCf z)Xn$0ppc*!x5*Wu{}N7kYISoJYHYewhuT+<`WYn-hpxoO2~emJG(8fgp%BrqZyGoO z+RD*wixVg4vkb+w4sep*5YXPGEnfsNq{Y2IgyF&xv5@7_Eo(R&I^e6n-BauAG>Kac z#FiMrCgFAwQPp@GP&P=tU>e|SM4mK5aZ>QoK6xQMItUjY7a%L!#bAz}IEgS=U5_7r zpNfh^j3v%o5m7GG2jLx0PqFEc#yR|@5gh!7H4SCW`s<@Hgh`13wn0=)5~cU-c7`|#er1c z53*!Zqot~HZaQ?nA{tMTyrmc0MruZd$CYVGQ_SmRNqFfT-?qkN-mOuohrweC zDWg>^)XU()_i0g==|-W@2q@S@pRnLVofvQ@{0bWzBV`uy>eVxcOj+BwmjP49RFn<$ z&K4=$TsO|wSFQtj_i?lHmcg==7u<`D@b4J3c?8pWHw^tP*qun`k~ky^J%N54nhuc2 zjmpv4a8OIgIp+a7da&!O*-}8ZDc1@Z{Vd6qEGvcujr4iIv{Glpu_#3|E4l}aVrzC! zJiD^h6$N3gNDA3YIb^N?kvFkUPK7?h;bq;#`t{?{@4B+#>8P1^#}DOuyKtsInLAlu zA-J?B7ZSS7>+6gN z;o641_d;y0G|7hFee0b0ilb=P))Bsvfe2GoQDHCODT zFM9(l#KPjSjRIn;=`boSqsW~)-(?D!=CA|@6$YL61`r!yiJasTVZY2{@bNyO-Xl<@ z>RVoDRO@9!n4nA-MP;{s-ICw|G2YL%{~Qe)SROaq3+F($uNPh#Bp?%M&1%Y6Z8aKI zrjA}4L#3Z(bYx2+P5f2cmPyv-@a_&Z(!K^I{PX8hGrAsLBCyq9%>6Wv!A+~#S05(G zatxYIL&I!#JPolZacA)&FMHf>A*Oe)n0!e*H+%@SlWIem)m$`c{nqYC4F;`xy*&uS zBpl>)Z`Mv_fNG5Ts=gf*L&_t1*C`yHu889qnl37|bb{_1Xxv7!b zk8*6}Ok~k9@d59md&HoAotuO6^r|+d;iN|6$^w=w)XM6V@(I(MMeSUBcWil0^kdDJ zg=4*@7BWu@;fp(ZuvL?pF2YLn^2sFcE;<}(&}8kDUkSRoGY%JWec^q!FuH27^br%@ zP4Dr@t*ew$k$#sD{X1`w{sYM}w%W=C1&apyA~V7dS`;d=>EYD{yhNQ&TVsi)<_>We zsdM8?*Hmcbrd;bc9+uhdj9Y}p%0L?iTC`CY!}87Twkg#4xBzyd&X-RFPS7?3aMns z)R3M0ZdETpETtl3=(Ubzeiwyl6A*X!LQ`|X34Dfbc1ixYR<<#JexCg<@J!8 zhTCc%AReWqkBIkie_62}4NXnu9X|PxBuy^ARIdo8iFrEyl&9Nx^Yl%^r$BkZ#r};K zxUb(IX)fRRY4(&dC&HZ=?QN{5^9!!R>1sqV-Ik@oHoz^&pEF$q!_Kp55LOMTaj)1# zPH6~jPZtZme1G2)rni1^^%_s>=|q}`&p<2qU5?^VzR=;qi&4^9_YwN_-A`Dp`r8TfXFYKQu63;m@ zVl8mnHR25`Com1drVKt?q7o6Rm#CZToa3_y40a7=#aGu(K5~(^4RV6yk`|P@C+ez~ zW5$UFySH?72vLd*9P#VcIw+BYDQM5Qe|o+e#TZl@7I}`@zd$g$sAMUO?X;(1>QCvm zxA;;$@sp1KKCnWq$d?`6t%UJh?Dm|$(40Bm{G}WnusSi}l`em#LL5(9T6KPi8hsVJ z9D^M0GFwkgyh)CaNyvfly*5gc847TS!h+tn-}l{wGqrLL8~iji_I)&tjz16lI+Wn& z6$cmT>G&rX5N6^AC{-lj5s22>DqIX4kMdWwR- z$zGhY-WYtA+`%c@_$>M&ThdN2#`uL7N10Th*N0l38-JiTs~-5KFWdTv@fL+3XH@J) z$5)1Xd<2xQ2~ufEBJ!5Cf}(qo*X*+Ec9>op0E~Wen)ngZHhx(=XohB29^LoS)r;V(#??r|vD6Js`H zR8KLm`n1Mr8pm?mgO6iog)@Lzm?I?Vr$WCjQbc|A67hl~QT>>jTT$9q>oQBWToiRfiMqwu{5CrH7u-tx>*? zt5j0KWeOQ!tj}X2a6x?%Xf)#5G8XhD-6onrR>!nAnw@4y|4hJpgf~|2E|f|Sap+Re z<*tiC!x~XQ$rx&RhQ*z7s$5cz=Gc`pJCuppB<9)Bnu6GpeGgWS5pLiTKrE#|*qdfH z3-F8qd3~ioU7PpH6w;5t@Vb-cYKV(RNrmeQBH0{lhO#4_{nB$GXEw2H z>q&J(^V}4+r%+W3dZX1VR&B1e$wTuqntFSl7+&VHC^6;4H~Y*D#lu7hCNI0czkLblT_#ff(3l4O-^n$f!?c)#% z$U(78ObCKCSl)xd@e_Iww(Noqjm;5@t}+rrkV6n277X`F3VL9X9}*UQ!WPq>sxC4e zY46Ko-!b)3Qx=FSJF8MWvtiDQV`Jn=@spJMbc*Fhs@s=T6s zu5be0LCB<$^VhtcD{Hl8#%|HYa9rk!Szh=6lIiz+!4>VuGtqHDwMXD(>F@Ma;srMd z@Yhn;*>GQ+vjU&lnZ$q4$X&=&5lYX`Qh1bk#{IhSP2?1w=fYs`i`y?e^|Ez$nkMfA zV*Ichf>$hnZvuGj0zdox;m>p+z2Tci24(HC{K|FkD}UyHT?c>WGD&>*8bqt^+oP$V z+#_uc>)O$l*9$WjZ)#5C<*{;5%#9{C=9YAee`RzG&`UPZ$3hT%A@q8VW2_tcBqz!x zIZ4ybmV5RkyJg$;mh;wjrGpUILg)t+ue0;n%fPk8H8I#Hui39WIK5dsc>5{~m z0vKW@`2?QDZiuL#+10JPT=fz&aB}O?z6TL@6{!Y+9d}h{&@5@NQ4ZlXo+J^xqIeQu z(^&Y{z>qUU*T{C~wi=LHZ)00HW(jk|;Z|fC-$Ol@+)dkFRiZ!HFgLLw<5mF1g)^?G z61rfoU21V|e!&r{&we;3JX2D`fa%An3UypDy9QwB7_9Q>Z>*5kE|1uiu&Ovx@Uxq` z@(vCuW*5gCTB#Fh=qPWNHO&=iGnKw`nA`Qc6)0k95VWKX+cVBMYFcuh7|Kc}O9ekc zx5);$-8AjxEzMHDs0x<|pnC*~YvSi%^huepbnT8GVKrr|-R4w4VOzVXjB@TNb8=7G zgtg%)Puk_wn6(tNuy-J2zj@8TNxPI6Yl={ZY=vW#G}F^4Po^UQ$%8O{^{NxTVvK%` zpm0{%Cu<)`9B{Y|Dk!Wa=Tg2z^cBezFE@QiXbs-q7G5VVdNog>wk>KpF)BszqEQkN z)~YkuOUTrg*ALg_=o)Gl;ZCILF^?upLwKM9kK?0W^oWyM^_f0* z&%NDxQIgB>lg+(DsO`KeKN=R8racZh5&S&RI;ap54+Ov->p(t%#Hq)-%vl1KA2+<) z$y!{)YQW1z9GrlauhwPA@;QFu9@xUlgLto+nnC(flWZ?jQ*Kmt5Pd1W z%@R*)f!0iruAdU|GisCx=6=l?V~9$^`CL^RmB&CQ<$!TBRY$lX9c3;wX6J!M7-5%< z;{?YZ)eK8u5(*V=1cZ80CH}k>yid`N2SZ{$$z=>+Hv~R6RX6}p$Zr)E5Q1VNelRW; zSj6N%FI&Jo?V(TpZWy0dNk-4H*M1y|qGGma!GDaCgTIr*&5JVnotQWiY9{XcbcE_i z9}UUk#H(u>ot2qCPIG+QV|_8b^&f?^45dHfl7 z;U^7e=H#WRg*@Pga64-=f>v23c)Z|nX(u@y#~*j77dz9w3d%pdwkwn=u7r6X7MSU> zf)`VSamMk*9Pr5(Fha|;T90h-NU zpzFbZ>N_el8+N*B6l*U0;?j&Qe{a-;&Ugj&&2S z#Ih~De2rlf%>4OiNnm>kr0VxKcX!m!Ls@Xv%C#zwg-RF7Ub9wVb*$Cx{O-{8wIe^1}>5h=~z78So*1cmO4)IUXj;@K4s^}@sj#CU5rh` zEIJH8c8aBD-{rLtVCW05p}F;%MQ-3K?v^7&-s(WeF^~9%7$$EUl{9^Zsjsu^!L+{ zXW5~ty3#g}@B@zm7nh{Onhls5tCrH&jz4}K?-#E*IOp)0bd}Lzjxawh|ESu=FVNc% zxsg(zr`^u>lM>-uQ_A<=g|)^BEw zEfn*5KNq7>$H+ftu)-8Rg{C`>sXoWd=|UAvTcZSiIs8MB5A`x*4MB=r^vfapSBI7P?%v09rZhz4 zmNOu*n~jj9RZOfidUrLt5t>LlxaXrG-fOx`=&9?sP1&Am&_lW`iA!Y_4OQ=X8d{I388A>Av(N{4(tpQ?fl ziuT2w@VSRup10+DDK*~`lsMl=W*e|?Nw=ZkP@%Nfw&|SvbzdCyBkziCF!GL&$zEn% zdxyZlM{Q#xISLVf>{a)5BK{;05l=!TB<-H&xgLgMi6Fz>S z)X&S7{jsCyQ0dRVVzMU1ep`XyZAO`nOIavjx9>P;XCtB9`cEzii$)!|k$d0&q0Py! zNWx7(+FbHWZD#$AVOiDO&H?an+2Nyl>@cp3A%Kh%91sP3zDBij)u}Byg>%<#V)7x% zA_^H_CwJL!wV+MKFy%5y{43pdEW=p0P`l88=lqlcDU-sn_vft)mt%p$5u;^aFwZD1 zvHQc0)h_C{&~J+n^sC$&(M`S~zF)Br(^MWaKRgJ1yTe@DZ#9m%F&GyT}(f)`yY|O3U##V0b_R|){C}!4F z=<|(T#=N4$5hN=})|fOh#gD|!Xw-FwyKOmB{A&$Zz5J-MjA9c*{pV|st-eY(5@jDq zm3ym@ha6<7s|uOY7|0pUy=f}GNg<1NIS9VjZcSv0e#3WZG5zeO@5vWqYX`bS<#iAJ zJDt<)Hi?ZmS`$J>2wJwCc5#6@2RD)=oDg=sD{_0O(y8GZTs~@qrnlAj$b^S=opDFv zQ*#LoPJ9rbcUk+yNF<13)2JIbGU-9D!ihD>s$rT^b4^=>$7pFW8sjgDx+jk)z%e3q zPpaZ9T@oc-m3W3#;`Z*<^{0r0=t#E+%2e^#S9-7mOD3(v{ z;-Ff_+x#{B#zg>oT@(!v?A_1MNx)_Q4JF(fr=Av0}kdREgo^rTbtfN z_?|`jb&0F^i=+EJ2kDO`O)wTXv6rRg9^&sdBlj}=882f#Z3ehU{yydqXFvP=xNM;*f_S(nmPe){7^!mue?lK&M^py)fvrdL|I)%J<(R03uO1)u9>r4_p3vkKzB~|x# zq!>%D1eW!^{iqP~zN-b{?F>qg2O_^{gFoIReaRgH5W5|J5>iRK-XBREx4EGYEPmBi zQDj5Bb4za9_XV?4PgUQj5u%!)mhir)w=C`x;p*cXGMro)Zd0uB7bOSKYR%S1j?~w~ z&cg?#I~7!mNG5R6`8(167W_q_3`4RzR1Jx#Ax-(^_)?2#O{WA`tWtSZOayH&M<^N_ zOjUH$duv*h22TpGEb87;rqr=;*1v_Cb6k#v=~AY7_JTmD6G31`0oq43i6dpZHx@Uf zLUvL|%M?n!*1%1w#9qS;MFas5$J+wNhV9l^L=_@AU0Hes7 zTj`0QE+5$#I!^o;If8hn)QN;mEQ_-=GtOP)b2N@_e{1l9SF(HMZ2x0V_WokYJ? z`Indqhs_UOK9_M-MI#Eeg0GAqwE51Ngmbs$oV_@1Y+`77u%c4p#F~Y@u)`C!Tna>d zY!Xz1?Rwv!wKe1qV_%2++w9Rs_%6_j*$yZ#&(Q5K^k|lw>)Mu16agbHaQsbMuZnBN zvjzQ1WTR9v@{jbB*;Nq@@;%e}K?$oZxzt5T70Lx=8(WZ~l($ua(0G2Pdxx-+ey{ec z_5w5`5WT4E@1Vb#+7bApOazdb(Sr_l|NR1*>o-Q~KN7XXtN`|w<`3*G>Cct38k|oR zhWG|!<*60+4mezxL{ttWVRN11%@zTRFvUJ)c>zf$FEIg^WT>SGfdEVZ!O!V^=YX&o7jU$+SGlg2t-_^5Tk zW(lKgrN&vq%ly7Bp`Ya>*DiGqb(xJ$S4M9CHXMK3zyVOtD9sU)#&y=*3JX!ZT zQiD)k;V(6y!jUS=Bt!OjN6^${yDf1RauSQMogltFR90^3TrTey_s}j zNpWwQ$!-lYg;GpYv87ZMWDstFMpPS6Xs)WAMQX7TQ2(mnI4*rRw-lFBqP#&{2IGUc z&P*N}6bY(=VF2Od11?HqeegwiM`6{ zVC8y^u54+N%|xUMneL-5G~H2VFPYdzHP^USxrLUx!r2CXM98NNuSl0=xAo6AaH*^= z5EM@0h~q|BsFk!<2Hzgh-E6ca(|IXbr<2OpXYUAa*hittpgf8~zlQ9ghGh+w zavyKmz`eG(=HoZA>D7C^!k~kjgEy%W$mHiPjNRW{8Fcw1C!iS<8MuR>F(q$^HVS+i zVFNp(1ZkzEz7(Z!RV^_lBUhv5RjGDEGz)z)?(~STHs`2v$Cd1bW>NQ7lxwG(R%3%I zO+m8DIoCj}n>~Wc{tCc79N;jUV6?%E&v8B^MkP<*M2V<4_pPswFMS&64FhbWlzGN_ zpk@ZuI`!OA2H*srSBVgk?BX@2{{6de=EWaW@!|_;A;j_j%e>5;+#Z@&`JdC7n4H`^ zCTe`>CN0f88KVS|Nq9Vlx(O-Bnx4%k%jh&`_ACO)@2SuwC@IoFuWV6y&o^j(~+rrdK)5=2B8J$=_9))t7Q$(`@*X>DWi!+dUYbNtQ3< zWW06Qn(;M8K6^vg^2}9)YxFf?@SQ-GInL-=y_zDnZBm5HY$yBMyYmq90~hM_j|is8 zB6^qsd`|`)4UQyHM3Bd5T^vemW`cUFoEh~yM{%w&?UE}?w!5hyyoXpW-Z>&LS14SL z=F-X^TjNY17^L*DbW5+LgnX=TTpvf#KiWi4SxfF|DDh_#n>XoKrNJ|i4vC*~#D{Pe zHpQD88$p>&K~HxkHip?L{lr+8$7#`Qc_Nu~)UrU&8$!EKOB!^Dn`J%WyLdTmo17F) z7A6>Sg`d`}vsspF-)u3qCRbFgZmiHnLu8%WjYt;vrop-fh%naRK1BOzyRZi{&^)BW z<&7pd*O#I63aQOzR7;o_2#6vdp+f-8H(D0`g$-s!sGqMwWF?N+&yD(QFC8!_sU@Sl zn2=cNY$u}!6GkwS9v`tRd`J(doGFz!!oW*4^)2B-=q+}R<=f`KKMn2o9g(QbUV5w( zx8>$Pl651SMjV+NgSs|_NG2KBLVpZ%_p-KcH|{VILe;XF-HaTAJ4i&Ac+~ni1NnT~ zZOkb39Lt9ZJXOW$X~q2XoX;@15^Zwtkx_X;;Z(X~##&Vd@^n$*p3mGlfkv#KdqN4Q zYv22(9)Jq~jSZBGV6sr4_&VB!Sj^xL)!(WBlkLhj;xl+U#Z`sG9cq|8!#>cCDXK!_ z6tQHEqwSDnV&O%&=Ba#P6{r?|fu(MdN)}sZ^JJ{_^PAWqigGoI`)bWcH!|h#!^4cq z5L8mBM#LWP5R1KE-eCxzD9De?$%6~9x)(oLM3rm<9JQy6%8@qXT}O>m$SyhAyjj;- zHu`2oP3!rkYalDK`K1-f{r)8NKP#g6bJqIbA0DI_tB)w*OJUqwyxr#V zEo+CyqUa5O@dT_a^Y9~lkIIZcDB^LH9Fi)b%xNNQwTXbtRZ&Q1$q1={gwFU

4#uRWQ@zDrkJK+IPeZn~$SA|m??MPn zlrD1Uz1s=xcH{-(2iHB#tFhXUqe>FdQ!naw!_&gx0K}~xjAcR*;iQKIPzWYB=^=xv z32r9n@|G$DrC{jyP-N~^DTuI#6h~-}(amj;V9J_D4%jStMCsMJ zL9r&n*!sfYP!%aF!ZSOqVu>B42CZ&<4c;3E^sH(25NyBY>GjX!&rcGjETlFBGrCFVg9cwK`Wb(_>^6jD0K`kU_Za32N ztugFV^VQ^MxsPFRyj{_?XJh&KOS&hE+Z%9*+KNWc;3j!Ca^f=!;B6uEhM~qTx#mtX?=@&KK$fL zva&1tX^wYpO%`T0Nj7YshZJ}XotE#$ru9c}3cR-*JfndelGagUsp`E1=fzz}yc*eo zTw@}UcrGhiT}Tuc_cO~&OUW;@d=Qom7Oi=_xJZPopM52GqvM0U%DXgkyyKDaetQHq zSkUR?o5;^uq+7CCfU%@v;$y+CNi}QjD&%4G=Z$RZ*JWn zq{nLf?Z=yA%WOw=kUU|ZO$o!VHdhwt4Q^LM74R3Q=nLG@Ztan#f3Ay;TAOF}S{klD zh*MeOzK7I^@sfZ5*vgJX6gX^S8d?`Y~yarX6fklubSfg*wppg zITcV1A<**O^$lv>wkqs^b4&2csKv*hCTwv0K))-fq?<@bQsmP z@1_pG1>s z=mz}iTE!%OD0B2PFy2Tq$+rk%I!G-Ue*hK(?FD}e`0uV6Mg6=i9~7?X2Nlrd`2l(d z^!4|kMce__b^sG=J8Rdc|4F<5xdV0xvh5k54&Z{AIDcR{1v$}wk3~#E%mD}l*qi+| zg>+O|#SZ9s+JUyu96wNe68U`!1#5c+fahN`7?1$t7p3=E1Rx4^5C!iKo!FE9T?%D$XW+M5WDfR!&-1X-HOR0Yh`qwEdHzh6 z_@%l&EXw*V0pq(kW&9iTzth==rSHBK5&JF_xxdE$i$bqItLnpQa3I}$AVekq0RE4) z^nT`gSSRgUeYx*qRr+hLf2ub3Gt^Pd^-uTA6O`Nbbe5ZeEN?{@jy?=aGKYT*Z#xAolF>OXV+pAg*7 z@DF{+Kf;Ht{|@|5A)24zANtU~IikPI+15Y9|Fv8CXO4#+h95ap_kNq>e@=wI9#0-_ zAinu3zDw%izvuXc=i=wieIxqs2ISlRE+9sVw&x VJDKrO(){vTiE@)iI9 literal 0 HcmV?d00001 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 2b79c5834..e7677f642 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 @@ -25,6 +25,7 @@ import org.bukkit.plugin.RegisteredListener; import com.cryptomorin.xseries.XMaterial; +import com.vk2gpz.tokenenchant.api.ITokenEnchant; import com.vk2gpz.tokenenchant.api.TokenEnchantAPI; import tech.mcprison.prison.Prison; @@ -388,18 +389,47 @@ protected int getFortune(SpigotItemStack itemInHand, StringBuilder debugInfo ){ itemInHand != null && itemInHand.getBukkitStack() != null ) { + debugInfo.append( " (useTokenEnchantsFortuneLevel:"); + try { + Class.forName( "com.vk2gpz.tokenenchant.api.TokenEnchantAPI", false, this.getClass().getClassLoader() ); + if ( TokenEnchantAPI.getInstance() != null ) { fortLevel = TokenEnchantAPI.getInstance().getEnchantments( itemInHand.getBukkitStack() ) .get( TokenEnchantAPI.getInstance().getEnchantment("Fortune")); usedTEFortune = true; + debugInfo.append( "used TokenEnchantAPI: level " ).append( fortLevel ); } } catch ( Exception e ) { - // ignore: could not use TE. + // ignore: could not use TE or TE version before v23.x is not loaded + + // Test for TE v23 & newer: + try { + Class.forName( "com.vk2gpz.tokenenchant.api.ITokenEnchant", false, this.getClass().getClassLoader() ); + + if ( ITokenEnchant.getInstance() != null ) { + + fortLevel = ITokenEnchant.getInstance().getEnchantments( itemInHand.getBukkitStack() ) + .get( ITokenEnchant.getInstance().getEnchantment("Fortune")); + + usedTEFortune = true; + debugInfo.append( "used ITokenEnchant: level " ).append( fortLevel ); + } + } + catch ( Exception e2 ) { + // Ignore - Cannot use TE + } + } + + if ( !usedTEFortune ) { + debugInfo.append( " &4WARNING: Feature enabled but TE not found.&3" ); + } + + debugInfo.append(")"); } try { From e71a2c1a0efe22f728c629020fad378a89a450b6 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 20 Jul 2024 01:09:37 -0400 Subject: [PATCH 091/323] Mine bombs: Hex color codes: Setup one mine bomb using hex color codes. Hex color support was added to minecraft with spigot v1.16. Older versions of spigot will not work. No changes were needed to allow the hex support since prison was already handling support for hex colors. This is triggered with a prefix of '&#' followed by the 6 hex digits, such as '&#a1b2c3'. As a result, this simple hex color code will be translated by prison in to the code structure that spigot and paper will recognize: '&#a1b2c3' is converted to: '&x&a&1&b&2&c&3' --- .../src/main/java/tech/mcprison/prison/util/Text.java | 6 ++++++ 1 file changed, 6 insertions(+) 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 972567829..d0fd98d18 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 @@ -520,6 +520,12 @@ public static String translateHexColorCodesCore(String message, char targetColor if ( message != null ) { + // NOTE: if '&#' is used, then it will convert the hex codes, but it will also + // leave the leading '&' there. So remove the '&' prefix. + if ( message != null && message.contains( "&#" ) ) { + message = message.replace( "&#", "#" ); + } + // final Pattern hexPattern = Pattern.compile(startTag + "([A-Fa-f0-9]{6})" + endTag); Matcher matcher = HEX_PATTERN.matcher(message); From be99c3a31e2592069b8f0d9ec848eac38fa38ff7 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 20 Jul 2024 21:40:31 -0400 Subject: [PATCH 092/323] Mine bombs: Geometric: update descriptions and create unit tests to confirm if the function getPointsOnCircleXZ are producing the intended results. --- docs/changelog_v3.3.x.md | 8 +- .../prison/bombs/GeometricShapes.java | 11 +++ .../prison/bombs/GeometricShapesTest.java | 67 +++++++++++++++++ .../mcprison/prison/internal/WorldTest.java | 74 +++++++++++++++++++ 4 files changed, 159 insertions(+), 1 deletion(-) create mode 100644 prison-core/src/test/java/tech/mcprison/prison/bombs/GeometricShapesTest.java create mode 100644 prison-core/src/test/java/tech/mcprison/prison/internal/WorldTest.java diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index e72c4db4c..098021973 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-beta.18c 2024-07-19 +# 3.3.0-beta.18c 2024-07-20 + + + + +* **Mine bombs: Geometric: update descriptions and create unit tests to confirm if the function getPointsOnCircleXZ are producing the intended results.** + * **Autofeatures: Use TokenEnchant fortune levels: Added support for the newer TE API "ITokenEnchant". "TokenEnchantAPI" is still supported.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/GeometricShapes.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/GeometricShapes.java index c0bb4768f..5f8ced4df 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/GeometricShapes.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/GeometricShapes.java @@ -262,6 +262,17 @@ public static void drawTorus( PrisonBlock block, World world, int xi, int yi, in // } // } + /** + * This will calculate a new Vector based upon the degrees (angle), and the + * radius (distance from the center); + * + * Incrementing the degrees, with keeping the same value for radius, should + * draw a circle on the plane X-Z. + * + * @param degrees + * @param radius + * @return + */ public static Vector getPointsOnCircleXZ( double degrees, double radius ) { Vector results = null; diff --git a/prison-core/src/test/java/tech/mcprison/prison/bombs/GeometricShapesTest.java b/prison-core/src/test/java/tech/mcprison/prison/bombs/GeometricShapesTest.java new file mode 100644 index 000000000..870bc0550 --- /dev/null +++ b/prison-core/src/test/java/tech/mcprison/prison/bombs/GeometricShapesTest.java @@ -0,0 +1,67 @@ +package tech.mcprison.prison.bombs; + +import java.text.DecimalFormat; + +import tech.mcprison.prison.internal.World; +import tech.mcprison.prison.internal.WorldTest; +import tech.mcprison.prison.util.Location; +import tech.mcprison.prison.util.Vector; + +public class GeometricShapesTest extends GeometricShapes { + +// @Test + public void test() { + + DecimalFormat dFmt = new DecimalFormat( "##0" ); + double radius = 1d; + + for ( double deg = 0; deg <= 360; deg += 5 ) { + + Vector v = getPointsOnCircleXZ( deg, radius ); + + System.out.println( + String.format( + "points on a circle: degree: %s r: %s %s", + dFmt.format( deg ), + dFmt.format( radius ), + v.toString() + ) + ); + } + } + +// @Test + public void testWithLocations() { + + DecimalFormat dFmt = new DecimalFormat( "##0" ); + + double x = 120; + double y = 60; + double z = -50; + + World w = new WorldTest(); + + Location loc = new Location( w, x, y, z ); + + double radius = 1d; + + for ( double deg = 0; deg <= 360; deg += 5 ) { + + Vector v = getPointsOnCircleXZ( deg, radius ); + + Location circleLoc = loc.add( v ); + + System.out.println( + String.format( + "points on a circle: degree: %3s r: %2s %s %s", + dFmt.format( deg ), + dFmt.format( radius ), + v.toString(), + circleLoc.toString() + ) + ); + } + + } + +} diff --git a/prison-core/src/test/java/tech/mcprison/prison/internal/WorldTest.java b/prison-core/src/test/java/tech/mcprison/prison/internal/WorldTest.java new file mode 100644 index 000000000..179383f2c --- /dev/null +++ b/prison-core/src/test/java/tech/mcprison/prison/internal/WorldTest.java @@ -0,0 +1,74 @@ +package tech.mcprison.prison.internal; + +import java.util.ArrayList; +import java.util.List; + +import tech.mcprison.prison.internal.block.Block; +import tech.mcprison.prison.internal.block.MineResetType; +import tech.mcprison.prison.internal.block.MineTargetPrisonBlock; +import tech.mcprison.prison.internal.block.PrisonBlock; +import tech.mcprison.prison.util.Location; + +public class WorldTest implements World { + + + @Override + public String getName() { + return "Test world - does not exist"; + } + + @Override + public List getPlayers() { + return new ArrayList<>(); + } + + @Override + public List getEntities() { + return new ArrayList<>(); + } + + @Override + public Block getBlockAt(Location location) { + return PrisonBlock.AIR; + } + + @Override + public Block getBlockAt(Location location, boolean containsCustomBlocks) { + return PrisonBlock.AIR; + } + + @Override + public void setBlock(PrisonBlock block, int x, int y, int z) { + } + + @Override + public void setBlockAsync(PrisonBlock prisonBlock, Location location) { + } + + @Override + public void setBlocksSynchronously(List tBlocks, MineResetType resetType, + PrisonStatsElapsedTimeNanos nanos) { + } + + @Override + public Entity spawnEntity(Location loc, EntityType entityType) { + return null; + } + + @Override + public ArmorStand spawnArmorStand(Location location) { + return null; + } + + @Override + public ArmorStand spawnArmorStand(Location location, String itemType, String customName, String nbtKey, + String nbtValue) { + return null; + } + + @Override + public int getMaxHeight() { + return 255; + } + +} From a2a8929c9e8e5fd48dcd5c52ee14a5de6f17bf4c Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 20 Jul 2024 21:52:24 -0400 Subject: [PATCH 093/323] Location and Vector: Enhance the toString() functions so they can be used in debugging and unit tests. --- docs/changelog_v3.3.x.md | 2 + .../tech/mcprison/prison/util/Location.java | 43 ++++++++++++++++--- .../tech/mcprison/prison/util/Vector.java | 21 ++++++++- 3 files changed, 60 insertions(+), 6 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 098021973..5dc22a9d1 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-beta.18c 2024-07-20 +* **Location and Vector: Enhance the toString() functions so they can be used in debugging and unit tests.** + * **Mine bombs: Geometric: update descriptions and create unit tests to confirm if the function getPointsOnCircleXZ are producing the intended results.** 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 8c01203f1..f4d34f7c8 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 @@ -18,6 +18,8 @@ package tech.mcprison.prison.util; +import java.text.DecimalFormat; + import tech.mcprison.prison.Prison; import tech.mcprison.prison.internal.ArmorStand; import tech.mcprison.prison.internal.Entity; @@ -124,6 +126,13 @@ public Vector getDirection() { return direction; } + /** + * Sets the {@link #getYaw() yaw} and {@link #getPitch() pitch} to point + * in the direction of the vector. + * + * @param vector the direction vector + * @return the same location + */ public void setDirection( Vector direction ) { this.direction = direction; } @@ -174,7 +183,8 @@ public void setCorner(boolean isCorner) { this.isCorner = isCorner; } - @Override public boolean equals(Object o) { + @Override + public boolean equals(Object o) { if (this == o) { return true; } @@ -192,7 +202,8 @@ public void setCorner(boolean isCorner) { } - @Override public int hashCode() { + @Override + public int hashCode() { int result; long temp; result = world != null ? world.hashCode() : 0; @@ -207,9 +218,17 @@ public void setCorner(boolean isCorner) { return result; } - @Override public String toString() { - return "Location{" + "world=" + world + ", x=" + x + ", y=" + y + ", z=" + z + ", pitch=" - + pitch + ", yaw=" + yaw + '}'; + @Override + public String toString() { + + DecimalFormat dFmt = new DecimalFormat( "0.00" ); + + return "Location{" + "world=" + world.getName() + ", " + + "x=" + dFmt.format(x) + ", " + + "y=" + dFmt.format(y) + ", " + + "z=" + dFmt.format(z) + ", " + + "pitch=" + dFmt.format(pitch) + ", " + + "yaw=" + dFmt.format(yaw) + '}'; } /** @@ -244,6 +263,7 @@ public static Location decodeWorldCoordinates( String worldCoordinats ) { public String toBlockCoordinates() { return "(" + Math.round(x) + ", " + Math.round(y) + ", " + Math.round(z) + ")"; } + public Location add( Vector direction ) { Location results = new Location( this ); @@ -256,6 +276,19 @@ public Location add( Vector direction ) return results; } + /** + * This returns a vector based upon the current location. + * + * Note that this is based upon org.bucket.location.Location.toVector() and + * it does not use yaw. + * + * @return + */ + public Vector toVector() { + Vector results = new Vector( getX(), getY(), getZ() ); + return results; + } + /** *

This function will clone the current location object and then add/subtract the amount of * x, y, and/or z to that location. To keep the same value for one or more of these coordinates diff --git a/prison-core/src/main/java/tech/mcprison/prison/util/Vector.java b/prison-core/src/main/java/tech/mcprison/prison/util/Vector.java index 46c93e2ee..1ed0850a8 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/util/Vector.java +++ b/prison-core/src/main/java/tech/mcprison/prison/util/Vector.java @@ -20,6 +20,7 @@ import tech.mcprison.prison.internal.World; +import java.text.DecimalFormat; import java.util.LinkedHashMap; import java.util.Map; import java.util.Random; @@ -661,7 +662,25 @@ public int getBlockZ() { * Returns this vector's components as x,y,z. */ @Override public String toString() { - return x + "," + y + "," + z; + + DecimalFormat dFmt = new DecimalFormat( "##0.0000" ); + + String msg = String.format( + "x: %8s y: %8s z: %8s", + dFmt.format( getX() ), + dFmt.format( getY() ), + dFmt.format( getZ() ) + ); + + return msg; + +// StringBuilder sb = new StringBuilder(); +// sb.append( "x: " ).append( dFmt.format( getX() )).append( " " ) +// .append( "y: " ).append( dFmt.format( getY() )).append( " " ) +// .append( "z: " ).append( dFmt.format( getZ() )); +// +// return sb.toString(); +// return x + "," + y + "," + z; } /** From 0bc56d7b54dc186a47a766c7f9fd34ceead84d19 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 20 Jul 2024 21:55:42 -0400 Subject: [PATCH 094/323] Mine bombs: Added support for "small" armorstands. --- .../mcprison/prison/bombs/MineBombData.java | 32 +++++++++++++++++-- .../bombs/animations/BombAnimations.java | 2 ++ 2 files changed, 32 insertions(+), 2 deletions(-) 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 c5f693592..447f10468 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 @@ -222,11 +222,29 @@ public class MineBombData /** - * + * This feature will allow the player to add all the exploded blocks to + * their block counts. If set to false, then this will not add bomb + * related block breaks to the player's block counts, which will help + * keep the payer's counts focused on actual blocks broken. */ private boolean applyToPlayersBlockCount = true; + /** + * If small is set to true, then the armor stand that will be generated + * will be a smaller version of the standard size. This maybe about 1 + * block high, instead of the normal 2 blocks high. + * + * Since the armor stand will be reduced in size by half, so will the item + * that it is holding, it too will be reduced in size. + * + * This feature is dependent upon how bukkit handles this setting, + * therefore it may or may not work, or it may behave differently than + * what is described here. + */ + private boolean small = false; + + /** *

Internal just to indicated if a mine bomb is activated or not. * This has not purpose if used in a save file. @@ -309,6 +327,8 @@ public MineBombData( String name, String itemType, String explosionShape, this.autosell = false; this.customModelData = 0; + this.small = false; + this.applyToPlayersBlockCount = true; @@ -357,6 +377,8 @@ public MineBombData clone() { cloned.setCustomModelData( getCustomModelData() ); + cloned.setSmall( isSmall() ); + for ( String l : getLore() ) { cloned.getLore().add( l ); @@ -703,7 +725,13 @@ public void setApplyToPlayersBlockCount(boolean applyToPlayersBlockCount) { this.applyToPlayersBlockCount = applyToPlayersBlockCount; } - + public boolean isSmall() { + return small; + } + public void setSmall(boolean small) { + this.small = small; + } + public boolean addSoundEffects( MineBombEffectsData effect ) { boolean results = false; diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java index d73874830..9f4e9182c 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java @@ -123,6 +123,8 @@ public void initialize() { // armorStand.setNbtString( MineBombs.MINE_BOMBS_NBT_THROWER_UUID, // playerUUID ); + armorStand.setSmall( getBomb().isSmall() ); + armorStand.setRightArmPose(arm); // ItemStack itemInHand = armorStand.getItemInHand(); From 12337f24e801c1309a96b3ae9ae7b22c6bcf6b06 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 20 Jul 2024 21:58:58 -0400 Subject: [PATCH 095/323] Mine bombs: Added support for "small" armorstands. --- docs/changelog_v3.3.x.md | 3 +++ .../java/tech/mcprison/prison/internal/ArmorStand.java | 3 +++ .../prison/spigot/game/entity/SpigotArmorStand.java | 9 +++++++++ 3 files changed, 15 insertions(+) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 5dc22a9d1..4fe480aa3 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-beta.18c 2024-07-20 +* **Mine bombs: Added support for "small" armorstands.** + + * **Location and Vector: Enhance the toString() functions so they can be used in debugging and unit tests.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/ArmorStand.java b/prison-core/src/main/java/tech/mcprison/prison/internal/ArmorStand.java index 3121af02c..dd0bd3d6d 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/ArmorStand.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/ArmorStand.java @@ -35,5 +35,8 @@ public interface ArmorStand public boolean getCanPickupItems(); public void setCanPickupItems( boolean canPickupItems ); + + public boolean isSmall(); + public void setSmall(boolean small); } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotArmorStand.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotArmorStand.java index c48c002ed..34052464b 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotArmorStand.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotArmorStand.java @@ -200,5 +200,14 @@ public boolean getCanPickupItems() { public void setCanPickupItems( boolean canPickupItems ) { bArmorStand.setCanPickupItems( canPickupItems ); } + + @Override + public boolean isSmall() { + return bArmorStand.isSmall(); + } + @Override + public void setSmall(boolean small) { + bArmorStand.setSmall(small); + } } From ffef736257395a69a9703038779abf54144d4b0b Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 20 Jul 2024 22:10:00 -0400 Subject: [PATCH 096/323] Mine Bombs: Add new settings for animationOffset and animationSpeed. Animation speed controls how much the animation angles change by adding this value to the prior value. Smaller is slower, and larger is faster. Animation offset is used on animations that move the actual armor stands, such as orbital, orbital8, and starburst. If offset is zero, then it will result in a round orbit. If it non-zero, then it will rotate around a point outside of the original location. Multiple ArmorStand animations, like orbital8 and starburst, will offset each placed armorstand around the main Location, therefore creating interesting geometric patterns. --- docs/changelog_v3.3.x.md | 7 +++++ .../mcprison/prison/bombs/MineBombData.java | 26 ++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 4fe480aa3..601ec91b2 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-beta.18c 2024-07-20 +* **Mine Bombs: Add new settings for animationOffset and animationSpeed. +Animation speed controls how much the animation angles change by adding this value to the prior value.** +Smaller is slower, and larger is faster. +Animation offset is used on animations that move the actual armor stands, such as orbital, orbital8, and starburst. +If offset is zero, then it will result in a round orbit. If it non-zero, then it will rotate around a point outside of the original location. Multiple ArmorStand animations, like orbital8 and starburst, will offset each placed armorstand around the main Location, therefore creating interesting geometric patterns. + + * **Mine bombs: Added support for "small" armorstands.** 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 447f10468..88fb679dc 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 @@ -117,7 +117,7 @@ public class MineBombData * of the mine too. *

*/ - private int placementAdjustmentY = -1; + private int placementAdjustmentY = 0; /** *

The chance of complete removal. So if the explosion includes @@ -165,6 +165,9 @@ public class MineBombData */ private AnimationPattern animationPattern = AnimationPattern.infinity; + private double animationOffset = 0; + + private double animationSpeed = 5; private double throwVelocityLow = 1.5; @@ -365,6 +368,9 @@ public MineBombData clone() { cloned.setGravity( isGravity() ); cloned.setAnimationPattern( getAnimationPattern() ); + cloned.setAnimationOffset( getAnimationOffset() ); + cloned.setAnimationSpeed( getAnimationSpeed() ); + cloned.setThrowVelocityLow( getThrowVelocityLow() ); cloned.setThrowVelocityHigh( getThrowVelocityHigh() ); @@ -669,6 +675,24 @@ public void setAnimationPattern(AnimationPattern animationPattern) { animationPattern; } + public double getAnimationOffset() { + return animationOffset; + } + public void setAnimationOffset(double animationOffset) { + this.animationOffset = animationOffset; + } + + public double getAnimationSpeed() { + return animationSpeed; + } + public void setAnimationSpeed(double animationSpeed) { + this.animationSpeed = animationSpeed; + } + + public int getTaskId() { + return taskId; + } + public double getThrowVelocityLow() { return throwVelocityLow; } From 31461f20f35170598172c400c7e6e7b8fd269e60 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 20 Jul 2024 22:14:33 -0400 Subject: [PATCH 097/323] Mine Bombs: added two new AnimationPatterns: orbital8 and starburst. --- docs/changelog_v3.3.x.md | 7 ++-- .../tech/mcprison/prison/bombs/MineBombs.java | 3 +- .../bombs/animations/BombAnimations.java | 34 ++++++++++++++----- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 601ec91b2..b47704e04 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-beta.18c 2024-07-20 -* **Mine Bombs: Add new settings for animationOffset and animationSpeed. -Animation speed controls how much the animation angles change by adding this value to the prior value.** +* **Mine Bombs: added two new AnimationPatterns: orbital8 and starburst.** + + +* **Mine Bombs: Add new settings for animationOffset and animationSpeed.** +Animation speed controls how much the animation angles change by adding this value to the prior value. Smaller is slower, and larger is faster. Animation offset is used on animations that move the actual armor stands, such as orbital, orbital8, and starburst. If offset is zero, then it will result in a round orbit. If it non-zero, then it will rotate around a point outside of the original location. Multiple ArmorStand animations, like orbital8 and starburst, will offset each placed armorstand around the main Location, therefore creating interesting geometric patterns. 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 b6ad51a56..b2993875b 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 @@ -95,7 +95,8 @@ public enum AnimationPattern { infinityEight, bounce, orbital, - orbitalEight + orbitalEight, + starburst ; diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java index 9f4e9182c..ec14429ac 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java @@ -87,24 +87,42 @@ protected void cancel() { public void initialize() { Location location = getsBlock().getLocation(); - location.setY( location.getY() + 3 ); + location.setY( location.getY() + 2.5 ); - location.setYaw( entityYaw ); - location.setPitch( entityPitch + 90 ); + // NOTE: The direction the entity is facing is based upon yaw. + // When using org.bukkit.Location.setDirection() it's using a vector + // to set yaw and pitch so it's looking at that vector point. + // So... I guess that means an entity cannot turn their head? + // For entities, or at least armorStands, there is an Euler angle + // based getHeadPose() and setHeadPose() functions. + location.setYaw( entityYaw ); - double startingAngle = ( 360d / entityYaw ) * twoPI; + + // Not sure why 90 was being added. I suspect 0 is straight up? + location.setPitch( entityPitch + 90 ); + + + +// double startingAngle = ( 360d / entityYaw ) * twoPI; +// location.setDirection( startingAngle ); // eulerAngleX += startingAngle; EulerAngle arm = new EulerAngle( - eulerAngleX + startingAngle, - eulerAngleY + startingAngle, - eulerAngleZ + startingAngle ); + eulerAngleX, + eulerAngleY, + eulerAngleZ ); + +// EulerAngle arm = new EulerAngle( +// eulerAngleX + startingAngle, +// eulerAngleY + startingAngle, +// eulerAngleZ + startingAngle ); // Spawn an invisible armor stand: - armorStand = location.spawnArmorStand( getBomb().getItemType(), + armorStand = location.spawnArmorStand( + (getItem() == null ? null : getBomb().getItemType()), getBomb().getName(), MineBombs.MINE_BOMBS_NBT_KEY, getBomb().getName() ); // armorStand = location.spawnArmorStand(); From ab4c2b8d2e294c7dc5c0dad87ba1f279238c5581 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 20 Jul 2024 22:16:11 -0400 Subject: [PATCH 098/323] Mine Bombs: Added the setup for starburst animations. --- docs/changelog_v3.3.x.md | 4 ++++ .../bombs/animations/BombAnimationsTask.java | 23 +++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index b47704e04..22dc7c270 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-beta.18c 2024-07-20 +* **Mine Bombs: Added the setup for starburst animations.** + + + * **Mine Bombs: added two new AnimationPatterns: orbital8 and starburst.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationsTask.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationsTask.java index ca8d0b858..99a5dd93d 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationsTask.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationsTask.java @@ -106,7 +106,30 @@ public void animatorFactory( submitTask(); } + break; + + case starburst: + { + float yaw = 0; + float pitch = 0; + float yawStep = 360f / 16f; + for ( int i = 0; i < 16; i++ ) { + BombAnimationOrbital ba = new BombAnimationOrbital( bomb, + pBlock, item, this, + yaw, pitch ); + + ba.setAlternateDirections( true ); + + getAnimators().add( ba ); + + yaw += yawStep; + } + + submitTask(); + } + break; + case infinity: { float yaw = 0; From ae25b8d221aeff1579a3b9a5fd93c373d44549ac Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 20 Jul 2024 22:19:54 -0400 Subject: [PATCH 099/323] Mine Bombs: Added a first none animation to the animation pattern so the holograph remains in the same spot. Otherwise it would move with the first moving armorstand. Orbital, orbital8, and starburst move armorstands so this allows the name to remain stationary. --- docs/changelog_v3.3.x.md | 5 +++++ .../bombs/animations/BombAnimationsTask.java | 15 +++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 22dc7c270..b91840c6a 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-beta.18c 2024-07-20 +* **Mine Bombs: Added a first none animation to the animation pattern so the holograph remains in the same spot.** +Otherwise it would move with the first moving armorstand. +Orbital, orbital8, and starburst move armorstands so this allows the name to remain stationary. + + * **Mine Bombs: Added the setup for starburst animations.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationsTask.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationsTask.java index 99a5dd93d..a1f815531 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationsTask.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationsTask.java @@ -75,6 +75,11 @@ public void animatorFactory( case orbital: { + // Add BombAnimationNone for a stationary name: + BombAnimationNone baHolo = new BombAnimationNone( bomb, + pBlock, null, this, 0f, 0f ); + getAnimators().add( baHolo ); + float yaw = 0; float pitch = 0; @@ -90,6 +95,11 @@ public void animatorFactory( case orbitalEight: { + // Add BombAnimationNone for a stationary name: + BombAnimationNone baHolo = new BombAnimationNone( bomb, + pBlock, null, this, 0f, 0f ); + getAnimators().add( baHolo ); + float yaw = 0; float pitch = 0; float yawStep = 360f / 8f; @@ -110,6 +120,11 @@ public void animatorFactory( case starburst: { + // Add BombAnimationNone for a stationary name: + BombAnimationNone baHolo = new BombAnimationNone( bomb, + pBlock, null, this, 0f, 0f ); + getAnimators().add( baHolo ); + float yaw = 0; float pitch = 0; float yawStep = 360f / 16f; From 3d2ce0cad8018dca0a558d4a0b194a2c055908cc Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 20 Jul 2024 22:22:44 -0400 Subject: [PATCH 100/323] Mine Bombs: update the orbital animation to fix a few issues. --- docs/changelog_v3.3.x.md | 4 ++ .../animations/BombAnimationOrbital.java | 68 +++++++++++++++++-- 2 files changed, 66 insertions(+), 6 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index b91840c6a..0915de7ad 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-beta.18c 2024-07-20 +* **Mine Bombs: update the orbital animation to fix a few issues.** + + + * **Mine Bombs: Added a first none animation to the animation pattern so the holograph remains in the same spot.** Otherwise it would move with the first moving armorstand. Orbital, orbital8, and starburst move armorstands so this allows the name to remain stationary. diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationOrbital.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationOrbital.java index dca1dc65e..0a8a5b2e8 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationOrbital.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationOrbital.java @@ -16,30 +16,58 @@ public class BombAnimationOrbital extends BombAnimations { private double angle = 0.0; private double radius = 1.0; - private Location oLoc = null; + private boolean alternateDirections = false; + + private Location originalLocation; + +// private Location oLoc = null; public BombAnimationOrbital(MineBombData bomb, PrisonBlock sBombBlock, ItemStack item, BombAnimationsTask task, float entityYaw, float entityPitch) { super(bomb, sBombBlock, item, task, entityYaw, entityPitch); + this.angle = entityYaw; + + this.originalLocation = getArmorStand().getLocation(); + + } @Override public void stepAnimation() { - angle += 25; + if ( isAlternateDirections() ) { + + if ( getId() % 2 == 0 ) { + angle += 5; + } + else { + angle -= 5; + } + + } + else { + angle += 5; + } if ( angle > 360 ) { angle -= 360; } - - if ( oLoc == null ) { - oLoc = new Location( getArmorStand().getLocation() ); + else if ( angle < -360 ) { + angle += 360; } + +// if ( oLoc == null ) { +// oLoc = new Location( getArmorStand().getLocation() ); +// } +// Location loc = getArmorStand().getLocation(); Vector vector = GeometricShapes.getPointsOnCircleXZ( angle, radius ); - Location newLoc = new Location( oLoc ).add(vector); + + // Location.add() creates a new instance of a Location and does not change + // the original value: + Location newLoc = getOriginalLocation().add(vector); getArmorStand().teleport( newLoc ); @@ -118,4 +146,32 @@ public void stepAnimation() { // getArmorStand().setRightArmPose(arm); } + public double getAngle() { + return angle; + } + public void setAngle(double angle) { + this.angle = angle; + } + + public double getRadius() { + return radius; + } + public void setRadius(double radius) { + this.radius = radius; + } + + public boolean isAlternateDirections() { + return alternateDirections; + } + public void setAlternateDirections(boolean alternateDirections) { + this.alternateDirections = alternateDirections; + } + + public Location getOriginalLocation() { + return originalLocation; + } + public void setOriginalLocation(Location originalLocation) { + this.originalLocation = originalLocation; + } + } From 001d28a02e02e3ce928c87daf07dadca7d596f0d Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 21 Jul 2024 14:03:58 -0400 Subject: [PATCH 101/323] Mine Bombs: removed nbt info that was being passed into the creation of an ArmorStand. This never did work correctly since it was set on the bukkit object, which was not visible when wrapped with a prison object. --- docs/changelog_v3.3.x.md | 7 ++++++- .../java/tech/mcprison/prison/internal/World.java | 2 +- .../test/java/tech/mcprison/prison/TestWorld.java | 3 +-- .../tech/mcprison/prison/internal/WorldTest.java | 4 ++-- .../mcprison/prison/spigot/game/SpigotWorld.java | 13 ++++++++----- 5 files changed, 18 insertions(+), 11 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 0915de7ad..75ec82670 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-beta.18c 2024-07-20 +# 3.3.0-beta.18c 2024-07-21 + + + +* **Mine Bombs: removed nbt info that was being passed into the creation of an ArmorStand.** +This never did work correctly since it was set on the bukkit object, which was not visible when wrapped with a prison object. * **Mine Bombs: update the orbital animation to fix a few issues.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/World.java b/prison-core/src/main/java/tech/mcprison/prison/internal/World.java index cd8dc249e..3ec2e1250 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/World.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/World.java @@ -90,7 +90,7 @@ public void setBlocksSynchronously( List tBlocks, public ArmorStand spawnArmorStand(Location location, String itemType, - String customName, String nbtKey, String nbtValue); + String customName ); public int getMaxHeight(); diff --git a/prison-core/src/test/java/tech/mcprison/prison/TestWorld.java b/prison-core/src/test/java/tech/mcprison/prison/TestWorld.java index 636c9523c..2f6fd4dcc 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/TestWorld.java +++ b/prison-core/src/test/java/tech/mcprison/prison/TestWorld.java @@ -102,8 +102,7 @@ public int getMaxHeight() { @Override public ArmorStand spawnArmorStand(Location location, String itemType, - String customName, String nbtKey, - String nbtValue) { + String customName ) { return null; } diff --git a/prison-core/src/test/java/tech/mcprison/prison/internal/WorldTest.java b/prison-core/src/test/java/tech/mcprison/prison/internal/WorldTest.java index 179383f2c..b00142e08 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/internal/WorldTest.java +++ b/prison-core/src/test/java/tech/mcprison/prison/internal/WorldTest.java @@ -61,8 +61,8 @@ public ArmorStand spawnArmorStand(Location location) { } @Override - public ArmorStand spawnArmorStand(Location location, String itemType, String customName, String nbtKey, - String nbtValue) { + public ArmorStand spawnArmorStand(Location location, String itemType, + String customName ) { return null; } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotWorld.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotWorld.java index 3b465279e..d52e168e7 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotWorld.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotWorld.java @@ -329,7 +329,10 @@ public org.bukkit.entity.ArmorStand spawnBukkitArmorStand( Location location ) { @Override public ArmorStand spawnArmorStand( Location location, String itemType, - String customName, String nbtKey, String nbtValue ) { + String customName +// , +// String nbtKey, String nbtValue + ) { int maxHight = location.getWorld().getMaxHeight(); @@ -354,10 +357,10 @@ public ArmorStand spawnArmorStand( Location location, String itemType, } - if ( nbtKey != null && nbtValue != null ) { - - PrisonNBTUtil.setNBTString( as, nbtKey, nbtValue ); - } +// if ( nbtKey != null && nbtValue != null ) { +// +// PrisonNBTUtil.setNBTString( as, nbtKey, nbtValue ); +// } if ( itemType != null && itemType.trim().length() > 0 ) { From f2377f95b7c42ac7c2114b89b5724831505db5e7 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 21 Jul 2024 14:12:20 -0400 Subject: [PATCH 102/323] Mine Bombs: Added transient variables for the placed block which is not accurate, and also the placed bomb location which is accurate. The SpigotPlayer is able to get the location where the player is looking. The placedBombLocation is derived by calculating the location where the player is looking when right-clicking to place a bomb, or it's from the location where the bomb item is sitting after its thrown. --- .../mcprison/prison/bombs/MineBombData.java | 29 ++++++++++++++++++- .../prison/spigot/game/SpigotPlayer.java | 21 ++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) 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 88fb679dc..e49bb1a5c 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 @@ -10,6 +10,7 @@ import tech.mcprison.prison.internal.block.Block; import tech.mcprison.prison.internal.block.PrisonBlock; import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.util.Location; public class MineBombData implements Comparable @@ -261,7 +262,20 @@ public class MineBombData private TreeSet visualEffects; - private Block placedBombBlock; + + /** + * This is a block that is "closest" to the location where the animation center + * point should be. But note, since the location is not exact, and there is rounding, + * this block may not be the block that was actually clicked, or where the item + * landed. For precise location, use placedBombLocation if it is not null. + * this should be used as a back for the location for the animation center point. + */ + private transient Block placedBombBlock; + + /** + * If not null, then this should be the animation target's center point. + */ + private transient Location placedBombLocation; private transient int taskId = -1; @@ -335,6 +349,9 @@ public MineBombData( String name, String itemType, String explosionShape, this.applyToPlayersBlockCount = true; + this.placedBombBlock = null; + this.placedBombLocation = null; + } @@ -385,6 +402,9 @@ public MineBombData clone() { cloned.setSmall( isSmall() ); + cloned.setPlacedBombBlock( getPlacedBombBlock() ); + cloned.setPlacedBombLocation( getPlacedBombLocation() ); + for ( String l : getLore() ) { cloned.getLore().add( l ); @@ -825,6 +845,13 @@ public void setPlacedBombBlock( Block placedBombBlock ) { this.placedBombBlock = placedBombBlock; } + public Location getPlacedBombLocation() { + return placedBombLocation; + } + public void setPlacedBombLocation(Location placedBombLocation) { + this.placedBombLocation = placedBombLocation; + } + public int getTask() { return taskId; 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 b66d47ad7..b2cb656b8 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 @@ -59,6 +59,7 @@ import tech.mcprison.prison.spigot.utils.tasks.PlayerMessagingTask; import tech.mcprison.prison.util.Gamemode; import tech.mcprison.prison.util.Location; +import tech.mcprison.prison.util.Vector; /** * @author Faizaan A. Datoo @@ -263,6 +264,26 @@ public SpigotBlock getLineOfSightBlock() { } + public Location getLineOfSightExactLocation() { + + SpigotLocation eyeLoc = new SpigotLocation( getWrapper().getEyeLocation() ); + Vector eyeVec = eyeLoc.getDirection(); + + Location loc = eyeLoc.add(eyeVec); + + int i = 0; + while ( i++ <= 50 && loc.getBlockAt().isEmpty() ) { + + loc = loc.add(eyeVec); + } + + if ( loc.getBlockAt().isEmpty() ) { + loc = null; + } + + return loc; + } + /** *

This will return a list of blocks that are in the line of sight of the player. * It will initially ignore all air blocks until it hits a non-air block, then it will From 09aff9366ba0ddb794066754f677bc653fbf8a3f Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 21 Jul 2024 14:21:19 -0400 Subject: [PATCH 103/323] Mine BoMine Bombs: removed nbt info that was being passed into the creation of an ArmorStand. This never did work correctly since it was set on the bukkit object, which was not visible when wrapped with a prison object. --- .../src/main/java/tech/mcprison/prison/util/Location.java | 6 ++---- .../tech/mcprison/prison/spigot/game/SpigotLocation.java | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) 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 f4d34f7c8..663564fbf 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 @@ -336,11 +336,9 @@ public ArmorStand spawnArmorStand() { return getWorld().spawnArmorStand( this ); } - public ArmorStand spawnArmorStand( String itemName, String name, - String nbtKey, - String nbtValue ) { + public ArmorStand spawnArmorStand( String itemName, String name ) { - return getWorld().spawnArmorStand( this, itemName, name, nbtKey, nbtValue ); + return getWorld().spawnArmorStand( this, itemName, name ); } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotLocation.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotLocation.java index 75b41866e..91b95dbd8 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotLocation.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotLocation.java @@ -40,7 +40,7 @@ public static org.bukkit.Location getBukkitLocation( Location location ) { org.bukkit.World world = Bukkit.getWorld( location.getWorld().getName() ); org.bukkit.Location bLocation = new org.bukkit.Location(world, - location.getBlockX(), location.getBlockY(), location.getBlockZ() ); + location.getX(), location.getY(), location.getZ() ); bLocation.setYaw( location.getYaw() ); From 61f2dd59fe1d554e30f1256c6f7fee758258ebb3 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 21 Jul 2024 14:26:58 -0400 Subject: [PATCH 104/323] Mine Bombs: More adjustments to the animation objects. Mostly cleaning them up. --- docs/changelog_v3.3.x.md | 3 + .../animations/BombAnimationOrbital.java | 66 ++----------------- .../bombs/animations/BombAnimations.java | 61 ++++++++++++----- 3 files changed, 53 insertions(+), 77 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 75ec82670..1d2bc080d 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-beta.18c 2024-07-21 +* **Mine Bombs: More adjustments to the animation objects.** +Mostly cleaning them up. + * **Mine Bombs: removed nbt info that was being passed into the creation of an ArmorStand.** This never did work correctly since it was set on the bukkit object, which was not visible when wrapped with a prison object. diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationOrbital.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationOrbital.java index 0a8a5b2e8..6f00b01f6 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationOrbital.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationOrbital.java @@ -18,10 +18,6 @@ public class BombAnimationOrbital extends BombAnimations { private boolean alternateDirections = false; - private Location originalLocation; - -// private Location oLoc = null; - public BombAnimationOrbital(MineBombData bomb, PrisonBlock sBombBlock, ItemStack item, BombAnimationsTask task, float entityYaw, float entityPitch) { @@ -29,8 +25,10 @@ public BombAnimationOrbital(MineBombData bomb, PrisonBlock sBombBlock, this.angle = entityYaw; - this.originalLocation = getArmorStand().getLocation(); - + getOriginalLocation().setX( + getOriginalLocation().getX() + bomb.getAnimationOffset()); + getOriginalLocation().setZ( + getOriginalLocation().getZ() + bomb.getAnimationOffset()); } @@ -58,11 +56,6 @@ else if ( angle < -360 ) { angle += 360; } -// if ( oLoc == null ) { -// oLoc = new Location( getArmorStand().getLocation() ); -// } - -// Location loc = getArmorStand().getLocation(); Vector vector = GeometricShapes.getPointsOnCircleXZ( angle, radius ); // Location.add() creates a new instance of a Location and does not change @@ -71,20 +64,6 @@ else if ( angle < -360 ) { getArmorStand().teleport( newLoc ); -// oLoc.setYaw( (float) angle ); -// getArmorStand().teleport( oLoc ); - - - -// Location loc = getArmorStand().getLocation(); -// loc.setDirection( vector ); - -// float radians = (float) Math.toRadians(angle); -// loc.setYaw( radians ); - -// getArmorStand().teleport( loc ); - - // DecimalFormat dFmt = new DecimalFormat( "#,##0.0000" ); // Output.get().logInfo( // String.format( @@ -99,7 +78,6 @@ else if ( angle < -360 ) { - // double angle = 0.05; // Vector direction = getArmorStand().getLocation().getDirection(); // @@ -115,35 +93,6 @@ else if ( angle < -360 ) { // " z: " + getEulerAngleZ() ); -// angle += 5; - - //arm.rotateAroundAxisY( angle ); - -// Output.get().logInfo( arm.toString() ); - - //getArmorStand().setRightArmPose( arm ); - - -// EulerAngle arm = EulerAngle.rotateAroundAxisY( -// getEulerAngleX(), -// getEulerAngleY(), -// getEulerAngleZ(), -// angle ); -// -// setEulerAngleX( arm.getX() ); -// setEulerAngleY( arm.getY() ); -// setEulerAngleZ( arm.getZ() ); - -// double speed = 0.35; -// -// setEulerAngleX( getEulerAngleX() + speed ); -// setEulerAngleY( getEulerAngleY() + speed ); -//// setEulerAngleZ( getEulerAngleZ() + speed ); -// -// -// EulerAngle arm = new EulerAngle( getEulerAngleX(), getEulerAngleY(), getEulerAngleZ() ); - -// getArmorStand().setRightArmPose(arm); } public double getAngle() { @@ -167,11 +116,4 @@ public void setAlternateDirections(boolean alternateDirections) { this.alternateDirections = alternateDirections; } - public Location getOriginalLocation() { - return originalLocation; - } - public void setOriginalLocation(Location originalLocation) { - this.originalLocation = originalLocation; - } - } diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java index ec14429ac..25e2eadf8 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java @@ -9,7 +9,6 @@ import tech.mcprison.prison.internal.EulerAngle; import tech.mcprison.prison.internal.ItemStack; import tech.mcprison.prison.internal.block.PrisonBlock; -import tech.mcprison.prison.output.Output; import tech.mcprison.prison.util.BluesSemanticVersionComparator; import tech.mcprison.prison.util.Location; import tech.mcprison.prison.util.Text; @@ -24,6 +23,8 @@ public abstract class BombAnimations { private PrisonBlock sBlock; private ItemStack item; + private Location originalLocation; + private String customName; private boolean isDyanmicTag = false; private String tagName; @@ -62,6 +63,8 @@ public BombAnimations( MineBombData bomb, this.sBlock = sBombBlock; this.item = item; + this.originalLocation = null; + // this.ageTicks = 0; this.terminateOnZeroTicks = getTaskLifeSpan(); @@ -86,9 +89,15 @@ protected void cancel() { public void initialize() { - Location location = getsBlock().getLocation(); + Location location = + getBomb().getPlacedBombLocation() != null ? + getBomb().getPlacedBombLocation() : + getsBlock().getLocation(); + location.setY( location.getY() + 2.5 ); + setOriginalLocation( location ); + // NOTE: The direction the entity is facing is based upon yaw. // When using org.bukkit.Location.setDirection() it's using a vector @@ -122,13 +131,27 @@ public void initialize() { // Spawn an invisible armor stand: armorStand = location.spawnArmorStand( - (getItem() == null ? null : getBomb().getItemType()), - getBomb().getName(), - MineBombs.MINE_BOMBS_NBT_KEY, getBomb().getName() ); + getBomb().getItemType(), +// (getItem() == null ? null : getBomb().getItemType()), + getBomb().getName() ); + +// MineBombs.MINE_BOMBS_NBT_KEY, getBomb().getName() ); + + // armorStand = location.spawnArmorStand(); if ( armorStand != null ) { +// Output.get().logInfo( "### init mine bomb 1: id: " + getId() + " " + +// armorStand.getLocation().toString() ); + + // Need to teleport the armor stand to the actual location where it + // landed or was thrown to, otherwise it will look like it's offset. + //armorStand.teleport( getOriginalLocation() ); + +// Output.get().logInfo( "### init mine bomb 2: id: " + getId() + " " + +// armorStand.getLocation().toString() ); + // Sets visibility:false, arms:true, basePlate:false, canPickupItems:false, // removeWhenFar:false, gravity:false, and itemInHand. // armorStand.setupArmorStand( getBomb().getItemType() ); @@ -136,7 +159,7 @@ public void initialize() { armorStand.setCustomNameVisible( getId() == 0 && initializeCustomName() ); -// armorStand.setNbtString( MineBombs.MINE_BOMBS_NBT_KEY, getBomb().getName() ); + armorStand.setNbtString( MineBombs.MINE_BOMBS_NBT_KEY, getBomb().getName() ); // armorStand.setNbtString( MineBombs.MINE_BOMBS_NBT_THROWER_UUID, // playerUUID ); @@ -170,15 +193,16 @@ public void initialize() { } } - if ( Output.get().isDebug() ) { - String msg = String.format( - "### BombAnimation.initializeArmorStand : id: %s %s ", - Integer.toString(getId()), - bomb.getAnimationPattern().name() - ); - - Output.get().logInfo( msg ); - } +// if ( Output.get().isDebug() ) { +// String msg = String.format( +// "### BombAnimation.initializeArmorStand : id: %s %s %s", +// Integer.toString(getId()), +// bomb.getAnimationPattern().name(), +// armorStand.getLocation().toString() +// ); +// +// Output.get().logInfo( msg ); +// } } @@ -333,6 +357,13 @@ public void setItem(ItemStack item) { this.item = item; } + public Location getOriginalLocation() { + return originalLocation; + } + public void setOriginalLocation(Location originalLocation) { + this.originalLocation = originalLocation; + } + public boolean isDyanmicTag() { return isDyanmicTag; } From 16657051eee9834e69558ab7bce1133bdbe0dd65 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 23 Jul 2024 02:45:23 -0400 Subject: [PATCH 105/323] Mine bombs: Update the '/prison utils bomb list' command to include more of the mine bomb's features and options. Added support to show the available Mine Bomb's animation patterns. --- docs/changelog_v3.3.x.md | 6 +- .../tech/mcprison/prison/bombs/MineBombs.java | 26 +++++- .../spigot/utils/PrisonUtilsMineBombs.java | 92 ++++++++++++++----- 3 files changed, 99 insertions(+), 25 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 1d2bc080d..147801dec 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-beta.18c 2024-07-21 +# 3.3.0-beta.18c 2024-07-23 + + +* **Mine bombs: Update the '/prison utils bomb list' command to include more of the mine bomb's features and options. ** +Added support to show the available Mine Bomb's animation patterns. * **Mine Bombs: More adjustments to the animation objects.** 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 b2993875b..c220fd7ad 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 @@ -85,7 +85,19 @@ public enum ExplosionOrientation { y_axis, z_axis, - full + full; + + public static List asList() + { + List results = new ArrayList<>(); + + for ( ExplosionOrientation orientation : values() ) + { + results.add( orientation.name() ); + } + + return results; + } } @@ -115,6 +127,18 @@ public static final AnimationPattern fromString( String animationPattern ) { return results; } + + public static List asList() + { + List results = new ArrayList<>(); + + for ( AnimationPattern animation : values() ) + { + results.add( animation.name() ); + } + + return results; + } } /** 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 1cde4ab13..c206f9a81 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 @@ -27,6 +27,7 @@ import tech.mcprison.prison.bombs.MineBombEffectsData; import tech.mcprison.prison.bombs.MineBombEffectsData.EffectType; import tech.mcprison.prison.bombs.MineBombs; +import tech.mcprison.prison.bombs.MineBombs.AnimationPattern; import tech.mcprison.prison.bombs.MineBombs.ExplosionShape; import tech.mcprison.prison.bombs.animations.BombAnimationsTask; import tech.mcprison.prison.commands.Arg; @@ -491,9 +492,12 @@ public void reloadPrisonMineBombs() { onlyPlayers = false, permissions = "prison.utils.bombs" ) public void utilsMineBombsList( CommandSender sender, - @Arg(name = "option", description = "Options: Show 'all' bomb details. " + - "'shapes', 'sounds', and 'visuals' lists valid settings " + - "to be used with the bombs. [all shapes sounds visuals]", def = "" ) String options + @Arg(name = "option", description = "Options: By default, the abbreviated list of " + + "mine bombs are shown, with the 'all' options shows a lot mmore of the " + + "bomb details. " + + "The options of 'animations', 'shapes', 'sounds', and 'visuals' lists valid settings " + + "to be used with the bombs. [all animations shapes sounds visuals]", def = "" ) + String options ) { @@ -507,7 +511,25 @@ public void utilsMineBombsList( CommandSender sender, List messages = new ArrayList<>(); - boolean optAll = options != null && options.toLowerCase().contains( "all" ); + boolean optAll = false; + + if ( options != null && options.toLowerCase().contains( "all" ) ) { + options = options.replace( "all", "" ).trim(); + optAll = true; + } + + if ( options != null && options.toLowerCase().contains( "animations" ) ) { + // exit after showing the list of mine bomb animations: + + messages.add( "&7Animations Patterns:" ); + + List animations = AnimationPattern.asList(); + messages.addAll( Text.formatColumnsFromList( animations, 4 ) ); + + sender.sendMessage( messages.toArray( new String[0] ) ); + return; + } + if ( options != null && options.toLowerCase().contains( "shapes" ) ) { // exit after showing shapes: @@ -556,6 +578,9 @@ public void utilsMineBombsList( CommandSender sender, return; } + + + if ( options != null && options.toLowerCase().contains( "visuals" ) ) { List visuals = new ArrayList<>(); @@ -603,20 +628,34 @@ public void utilsMineBombsList( CommandSender sender, return; } + + DecimalFormat dFmt = new DecimalFormat( "#,##0.000" ); + + Set keys = mBombs.getConfigData().getBombs().keySet(); for ( String key : keys ) { MineBombData bomb = mBombs.getConfigData().getBombs().get( key ); String message = String.format( - "&7%-12s &3Autosell: &7%b &3FuseDelayTicks: &7%d &3CooldownTicks: &7%d", + "&7%-12s &3AnimationPattern & Speed: &7%s %s &3Throw Speed: &7(%s - %s)", bomb.getName(), - bomb.isAutosell(), + bomb.getAnimationPattern().name(), + dFmt.format( bomb.getAnimationSpeed() ), + dFmt.format( bomb.getThrowVelocityLow() ), + dFmt.format( bomb.getThrowVelocityHigh() ) + ); + + messages.add( message ); + + + String msg2 = String.format( + " &3FuseDelayTicks: &7%d &3CooldownTicks: &7%d", bomb.getFuseDelayTicks(), bomb.getCooldownTicks() ); - messages.add( message ); + messages.add( msg2 ); @@ -667,20 +706,24 @@ public void utilsMineBombsList( CommandSender sender, } - String message2 = String.format( - " &3ToolInHand: &7%s &3Fortune: &7%d &3Percent Chance: &7%f", - bomb.getToolInHandName(), - bomb.getToolInHandFortuneLevel(), - bomb.getRemovalChance() ); - messages.add( message2 ); - - - String message3 = String.format( - " &3ItemType: &7%s &3Glowng: &7%b &3Gravity: &7%b", - bomb.getItemType(), - bomb.isGlowing(), - bomb.isGravity() ); - messages.add( message3 ); + if ( optAll ) { + + String message2 = String.format( + " &3ToolInHand: &7%s &3Fortune: &7%d &3Percent Chance: &7%f", + bomb.getToolInHandName(), + bomb.getToolInHandFortuneLevel(), + bomb.getRemovalChance() ); + messages.add( message2 ); + + + String message3 = String.format( + " &3ItemType: &7%s &3Autosell: &7%b &3Glowng: &7%b &3Gravity: &7%b", + bomb.getItemType(), + bomb.isAutosell(), + bomb.isGlowing(), + bomb.isGravity() ); + messages.add( message3 ); + } messages.add( " " + bomb.getDescription() ); @@ -1059,12 +1102,15 @@ public MineBombData getBombItem( Player player ) { * bomb cannot be activated. *

* - * @param player + * @param sPlayer * @param bomb + * @param sBlock + * @param hand * @return */ public boolean setBombInHand( SpigotPlayer sPlayer, - MineBombData bomb, SpigotBlock sBlock, + MineBombData bomb, + SpigotBlock sBlock, tech.mcprison.prison.spigot.compat.Compatibility.EquipmentSlot hand ) { boolean isABomb = false; From 1a20ea46169bfb43f0a40f491ea87b100a6c60e0 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 23 Jul 2024 02:50:30 -0400 Subject: [PATCH 106/323] Mine bombs: Hooked up the animationSpeed mine bomb setting to the bounce, infinity, and orbital animations. Since bounce and infinity are radians based, the speed is divided by 16 to help slow it down, otherwise it would be way too fast. Normally, for these two animations, it was using an internal speed of 0.35, so now a comparable speed can be achieved with a value of 5.6. The other animations appear to be more ideal with an animation speed around 5.0, so this is a good common ratio to use. --- docs/changelog_v3.3.x.md | 5 +++++ .../bombs/animations/BombAnimationBounce.java | 2 +- .../animations/BombAnimationInfinity.java | 2 +- .../animations/BombAnimationOrbital.java | 19 ++++++++++++------- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 147801dec..bd80cdae8 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-beta.18c 2024-07-23 +* **Mine bombs: Hooked up the animationSpeed mine bomb setting to the bounce, infinity, and orbital animations.** +Since bounce and infinity are radians based, the speed is divided by 16 to help slow it down, otherwise it would be way too fast. +Normally, for these two animations, it was using an internal speed of 0.35, so now a comparable speed can be achieved with a value of 5.6. The other animations appear to be more ideal with an animation speed around 5.0, so this is a good common ratio to use. + + * **Mine bombs: Update the '/prison utils bomb list' command to include more of the mine bomb's features and options. ** Added support to show the available Mine Bomb's animation patterns. diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationBounce.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationBounce.java index 32fc04506..52c571326 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationBounce.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationBounce.java @@ -22,7 +22,7 @@ public BombAnimationBounce(MineBombData bomb, PrisonBlock sBombBlock, @Override public void stepAnimation() { - double speed = 0.35; + double speed = getBomb().getAnimationSpeed() / 16d; counter += speed; diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationInfinity.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationInfinity.java index ea40ebd4f..cae7bc9b0 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationInfinity.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationInfinity.java @@ -21,7 +21,7 @@ public BombAnimationInfinity( MineBombData bomb, public void stepAnimation() { - double speed = 0.35; + double speed = getBomb().getAnimationSpeed() / 16d; setEulerAngleX( getEulerAngleX() + speed ); setEulerAngleY( getEulerAngleY() + speed / 3); diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationOrbital.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationOrbital.java index 6f00b01f6..ba871f358 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationOrbital.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationOrbital.java @@ -25,10 +25,15 @@ public BombAnimationOrbital(MineBombData bomb, PrisonBlock sBombBlock, this.angle = entityYaw; - getOriginalLocation().setX( - getOriginalLocation().getX() + bomb.getAnimationOffset()); - getOriginalLocation().setZ( - getOriginalLocation().getZ() + bomb.getAnimationOffset()); + + Vector vec = new Vector( + bomb.getAnimationOffset(), 0d, bomb.getAnimationOffset()); + getOriginalLocation().add( vec ); + +// getOriginalLocation().setX( +// getOriginalLocation().getX() + bomb.getAnimationOffset()); +// getOriginalLocation().setZ( +// getOriginalLocation().getZ() + bomb.getAnimationOffset()); } @@ -38,15 +43,15 @@ public void stepAnimation() { if ( isAlternateDirections() ) { if ( getId() % 2 == 0 ) { - angle += 5; + angle += getBomb().getAnimationSpeed(); } else { - angle -= 5; + angle -= getBomb().getAnimationSpeed(); } } else { - angle += 5; + angle += getBomb().getAnimationSpeed(); } if ( angle > 360 ) { From e61494b54710387d1e131b5b4c0934516a46d829 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 23 Jul 2024 03:06:21 -0400 Subject: [PATCH 107/323] Mine Bomb: Setup a simplified constructor for animations which will not use an item. The purpose would be for showing only the holographic name, which is needed for animations that are actually moving the armor stand. --- docs/changelog_v3.3.x.md | 4 ++++ .../bombs/animations/BombAnimationNone.java | 24 +++++++++++++++---- .../bombs/animations/BombAnimations.java | 11 +++++++++ .../bombs/animations/BombAnimationsTask.java | 17 ++++++++----- 4 files changed, 46 insertions(+), 10 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index bd80cdae8..7c7f30d4e 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-beta.18c 2024-07-23 +* **Mine Bomb: Setup a simplified constructor for animations which will not use an item.** +The purpose would be for showing only the holographic name, which is needed for animations that are actually moving the armor stand. + + * **Mine bombs: Hooked up the animationSpeed mine bomb setting to the bounce, infinity, and orbital animations.** Since bounce and infinity are radians based, the speed is divided by 16 to help slow it down, otherwise it would be way too fast. Normally, for these two animations, it was using an internal speed of 0.35, so now a comparable speed can be achieved with a value of 5.6. The other animations appear to be more ideal with an animation speed around 5.0, so this is a good common ratio to use. diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationNone.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationNone.java index f8adbe0a2..130aa07e2 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationNone.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationNone.java @@ -7,14 +7,30 @@ public class BombAnimationNone extends BombAnimations { + /** + * This constructor will generate an armor stand without holding an item. + * This is ideal for a holographic display that is not moving. + * + * @param bomb + * @param sBombBlock + * @param task + */ public BombAnimationNone( MineBombData bomb, - PrisonBlock sBombBlock, ItemStack item, - BombAnimationsTask task, - float entityYaw, float entityPitch ) { - super( bomb, sBombBlock, item, task, entityYaw, entityPitch ); + PrisonBlock sBombBlock, + BombAnimationsTask task ) { + super( bomb, sBombBlock, task ); } + + public BombAnimationNone( MineBombData bomb, + PrisonBlock sBombBlock, ItemStack item, + BombAnimationsTask task, + float entityYaw, float entityPitch ) { + super( bomb, sBombBlock, item, task, entityYaw, entityPitch ); + + } + @Override public void stepAnimation() diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java index 25e2eadf8..4f2ddd9f8 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java @@ -46,6 +46,17 @@ public abstract class BombAnimations { private DecimalFormat dFmt; + /* + * For none animations that will now hold an item. + * This is good for a non-animated animation that is used only as an + * holographic display of the name. + */ + public BombAnimations( MineBombData bomb, + PrisonBlock sBombBlock, + BombAnimationsTask task ) { + this( bomb, sBombBlock, null, task, 0f, 0f ); + } + public BombAnimations( MineBombData bomb, PrisonBlock sBombBlock, ItemStack item, diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationsTask.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationsTask.java index a1f815531..cefe623dc 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationsTask.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationsTask.java @@ -60,6 +60,10 @@ public void animatorFactory( case bounce: { + // Add BombAnimationNone for a stationary name: + BombAnimationNone baHolo = new BombAnimationNone( bomb, pBlock, this ); + getAnimators().add( baHolo ); + float yaw = 0; float pitch = 0; @@ -76,8 +80,7 @@ public void animatorFactory( case orbital: { // Add BombAnimationNone for a stationary name: - BombAnimationNone baHolo = new BombAnimationNone( bomb, - pBlock, null, this, 0f, 0f ); + BombAnimationNone baHolo = new BombAnimationNone( bomb, pBlock, this ); getAnimators().add( baHolo ); float yaw = 0; @@ -96,8 +99,7 @@ public void animatorFactory( case orbitalEight: { // Add BombAnimationNone for a stationary name: - BombAnimationNone baHolo = new BombAnimationNone( bomb, - pBlock, null, this, 0f, 0f ); + BombAnimationNone baHolo = new BombAnimationNone( bomb, pBlock, this ); getAnimators().add( baHolo ); float yaw = 0; @@ -121,8 +123,7 @@ public void animatorFactory( case starburst: { // Add BombAnimationNone for a stationary name: - BombAnimationNone baHolo = new BombAnimationNone( bomb, - pBlock, null, this, 0f, 0f ); + BombAnimationNone baHolo = new BombAnimationNone( bomb, pBlock, this ); getAnimators().add( baHolo ); float yaw = 0; @@ -162,6 +163,10 @@ public void animatorFactory( case infinityEight: { + // Add BombAnimationNone for a stationary name: + BombAnimationNone baHolo = new BombAnimationNone( bomb, pBlock, this ); + getAnimators().add( baHolo ); + float yaw = 0; float pitch = 0; float yawStep = 360f / 8f; From 28811a83d0ca3a20aeda84f2ca1150ea0642953a Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 23 Jul 2024 03:37:53 -0400 Subject: [PATCH 108/323] XSeries: Upgrade XSeries to v11.2.0.1 from v11.2.0. --- docs/changelog_v3.3.x.md | 3 +++ gradle/libs.versions.toml | 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 7c7f30d4e..17a7cf7f7 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-beta.18c 2024-07-23 +* **XSeries: Upgrade XSeries to v11.2.0.1 from v11.2.0.** + + * **Mine Bomb: Setup a simplified constructor for animations which will not use an item.** The purpose would be for showing only the holographic name, which is needed for animations that are actually moving the armor stand. diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 92c5b07e0..8bd638cde 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -34,7 +34,7 @@ commons-lang3 = "3.12.0" groovy = "3.0.9" gson = "2.10.1" spiget = "1.4.6-SNAPSHOT" -xseries = "11.2.0" +xseries = "11.2.0.1" junit = "4.12" guava = "31.1-jre" spigotApi = "1.13.2-R0.1-SNAPSHOT" From e3b6d28750bf23feefaaa845315980188ec9332d Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 23 Jul 2024 03:39:02 -0400 Subject: [PATCH 109/323] Mine bombs: Various updates to the general mine bomb defaults to include more of the newer features. --- docs/changelog_v3.3.x.md | 3 + .../bombs/MineBombDefaultConfigSettings.java | 81 ++++++++++++++----- 2 files changed, 64 insertions(+), 20 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 17a7cf7f7..c77501785 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-beta.18c 2024-07-23 +* **Mine bombs: Various updates to the general mine bomb defaults to include more of the newer features.** + + * **XSeries: Upgrade XSeries to v11.2.0.1 from v11.2.0.** 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 49ca3b1a9..b016bf8ef 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 @@ -291,7 +291,7 @@ public void setupDefaultMineBombData(MineBombs mineBombs) mbd.setGlowing( true ); mbd.setCooldownTicks( 20 ); - mbd.setFuseDelayTicks( 10 * 20 ); // 10 seconds + mbd.setFuseDelayTicks( 15 * 20 ); // 15 seconds mbd.setAnimationPattern( AnimationPattern.orbital ); @@ -302,7 +302,7 @@ public void setupDefaultMineBombData(MineBombs mineBombs) { MineBombData mbd = new MineBombData( - "DudNoneBomb", "COAL", ExplosionShape.sphere.name(), 1, + "NoneBomb", "COAL", ExplosionShape.sphere.name(), 2, "This is a bomb?&r" ); mbd.setDescription("This old bomb is a dud.&r"); @@ -320,10 +320,11 @@ public void setupDefaultMineBombData(MineBombs mineBombs) mbd.addVisualEffects( mbeExplode04.clone() ); mbd.addVisualEffects( mbeExplode02.clone().setOffsetTicks( 30 ) ); - mbd.setCooldownTicks( 10 ); + mbd.setCooldownTicks( 20 ); + mbd.setFuseDelayTicks( 15 * 20 ); // 15 seconds - mbd.setThrowVelocityLow( 0.05 ); - mbd.setThrowVelocityHigh( 0.5 ); + mbd.setThrowVelocityLow( 0.25 ); + mbd.setThrowVelocityHigh( 3.5 ); mbd.setAnimationPattern( AnimationPattern.none ); @@ -335,7 +336,7 @@ public void setupDefaultMineBombData(MineBombs mineBombs) { MineBombData mbd = new MineBombData( - "DudBounceBomb", "IRON_INGOT", ExplosionShape.sphere.name(), 1, + "BounceBomb", "IRON_INGOT", ExplosionShape.sphere.name(), 2, "This is a bomb?&r" ); mbd.setDescription("This old bomb is a dud.&r"); @@ -344,7 +345,7 @@ public void setupDefaultMineBombData(MineBombs mineBombs) mbd.setToolInHandName( "STONE_PICKAXE" ); mbd.setToolInHandFortuneLevel( 1 ); - mbd.setRemovalChance( 25.0d ); + mbd.setRemovalChance( 50.0d ); mbd.addSoundEffects( mbeSound01.clone() ); mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 30 ) ); @@ -353,10 +354,11 @@ public void setupDefaultMineBombData(MineBombs mineBombs) mbd.addVisualEffects( mbeExplode04.clone() ); mbd.addVisualEffects( mbeExplode02.clone().setOffsetTicks( 30 ) ); - mbd.setCooldownTicks( 10 ); + mbd.setCooldownTicks( 20 ); + mbd.setFuseDelayTicks( 15 * 20 ); // 15 seconds - mbd.setThrowVelocityLow( 0.05 ); - mbd.setThrowVelocityHigh( 0.5 ); + mbd.setThrowVelocityLow( 0.25 ); + mbd.setThrowVelocityHigh( 1.5 ); mbd.setAnimationPattern( AnimationPattern.bounce ); @@ -368,7 +370,7 @@ public void setupDefaultMineBombData(MineBombs mineBombs) { MineBombData mbd = new MineBombData( - "DudOrbitalBomb", "GOLD_INGOT", ExplosionShape.sphere.name(), 1, + "OrbitalBomb", "GOLD_INGOT", ExplosionShape.sphere.name(), 2, "This is a bomb?&r" ); mbd.setDescription("This old bomb is a dud.&r"); @@ -377,7 +379,7 @@ public void setupDefaultMineBombData(MineBombs mineBombs) mbd.setToolInHandName( "STONE_PICKAXE" ); mbd.setToolInHandFortuneLevel( 1 ); - mbd.setRemovalChance( 25.0d ); + mbd.setRemovalChance( 50.0d ); mbd.addSoundEffects( mbeSound01.clone() ); mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 30 ) ); @@ -386,10 +388,11 @@ public void setupDefaultMineBombData(MineBombs mineBombs) mbd.addVisualEffects( mbeExplode04.clone() ); mbd.addVisualEffects( mbeExplode02.clone().setOffsetTicks( 30 ) ); - mbd.setCooldownTicks( 10 ); + mbd.setCooldownTicks( 20 ); + mbd.setFuseDelayTicks( 15 * 20 ); // 15 seconds - mbd.setThrowVelocityLow( 0.05 ); - mbd.setThrowVelocityHigh( 0.5 ); + mbd.setThrowVelocityLow( 0.25 ); + mbd.setThrowVelocityHigh( 1.5 ); mbd.setAnimationPattern( AnimationPattern.orbital ); @@ -401,7 +404,7 @@ public void setupDefaultMineBombData(MineBombs mineBombs) { MineBombData mbd = new MineBombData( - "DudOrbital8Bomb", "DIAMOND", ExplosionShape.sphere.name(), 1, + "Orbital8Bomb", "DIAMOND", ExplosionShape.sphere.name(), 2, "This is a bomb?&r" ); mbd.setDescription("This old bomb is a dud.&r"); @@ -413,7 +416,7 @@ public void setupDefaultMineBombData(MineBombs mineBombs) mbd.setToolInHandName( "STONE_PICKAXE" ); mbd.setToolInHandFortuneLevel( 1 ); - mbd.setRemovalChance( 25.0d ); + mbd.setRemovalChance( 50.0d ); mbd.addSoundEffects( mbeSound01.clone() ); mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 30 ) ); @@ -422,10 +425,11 @@ public void setupDefaultMineBombData(MineBombs mineBombs) mbd.addVisualEffects( mbeExplode04.clone() ); mbd.addVisualEffects( mbeExplode02.clone().setOffsetTicks( 30 ) ); - mbd.setCooldownTicks( 10 ); + mbd.setCooldownTicks( 20 ); + mbd.setFuseDelayTicks( 15 * 20 ); // 15 seconds - mbd.setThrowVelocityLow( 0.05 ); - mbd.setThrowVelocityHigh( 0.5 ); + mbd.setThrowVelocityLow( 0.25 ); + mbd.setThrowVelocityHigh( 1.5 ); mbd.setAnimationPattern( AnimationPattern.orbitalEight ); @@ -435,6 +439,43 @@ public void setupDefaultMineBombData(MineBombs mineBombs) + { + MineBombData mbd = new MineBombData( + "starburstBomb", "WHEAT", ExplosionShape.sphere.name(), 2, + "This is a bomb?&r" ); + mbd.setDescription("This old bomb is a dud.&r"); + + mbd.setNameTag( "&a-=- &4{countdown} &5-=- &7{name} &5-=- &4{countdown} &a-=-&r" ); + mbd.setItemName( MineBombData.MINE_BOMB_DEFAULT_ITEM_NAME ); + + mbd.getLore().add( "&7Hex Colors: &#e81416Red&#ffa500Orange&#faeb36Yellow" + + "Oc314Greenǧde7Blueb369dIndigo𑋡dViolet" ); + + mbd.setToolInHandName( "STONE_PICKAXE" ); + mbd.setToolInHandFortuneLevel( 1 ); + mbd.setRemovalChance( 50.0d ); + + mbd.addSoundEffects( mbeSound01.clone() ); + mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 30 ) ); + mbd.addSoundEffects( mbeSound03.clone() ); + + mbd.addVisualEffects( mbeExplode04.clone() ); + mbd.addVisualEffects( mbeExplode02.clone().setOffsetTicks( 30 ) ); + + mbd.setCooldownTicks( 20 ); + mbd.setFuseDelayTicks( 15 * 20 ); // 15 seconds + + mbd.setThrowVelocityLow( 0.25 ); + mbd.setThrowVelocityHigh( 1.5 ); + + + mbd.setAnimationPattern( AnimationPattern.starburst ); + + mineBombs.getConfigData().getBombs().put( mbd.getName().toLowerCase(), mbd ); + } + + + mineBombs.saveConfigJson(); From 75f86783f565744e7eb00659f8df73fbccafa74d Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 23 Jul 2024 03:42:55 -0400 Subject: [PATCH 110/323] Mind bombs: Minor updates to the BombAnimations class to realign a few of the settings. --- docs/changelog_v3.3.x.md | 3 + .../bombs/animations/BombAnimations.java | 124 ++++++++++++------ 2 files changed, 84 insertions(+), 43 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index c77501785..61246e42a 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-beta.18c 2024-07-23 +* **Mind bombs: Minor updates to the BombAnimations class to realign a few of the settings. ** + + * **Mine bombs: Various updates to the general mine bomb defaults to include more of the newer features.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java index 4f2ddd9f8..96d685242 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java @@ -9,6 +9,7 @@ import tech.mcprison.prison.internal.EulerAngle; import tech.mcprison.prison.internal.ItemStack; import tech.mcprison.prison.internal.block.PrisonBlock; +import tech.mcprison.prison.output.Output; import tech.mcprison.prison.util.BluesSemanticVersionComparator; import tech.mcprison.prison.util.Location; import tech.mcprison.prison.util.Text; @@ -73,8 +74,30 @@ public BombAnimations( MineBombData bomb, this.bomb = bomb; this.sBlock = sBombBlock; this.item = item; + + + Location location = + getBomb().getPlacedBombLocation() != null ? + getBomb().getPlacedBombLocation() : + getsBlock().getLocation(); + location.setY( location.getY() + 2.5 ); + + // NOTE: The direction the entity is facing is based upon yaw. + // When using org.bukkit.Location.setDirection() it's using a vector + // to set yaw and pitch so it's looking at that vector point. + // So... I guess that means an entity cannot turn their head? + // For entities, or at least armorStands, there is an Euler angle + // based getHeadPose() and setHeadPose() functions. + location.setYaw( entityYaw ); + + + // Not sure why 90 was being added. I suspect 0 is straight up? + location.setPitch( entityPitch + 90 ); + + this.originalLocation = location; + + - this.originalLocation = null; // this.ageTicks = 0; this.terminateOnZeroTicks = getTaskLifeSpan(); @@ -100,39 +123,39 @@ protected void cancel() { public void initialize() { - Location location = - getBomb().getPlacedBombLocation() != null ? - getBomb().getPlacedBombLocation() : - getsBlock().getLocation(); - - location.setY( location.getY() + 2.5 ); - - setOriginalLocation( location ); - - - // NOTE: The direction the entity is facing is based upon yaw. - // When using org.bukkit.Location.setDirection() it's using a vector - // to set yaw and pitch so it's looking at that vector point. - // So... I guess that means an entity cannot turn their head? - // For entities, or at least armorStands, there is an Euler angle - // based getHeadPose() and setHeadPose() functions. - location.setYaw( entityYaw ); - - - // Not sure why 90 was being added. I suspect 0 is straight up? - location.setPitch( entityPitch + 90 ); - - +// Location location = +// getBomb().getPlacedBombLocation() != null ? +// getBomb().getPlacedBombLocation() : +// getsBlock().getLocation(); +// +// location.setY( location.getY() + 2.5 ); +// +// setOriginalLocation( location ); +// + +// // NOTE: The direction the entity is facing is based upon yaw. +// // When using org.bukkit.Location.setDirection() it's using a vector +// // to set yaw and pitch so it's looking at that vector point. +// // So... I guess that means an entity cannot turn their head? +// // For entities, or at least armorStands, there is an Euler angle +// // based getHeadPose() and setHeadPose() functions. +// getOriginalLocation().setYaw( entityYaw ); +// +// +// // Not sure why 90 was being added. I suspect 0 is straight up? +// getOriginalLocation().setPitch( entityPitch + 90 ); +// +// // double startingAngle = ( 360d / entityYaw ) * twoPI; // location.setDirection( startingAngle ); // eulerAngleX += startingAngle; - EulerAngle arm = new EulerAngle( - eulerAngleX, - eulerAngleY, - eulerAngleZ ); +// EulerAngle arm = new EulerAngle( +// eulerAngleX, +// eulerAngleY, +// eulerAngleZ ); // EulerAngle arm = new EulerAngle( // eulerAngleX + startingAngle, @@ -141,10 +164,11 @@ public void initialize() { // Spawn an invisible armor stand: - armorStand = location.spawnArmorStand( - getBomb().getItemType(), -// (getItem() == null ? null : getBomb().getItemType()), - getBomb().getName() ); + // If item is null, then armorstand will not spawn with an item + // and no arms. + armorStand = getOriginalLocation().spawnArmorStand( + (getItem() == null ? null : getBomb().getItemType()), + (getId() == 0 ? getBomb().getName() : null) ); // MineBombs.MINE_BOMBS_NBT_KEY, getBomb().getName() ); @@ -177,7 +201,17 @@ public void initialize() { armorStand.setSmall( getBomb().isSmall() ); - armorStand.setRightArmPose(arm); + + if ( getItem() != null ) { + + EulerAngle arm = new EulerAngle( + eulerAngleX, + eulerAngleY, + eulerAngleZ ); + + armorStand.setArms( true ); + armorStand.setRightArmPose(arm); + } // ItemStack itemInHand = armorStand.getItemInHand(); // @@ -204,16 +238,20 @@ public void initialize() { } } -// if ( Output.get().isDebug() ) { -// String msg = String.format( -// "### BombAnimation.initializeArmorStand : id: %s %s %s", -// Integer.toString(getId()), -// bomb.getAnimationPattern().name(), -// armorStand.getLocation().toString() -// ); -// -// Output.get().logInfo( msg ); -// } + if ( Output.get().isDebug() ) { + String msg = String.format( + "### BombAnimation.initializeArmorStand : id: %s %s %s %s%s", + Integer.toString(getId()), + bomb.getAnimationPattern().name(), + armorStand.getLocation().toString(), + (getArmorStand().isCustomNameVisible() ? " CustomName" : ""), + (getArmorStand().hasArms() ? " hasArms" : "" ), + (getArmorStand().getItemInHand() != null ? + " " + getArmorStand().getItemInHand().getName() : "" ) + ); + + Output.get().logInfo( msg ); + } } From ad2a8ca6322a028556071d9da3afbf92d1d1a751 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 29 Jul 2024 01:06:24 -0400 Subject: [PATCH 111/323] Add support for new economy: The New Economy: Created dummy stubs to allow prison to build the new classes for the integration. Cannot use maven because those jars are built with Java 17 when prison can only be built with java 1.8. --- docs/changelog_v3.3.x.md | 6 +- .../TheNewEconomy_prisonBuild_v0.1.3.jardesc | 17 ++++++ .../src/main/java/net/tnemc/core/TNECore.java | 21 +++++++ .../main/java/net/tnemc/core/api/TNEAPI.java | 53 ++++++++++++++++++ .../TheNewEconomy_prisonBuild_v0.1.3.0.jar | Bin 0 -> 2191 bytes 5 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 prison-misc/TheNewEconomy_prisonBuild_v0.1.3.jardesc create mode 100644 prison-misc/src/main/java/net/tnemc/core/TNECore.java create mode 100644 prison-misc/src/main/java/net/tnemc/core/api/TNEAPI.java create mode 100644 prison-spigot/lib/TheNewEconomy_prisonBuild_v0.1.3.0.jar diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 61246e42a..7c1c246d6 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-beta.18c 2024-07-23 +# 3.3.0-beta.18c 2024-07-29 + + +* **Add support for new economy: The New Economy: Created dummy stubs to allow prison to build the new classes for the integration.** +Cannot use maven because those jars are built with Java 17 when prison can only be built with java 1.8. * **Mind bombs: Minor updates to the BombAnimations class to realign a few of the settings. ** diff --git a/prison-misc/TheNewEconomy_prisonBuild_v0.1.3.jardesc b/prison-misc/TheNewEconomy_prisonBuild_v0.1.3.jardesc new file mode 100644 index 000000000..345bf73eb --- /dev/null +++ b/prison-misc/TheNewEconomy_prisonBuild_v0.1.3.jardesc @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/prison-misc/src/main/java/net/tnemc/core/TNECore.java b/prison-misc/src/main/java/net/tnemc/core/TNECore.java new file mode 100644 index 000000000..c0ffc8b16 --- /dev/null +++ b/prison-misc/src/main/java/net/tnemc/core/TNECore.java @@ -0,0 +1,21 @@ +package net.tnemc.core; + +public class TNECore { + + + public static TNECore eco() { + return new TNECore(); + } + + public TNECore currency() { + return this; + } + + public TNECore findCurrency( String currency ) { + return this; + } + + public boolean isPresent() { + return true; + } +} diff --git a/prison-misc/src/main/java/net/tnemc/core/api/TNEAPI.java b/prison-misc/src/main/java/net/tnemc/core/api/TNEAPI.java new file mode 100644 index 000000000..9ecf4d7b4 --- /dev/null +++ b/prison-misc/src/main/java/net/tnemc/core/api/TNEAPI.java @@ -0,0 +1,53 @@ +package net.tnemc.core.api; + +import java.math.BigDecimal; + +public class TNEAPI { + + public boolean hasPlayerAccount( String playerUUID ) { + return true; + } + + public boolean hasHoldings( String playerUUID, String worldName, + String currency, BigDecimal amount ) { + return true; + } + + + public boolean setHoldings( String playerUUID, String worldName, + String currency, BigDecimal amount ) { + return true; + } + + + public BigDecimal getHoldings( String playerUUID, String worldName, + String currency ) { + return BigDecimal.ZERO; + } + + + public TNEAPI getDefaultCurrency() { + return this; + } + + public String getIdentifier() { + return ""; + } + + + public TNEAPI addHoldings( String playerUUID, String worldName, + String currency, BigDecimal amount, String source ) { + return this; + } + + + public TNEAPI removeHoldings( String playerUUID, String worldName, + String currency, BigDecimal amount, String source ) { + return this; + } + + public boolean isSuccessful() { + return true; + } + +} diff --git a/prison-spigot/lib/TheNewEconomy_prisonBuild_v0.1.3.0.jar b/prison-spigot/lib/TheNewEconomy_prisonBuild_v0.1.3.0.jar new file mode 100644 index 0000000000000000000000000000000000000000..23aa831e374ab63081766057972e0eafb02d7da2 GIT binary patch literal 2191 zcmaJ?2{crD9KJKQu|?VUY!TVsNOr@7XBmyHnexay+2%1~EFnw{L*zw?=usq*Y>kHs zPZ&#REMqCV3R9LMZMHYlJLj3|)OXK4_ug~Q`ToD(|M&gB4{687E(|~*5I`TYi3V68 z46p+TOBZtu8wV>bgt>!_m8G+bCcr?se@mZpNopA3a881Y)?DrkPvrS&xRgWw--Y?mA z^D2}!*7GVbhq_6auA3O)tZGX0?f8_U{h~k4r&2CnI&8?lbZKj8GQ~o^eX(qSmbcxj zw0E{v{yJWQA~p#{H+b&;ym7o3x)2|Gr&vEfHMBS@KdF&;*CrdDSAxZ#ACuycJaF%6 zUGYuWkO!z^IgRQiMv4DTr8?@qK;=Va+lu{-600Jl{Cc0i_t=zWw~1}d`=6JUxoF#L ztXL6vQq;>QY!Go(P0h>fsL>4%+ws#jJ;eboW*5lM1egPwOqhY8Kmd>f{@H+-BmBXD zu$XX6YU(4NW^FzgRc1jhWK44%bg`ur@|n&30$G0`y(lSZ8^=}FQ4cvQ?J?06@D^(g z-nW=RC&@(RBisiEr4u{lr%u8N&vBzF05ySjrBl0ju$o8t9pd4bxMHEBe%Nw?Uf|=L z;aU&l3kt0t(VbDj@F}urH z7pGid)UM9xa7TU{oL|dN?)&aAr~H``G)LO}r@%62x1c?af_ZFRGS6(?)P|0h9TIiZ z(`n1f*@wm|$@fAQ;d1u7x5ID*+@{pfJAAX{dS>6XVN<1;7jb8ZeyN-sAXuW^}3`YG9X)R(4mB4Vpf;&mrgBr zK+Tq_ryRYVW;!%4LVk4z`+&2*0(D#n;od&e=6AwWF|9!`QbnbQ)UKZe-$lU zJP{q_p1wtjzGyIqDv8W^14yM1KXer&Y;$iE^*X<4EthxPFwRdK;oXy-Qj0On7~J&tiO^~NxKvZ-w^mpI;H-*`Pc$hPp%0r3Ng zx@f(OOF|A+F10O>PTjDlD>bPv=^PXfr{}8q*gw8u`o62KFPWelB|uI26q^0Wdi>X% zCv65jewf7AlDAF2D2Mcsbnc#0b%RCTEgyc$hr{|^f+VVno;zHwdx`pLZN)@C7sc0@ zh+T1yiYQp+kj#T2a&^6v6$0qmXTxP-&Qj~6l>57>(+{j-fs~ZfbV%(6y=#MBH4MLe z=9bxW4J(-?sq$doq}&yLb6(sF^;4N-erze)u&!@D-cX2QynP*TKrR;uMy&c-)5jAk zgQFX3$azH9SdsH1>w&cK)3M{|wYV=fG39h+O_5;{vh2+527!fvogidQFlG>bjUUA# zD+@F2SZ$V>c00f@UVmV%U$XC8CRR&h+VT#-48i<>iKzuvBBlefYK-ZCJDB>O=vzPh kmW*`=nX=r$RgUkfVj=slFb;;y0f2*Xg)pYT#l`&k7X&3@YXATM literal 0 HcmV?d00001 From b532b9fa5989b90b2c16598423f68dd15de24ad5 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 29 Jul 2024 01:09:45 -0400 Subject: [PATCH 112/323] Bug fix: When using a file filter, handle the condition of the result being null. --- docs/changelog_v3.3.x.md | 3 +++ .../src/main/java/tech/mcprison/prison/file/FileIO.java | 9 ++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 7c1c246d6..455f09ff9 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-beta.18c 2024-07-29 +* **Bug fix: When using a file filter, handle the condition of the result being null.** + + * **Add support for new economy: The New Economy: Created dummy stubs to allow prison to build the new classes for the integration.** Cannot use maven because those jars are built with Java 17 when prison can only be built with java 1.8. diff --git a/prison-core/src/main/java/tech/mcprison/prison/file/FileIO.java b/prison-core/src/main/java/tech/mcprison/prison/file/FileIO.java index e5d9f15e9..8dce4ad90 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/file/FileIO.java +++ b/prison-core/src/main/java/tech/mcprison/prison/file/FileIO.java @@ -511,9 +511,12 @@ public List getFilesFromPrefix( String filePrefix, File path ) { File[] collectionFiles = path.listFiles( fFilter ); - for (File file : collectionFiles ) { - results.add(file); - } + if ( collectionFiles != null ) { + + for (File file : collectionFiles ) { + results.add(file); + } + } return results; } From dd8a9b03f0774a657a78bc91379838ed682603d8 Mon Sep 17 00:00:00 2001 From: Daniel V Date: Mon, 29 Jul 2024 18:49:12 -0400 Subject: [PATCH 113/323] TNE Files. --- .../src/main/resources/plugin.yml | 1 + .../mcprison/prison/spigot/SpigotPrison.java | 2 + .../spigot/economies/TheNewEconomy.java | 150 ++++++++++++++++++ .../economies/TheNewEconomyWrapper.java | 68 ++++++++ prison-spigot/src/main/resources/config.yml | 2 +- prison-spigot/src/main/resources/plugin.yml | 1 + 6 files changed, 223 insertions(+), 1 deletion(-) create mode 100644 prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/TheNewEconomy.java create mode 100644 prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/TheNewEconomyWrapper.java diff --git a/prison-spigot-alt/src/main/resources/plugin.yml b/prison-spigot-alt/src/main/resources/plugin.yml index a24af7f6b..b82588dc0 100644 --- a/prison-spigot-alt/src/main/resources/plugin.yml +++ b/prison-spigot-alt/src/main/resources/plugin.yml @@ -37,6 +37,7 @@ softdepend: - PermissionsEx - GroupManagerX - GemsEconomy + - TheNewEconomy - TokenEnchant - CMI - CMILib 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 d9710006d..ddca20832 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 @@ -84,6 +84,7 @@ import tech.mcprison.prison.spigot.economies.EssentialsEconomy; import tech.mcprison.prison.spigot.economies.GemsEconomy; import tech.mcprison.prison.spigot.economies.SaneEconomy; +import tech.mcprison.prison.spigot.economies.TheNewEconomy; import tech.mcprison.prison.spigot.economies.VaultEconomy; import tech.mcprison.prison.spigot.gui.ListenersPrisonManager; import tech.mcprison.prison.spigot.permissions.LuckPermissions; @@ -959,6 +960,7 @@ private void initIntegrations() { registerIntegration(new EssentialsEconomy()); registerIntegration(new SaneEconomy()); registerIntegration(new GemsEconomy()); + registerIntegration(new TheNewEconomy()); registerIntegration(new CoinsEngineEconomy()); registerIntegration(new EdPrisonEconomy()); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/TheNewEconomy.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/TheNewEconomy.java new file mode 100644 index 000000000..25481d365 --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/TheNewEconomy.java @@ -0,0 +1,150 @@ +package tech.mcprison.prison.spigot.economies; + +import tech.mcprison.prison.PrisonAPI; +import tech.mcprison.prison.integration.EconomyCurrencyIntegration; +import tech.mcprison.prison.integration.IntegrationType; +import tech.mcprison.prison.internal.Player; +import tech.mcprison.prison.output.Output; + +import java.math.BigDecimal; + +public class TheNewEconomy extends EconomyCurrencyIntegration { + + private TheNewEconomyWrapper wrapper = null; + private boolean availableAsAnAlternative = false; + + public TheNewEconomy() { + super("TheNewEconomy", "TheNewEconomy"); + } + + @Override + public String getPluginSourceURL() { + return "https://www.spigotmc.org/resources/the-new-economy.7805/"; + } + + @Override + public void integrate() { + if(isRegistered()) { + + // if an econ is already registered, then don't register this one: + final boolean econAlreadySet = PrisonAPI.getIntegrationManager().getForType(IntegrationType.ECONOMY).isPresent(); + + if(!econAlreadySet) { + this.wrapper = new TheNewEconomyWrapper(); + } else { + Output.get().logInfo("TheNewEconomy is not directly enabled - Available as backup. "); + this.availableAsAnAlternative = true; + } + + } + } + + @Override + public boolean hasIntegrated() { + return wrapper != null; + } + + @Override + public void disableIntegration() { + wrapper = null; + } + + @Override + public String getDisplayName() { + return super.getDisplayName() + + (availableAsAnAlternative ? " (disabled)" : ""); + } + + @Override + public boolean supportedCurrency(final String currency) { + return wrapper != null && wrapper.supportedCurrency(currency); + } + + @Override + public boolean hasAccount(final Player player) { + return wrapper.hasAccount(player); + } + + /** + * Returns the player's current balance. + * + * @param player The {@link Player}. + * + * @return a double. + */ + @Override + public double getBalance(final Player player) { + return getBalance(player, wrapper.defaultCurrency()); + } + + @Override + public double getBalance(final Player player, final String currency) { + return wrapper.getBalance(player, currency).doubleValue(); + } + + /** + * Sets the player's balance. This will overwrite the previous balance, if that was not clear. + * + * @param player The {@link Player}. + * @param amount The amount. + */ + @Override + public boolean setBalance(final Player player, final double amount) { + return setBalance(player, amount, wrapper.defaultCurrency()); + } + + @Override + public boolean setBalance(final Player player, final double amount, final String currency) { + return wrapper.setBalance(player, currency, new BigDecimal(amount)); + } + + /** + * Adds to the player's current balance. + * + * @param player The {@link Player}. + * @param amount The amount. + */ + @Override + public boolean addBalance(final Player player, final double amount) { + return addBalance(player, amount, wrapper.defaultCurrency()); + } + + @Override + public boolean addBalance(final Player player, final double amount, final String currency) { + return wrapper.addBalance(player, new BigDecimal(amount), currency); + } + + /** + * Removes from the player's current balance. + * + * @param player The {@link Player}. + * @param amount The amount. + */ + @Override + public boolean removeBalance(final Player player, final double amount) { + return removeBalance(player, amount, wrapper.defaultCurrency()); + } + + @Override + public boolean removeBalance(final Player player, final double amount, final String currency) { + return wrapper.withdraw(player, new BigDecimal(amount), currency); + } + + /** + * Returns whether the player can afford a transaction. + * + * @param player The {@link Player}. + * @param amount The amount. + * + * @return true if the player can afford it, false otherwise. + */ + @Override + public boolean canAfford(final Player player, final double amount) { + return canAfford(player, amount, wrapper.defaultCurrency()); + } + + @Override + public boolean canAfford(final Player player, final double amount, final String currency) { + return wrapper.hasBalance(player, currency, new BigDecimal(amount)); + } +} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/TheNewEconomyWrapper.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/TheNewEconomyWrapper.java new file mode 100644 index 000000000..07ed950c0 --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/TheNewEconomyWrapper.java @@ -0,0 +1,68 @@ +package tech.mcprison.prison.spigot.economies; + +import net.tnemc.core.TNECore; +import net.tnemc.core.api.TNEAPI; +import tech.mcprison.prison.internal.Player; + +import java.math.BigDecimal; + +public class TheNewEconomyWrapper { + + private TNEAPI economy; + + public TheNewEconomyWrapper() { + + this.economy = new TNEAPI(); + } + + + public boolean isEnabled() { + return economy != null; + } + + public boolean supportedCurrency(final String currency) { + return TNECore.eco().currency().findCurrency(currency).isPresent(); + } + + public boolean hasAccount(final Player player) { + return economy.hasPlayerAccount(player.getUUID().toString()); + } + + public boolean hasBalance(final Player player, final String currency, final BigDecimal amount) { + return economy.hasHoldings(player.getUUID().toString(), + player.getLocation().getWorld().getName(), + currency, amount); + } + + public boolean setBalance(final Player player, final String currency, final BigDecimal amount) { + return economy.setHoldings(player.getUUID().toString(), + player.getLocation().getWorld().getName(), + currency, amount); + } + + public BigDecimal getBalance(final Player player, final String currency) { + return economy.getHoldings(player.getUUID().toString(), + player.getLocation().getWorld().getName(), + currency); + } + + public String defaultCurrency() { + return economy.getDefaultCurrency().getIdentifier(); + } + + public boolean addBalance(final Player player, final BigDecimal amount, final String currency) { + return economy.addHoldings(player.getUUID().toString(), + player.getLocation().getWorld().getName(), + currency, + amount, + "Prison").isSuccessful(); + } + + public boolean withdraw(final Player player, final BigDecimal amount, final String currency) { + return economy.removeHoldings(player.getUUID().toString(), + player.getLocation().getWorld().getName(), + currency, + amount, + "Prison").isSuccessful(); + } +} diff --git a/prison-spigot/src/main/resources/config.yml b/prison-spigot/src/main/resources/config.yml index f2c9e7a37..6ba8affaf 100644 --- a/prison-spigot/src/main/resources/config.yml +++ b/prison-spigot/src/main/resources/config.yml @@ -187,7 +187,7 @@ prison-ranks: # so enabling this setting could be dangerous. # Where it can be useful, is if prison cannot communicate through vault, # but is able to successfully communicate directly with the -# EssentialsEconomy, SaneEconomy, or GemsEconomy. Enabling this setting +# EssentialsEconomy, SaneEconomy, TheNewEconomy, or GemsEconomy. Enabling this setting # will NOT work for any other plugins. # To test vault, run the following commands when vault economy has been # succesfully loaded. Run these command in the console: diff --git a/prison-spigot/src/main/resources/plugin.yml b/prison-spigot/src/main/resources/plugin.yml index 99f283129..afd56092b 100644 --- a/prison-spigot/src/main/resources/plugin.yml +++ b/prison-spigot/src/main/resources/plugin.yml @@ -36,6 +36,7 @@ softdepend: - PermissionsEx - GroupManagerX - GemsEconomy + - TheNewEconomy - TokenEnchant - CMI - CMILib From 8aa350d1eeb935ee6a7cf3e3aa216d7d1b2a5176 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 29 Jul 2024 21:38:12 -0400 Subject: [PATCH 114/323] Update the TNE API jar: TheNewEconomy_prisonBuild_v0.1.3.0.jar It was accidentally built with Java 21 instead of Java 1.8. --- docs/changelog_v3.3.x.md | 3 +++ .../TheNewEconomy_prisonBuild_v0.1.3.0.jar | Bin 2191 -> 2260 bytes 2 files changed, 3 insertions(+) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 455f09ff9..a52af429a 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-beta.18c 2024-07-29 +* **Update the TNE API jar: TheNewEconomy_prisonBuild_v0.1.3.0.jar It was accidentally built with Java 21 instead of Java 1.8.** + + * **Bug fix: When using a file filter, handle the condition of the result being null.** diff --git a/prison-spigot/lib/TheNewEconomy_prisonBuild_v0.1.3.0.jar b/prison-spigot/lib/TheNewEconomy_prisonBuild_v0.1.3.0.jar index 23aa831e374ab63081766057972e0eafb02d7da2..08bad829476e2017ca71427b5cf19969c41f4e13 100644 GIT binary patch delta 1209 zcmV;q1V;Oh5!4Y3P)h>@6aWYa2mnB8YClaylOKe^Bqi6(x4A7#89CTI}4xR3Unb5HNr_xmS+bChjZ z3`NPcqa~ktj^``x^xD@=$~K}5xrzJaI#XAUoV&q43SE;&k$|;L!Lqe z$qZtMGk;`TLh|-vHsGq~4yK&ppyhk+wC^fm`tUNU$70SZg|2MW{~<^^@u zR%SL}7FVw!(^PpJ()*F|Z!8$OB91qWL|-=K3R{hog6`x8P)i30vjOeOZUF!QxB>tG zP?G}!=K>(Blk5U9f3;IvPZLoPp3~i4pe>g|5kye&)~&)OhWLUZLBL2-TOyYS9!w6q zr|ltoA!m0n#J}W&`eNdPKfoVloO5>5Lc0<)vJbm6XXcylo0+pee|`S}0IOi;Awyu! zW1$&(%(YC*7tExm+}v+&Z|v^mK_@VALeHq_P_JXQj!&2se-g;Oa2M0S_l5r>pi@jxG*SB}6pe_rUK=vZmf8#qg zCZN|!DSiDDf0u?`^A+!GF^jv@QKCjZ_`!-GH*RJo9g4yN7WRb| zI~Tp?Kgu-H$wpuS?&e{Uz;s%?1ovPT*LAf0u7!g|C0ndbBPZPKwX;w&uH0f7K|40{ zLf+;~AWzL0R#$+>1OR)bw%zab<9}UA+Dxtzo(ud)e^|J?F~MB_jP-Suc(4~)77K!Q zgE30y= zadfDhf3&J-#bh&RY0A0N_3yhp9~sP!JTo={7|vUZ7(;Nq8(RX74j#gR*o@G_fEYsT$Im0ssIq2b10c9J8_oVF3a_tCJN6L=7OT{aCXB?aFQe006j? zW(QjW83L0Y0v(g!2Miw|tNmE;sT$Im0ssIq2LJ#c0000000000000000QZv%2uuRq X1(W;&9Fx!m1e19P5C%*K00000@QEjk delta 1142 zcmV-+1d0395swiJP)h>@6aWYa2mm+;kqln~as-iWFn>)?!axvx+ZGC?3Wy?l^9F?2 zn-`3UA$n@i1VW;>QdV37+oTi||C0wjk!a!%@JAVEOM|Au9_I7Cc{BU<{r(By5=SO9 zhN|R|6G=Yv9X|-U)9+q&$eS=2N)zwNbEcjgJ2%4#_albvxsW2dV9@K00fW&AM%;pq zyp0U941YyeNZwt{hCJ+h!zpLja|7R-4!lsPJSiH{qnI<)+|BB3n$P`!;ke$|2C=}9 zXUO@BFyzvIX0RWG9Cg-dtM2~p--|*a$L+1t)Smy)Bp~LuA)j*@#TVZ*SiN8o`utj` zGwg(Zs;D@jjdZA&p@_bNtVx+eo~deciQF3n8e}Z8*|?~qK-OLX$nTKPV;9AQTqm@8 zxeu_rB}%U;z8UishM~M>wGv6KnZ_6X=xK=_9gj-FJR`4dWENv)b=6InDk@_?Ry&|x zO5J!#&8TctKa8{54^T@72;YU`Kvw|(0Gg8)0_&6K1rU=F10#Q}Q(JEmQ4pR3%N^QE zTPoI8tv421HZjJRnkHCkBq7iU?L!|-4$A>fvzKNsHI0AC2ld6o2Y-M+$~b#=vk+Jt z)bg-r=FEKaeKT|T`Rn@+0H{MP1u+6;gE@+0FkMwt(_#v};7YH3R6lN}Kq9bmPA{pV zQDdZZ`sYk_2qb@Baf3St1mYF>lz?<-4pO?&NslqpA(W#BGsr(lb~T2wp__h18eb9VHugHuE$4K}2%<{XCY zY*plIS5`n!bHEIT4>_}try|d*OT%LVfW6YeVAAWy8(m4%Os*52v`yDiad%4=)6GjZ z(Us?R*HwR2X4^wo6Yt)8Z(Wi8hI@}W=U1tDl<)u>i-Y&eqJ{qn{HD-T@WiemQT+z# zFKEOt0Yn%tA&1|5VCSI#-h7r|IRL-JGv;BWPcz80K$iSyfb^^txFraSuo~3p2{}#v)0h^8P?H?3#$YhAYuIW0t~DF#ZZ5SI{`xrPYF-yD{OwA;V27^svi$I zq>w`jIi!Gtz+CZ?)KDfV&QIf;9-E=3y|^Rqgm+A6f_<}pTN@q`X0|@ zBxyw;5B%s~4$QMEc$dITc>%844RKZB+3Yaq9>Vj;VeSfV?>A6O2M9gkS=Va<005l^ z006Vy1$zMkI0%zk2Sg2W1pQdwh2lV00RRA+ldA_?0s;b)z6TjEYGHO^P)h*<6aW+e z2nYxO{09A4J>gl`YXSfOody5^9{>OV0000000000007{VPzX!{m<5wj2pp5T2owef I2LJ#70BYg@%K!iX From 790be7593343a7de4bd393571eab57aae2c78efc Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 29 Jul 2024 21:40:38 -0400 Subject: [PATCH 115/323] PrisonJarReporter: Update support for java 22. --- docs/changelog_v3.3.x.md | 4 ++++ .../java/tech/mcprison/prison/util/PrisonJarReporter.java | 1 + 2 files changed, 5 insertions(+) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index a52af429a..97081ed43 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-beta.18c 2024-07-29 +* **PrisonJarReporter: Update support for java 22.** + + + * **Update the TNE API jar: TheNewEconomy_prisonBuild_v0.1.3.0.jar It was accidentally built with Java 21 instead of Java 1.8.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/util/PrisonJarReporter.java b/prison-core/src/main/java/tech/mcprison/prison/util/PrisonJarReporter.java index b9cb8f58d..ba8047870 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/util/PrisonJarReporter.java +++ b/prison-core/src/main/java/tech/mcprison/prison/util/PrisonJarReporter.java @@ -59,6 +59,7 @@ public enum JavaVersion { JavaSE_19("3f"), JavaSE_20("40"), JavaSE_21("41"), + JavaSE_22("42"), JavaSE_UnknownVersion("UnknownJavaVersion") ; From aca01590ad3d82f900cc647fd5fd06eb104524c7 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 29 Jul 2024 22:02:16 -0400 Subject: [PATCH 116/323] Mine Bombs: Updated text on the mine bomb list help details. --- docs/changelog_v3.3.x.md | 5 +++++ .../mcprison/prison/spigot/utils/PrisonUtilsMineBombs.java | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 97081ed43..d180b4afb 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-beta.18c 2024-07-29 + +* **Mine Bombs: Updated text on the mine bomb list help details.** + + + * **PrisonJarReporter: Update support for java 22.** 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 c206f9a81..99bc0a8ef 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 @@ -488,7 +488,8 @@ public void reloadPrisonMineBombs() { @Command(identifier = "prison utils bomb list", description = "A list of all available bombs, including their full details. " + - "This command also shows a list of settings for shapes, sounds, and visual effects.", + "This command also shows a list of settings for the animation patterns, " + + "shapes, sounds, and visual effects. This command is best ran in the console.", onlyPlayers = false, permissions = "prison.utils.bombs" ) public void utilsMineBombsList( CommandSender sender, From 005b13b7d97b3a5e6848371803914d186c9526d1 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 29 Jul 2024 23:27:32 -0400 Subject: [PATCH 117/323] TheNewEconomy support: I had a wrong method signature for one of the mock functions. This should correct it. The jar was regenerated for java 1.8. --- docs/changelog_v3.3.x.md | 3 +++ .../main/java/net/tnemc/core/api/TNEAPI.java | 3 ++- .../TheNewEconomy_prisonBuild_v0.1.3.0.jar | Bin 2260 -> 2285 bytes .../economies/TheNewEconomyWrapper.java | 2 +- 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index d180b4afb..488fd48db 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-beta.18c 2024-07-29 +* **TheNewEconomy support: I had a wrong method signature for one of the mock functions. This should correct it.** +The jar was regenerated for java 1.8. + * **Mine Bombs: Updated text on the mine bomb list help details.** diff --git a/prison-misc/src/main/java/net/tnemc/core/api/TNEAPI.java b/prison-misc/src/main/java/net/tnemc/core/api/TNEAPI.java index 9ecf4d7b4..eb7bb7060 100644 --- a/prison-misc/src/main/java/net/tnemc/core/api/TNEAPI.java +++ b/prison-misc/src/main/java/net/tnemc/core/api/TNEAPI.java @@ -1,10 +1,11 @@ package net.tnemc.core.api; import java.math.BigDecimal; +import java.util.UUID; public class TNEAPI { - public boolean hasPlayerAccount( String playerUUID ) { + public boolean hasPlayerAccount( UUID playerUUID ) { return true; } diff --git a/prison-spigot/lib/TheNewEconomy_prisonBuild_v0.1.3.0.jar b/prison-spigot/lib/TheNewEconomy_prisonBuild_v0.1.3.0.jar index 08bad829476e2017ca71427b5cf19969c41f4e13..366ce0d124bbfa16fb42c956f73e1e5186f1a485 100644 GIT binary patch delta 1156 zcmV-~1bh3`5$zESP)h>@6aWYa2mmg-kqln~CA+b0lmY@JyORS0Hh)1BKGSYnO3SU> zK}5w%w<2pI@dZPIfRUuML@p0Jm<+o^J7h0pb{0eYOFpPCCO-HB{87d;vzr3#O3=tA zJ2Pj_`Of#9b9R6J`u+m|mf?8;G6bf5CN1eR&$jG9FpHjYYp=1nwzE|LgTU|!J)@RO z{g%}{I$^dXkblK}E`L`EWUJ-@0b@OISU+T;ScV+r2@KV_&l-_;#Kaywav6b2J+P^J zKm}KJa%spm4++fH|0rMu>Dx5iap^e|YqlLkKGKg?>snJJxohq3Z*8oYhXndhb(FFZ z)g6IX+f23tXNL;vG06lnmoWF+z;(FaLaUji)urxAfwwC+zkl(lY+J8+YlGR`qpp@z z=?x}O{16D&X`l!KeRd=S^X+r&DfQy&Cerhv+K|Z$wWZc&tMQN8&2+LN+=Y7um?ton z<}bs2n8x`XZoX?`m8fKc9n;8_>z#7us^+z09YD~Q!+gn)ITOfJHG9?d!4m?2wNl5q zsP*H2ol{y*u74Ar4}(b9IJ-f?yx@#o=qmGYH?nOOhR2bs{|)t3?&|P2Tz&ARILnfv z#1>)QuwKoUVC1*VE*hmhtokGOXK|v8Wq(WduDR+Kbc?ENRR74Nyx52-^Q^ zAg2NV07C}=08mQ<1QY-W2nYbMx|8VzGJm~p!Y~k?gTy*~;3pE`Mh67~^#{u5( zfWlzN#l6brB$Yuuz3j%IwAgN!^BPygomLX0M(^QewV17!@L4sIrn7TS6I#g8uYWZj ziDy!}Xu}vP4k+qc{k*GyNx~E&TL>JfR7k$c)64egbgFFT$FK=pKF+8nKcx@HI$fcm z2~^ZcQi!QF{M^$+!dE+F8%S zD!++RlK1?kqsrg{aD)nYapir002XiJ_tY{u)6(NQe#SsE&%`lGz0(u9smFU0000000000 W008R+lTip9le!2L24x2T0002{xe~@6aWYa2mnBg| z5kye&)~&)OhWLUZLBL2-TOyYS9!w6qr|ltoA!m0n#J}W&`eNdPKfoVloO5>5Lc0<) zvJbm6XXcylo0+pee|`S}0IOi;Awyu!W1$&(%(YC*7tExm+}v+&Z|v^mK_@VALeHq_ zP_JXQj!&2s63D&e9)Azl31~Irkbu7F+iVmx7%4#(asa2M0S_ zl5r>pi@jxG*SB}6pe_rUK=vZmf8#qgCZN|!DSiDDmxf*Q6@Tw+F^jv@QKCjZ_`!-GH*RJo9g4yN7WRb|I~Tp?Kgu-H$wpuS?&e{Uz;s%?1ovPT*LAf0 zu7!g|C0ndbBPZPKwX;w&uH0f7K|40{Lf+;~AWzL0R#$+>1OR)bw%zab<9}UA+Dxtz zo(ud)Sh%|}!GB!;jP-Suc(4~)77K!QgE30y=adfDhw5n*uWPdYgY0A0N_3yhp9~sP!JTo={7|vUZ7(;Nq8(RX74j#gR*o@G_f z)$Gua4K*dBehnEbH!tI<8vUge3|+M6sVi7k-pX%KO9u$>sT$Im0ssIq2LJ$2O9KQH z00;;O0Q?4%_XRS4%}&BV5I&cLcbIU(g!BbGp^(@M5|N9yVLFu6{b^=*F~s=pwxm)m zjVBC;-NQ`2pP6q;q&F-WEQd5$Hk6VRPO((C!@+Q%Oz9-REABBh7DZ5t~8R*>hxBThL{OPgRLz8@^KjSS%9qt>hac78~@(n=?ZsaR)ma`3Nt5`a?(ddLa z6U99Lp8!rlQ17A;ck^gR>D`5}aeKbDvz~)heiez>`)$Oa}k}001uH0I2`~ diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/TheNewEconomyWrapper.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/TheNewEconomyWrapper.java index 07ed950c0..664adbeea 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/TheNewEconomyWrapper.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/TheNewEconomyWrapper.java @@ -25,7 +25,7 @@ public boolean supportedCurrency(final String currency) { } public boolean hasAccount(final Player player) { - return economy.hasPlayerAccount(player.getUUID().toString()); + return economy.hasPlayerAccount(player.getUUID()); } public boolean hasBalance(final Player player, final String currency, final BigDecimal amount) { From 903e362493a3c128e8871ff9e3576a845002310a Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 2 Aug 2024 02:25:46 -0400 Subject: [PATCH 118/323] Bug Fix: BlockBreakEvent ACCESS Priority. This event was not being handled in the correct place, so other fast-fail checks were intercepting this ACCESS check. This now has three different results.... If outside of a mine, it will fail and cancel the event. If in a mine and the player does not have access, then it will cancel the event. If its in a mine and the player has access, then it will let the other events handle the event without it being canceled. --- docs/changelog_v3.3.x.md | 7 +- .../spigot/block/OnBlockBreakMines.java | 103 +++++++++++++----- 2 files changed, 83 insertions(+), 27 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 488fd48db..955b1d061 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-beta.18c 2024-07-29 +# 3.3.0-beta.18c 2024-08-02 + + +* **Bug Fix: BlockBreakEvent ACCESS Priority. This event was not being handled in the correct place, so other fast-fail checks were intercepting this ACCESS check.** +This now has three different results.... If outside of a mine, it will fail and cancel the event. If in a mine and the player does not have access, then it will cancel the event. +If its in a mine and the player has access, then it will let the other events handle the event without it being canceled. * **TheNewEconomy support: I had a wrong method signature for one of the mock functions. This should correct it.** 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 cdd7de9ad..94ab42dab 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 @@ -47,7 +47,11 @@ enum EventResultsReasons { cancel_event__block_already_counted, ignore_event__monitor_priority_but_not_AIR, cancel_event__player_has_no_access, - cancel_event__block_is_not_mappable_to_target_block + cancel_event__block_is_not_mappable_to_target_block, + + results_passed__access_priority__player_has_access, + cancel_event__access_priority__block_is_not_in_a_mine, + cancel_event__access_priority__player_has_no_access ; } @@ -301,6 +305,53 @@ protected MinesEventResults ignoreMinesBlockBreakEvent( Player player, results.setCancelEvent( true ); results.setIgnoreEvent( true ); } + else if ( bbPriority.isAccess() ) { + + Mine mine = findMine( player, sBlock, null, null ); + results.setMine( mine ); + + if ( mine == null ) { + // Prison is unable to process blocks outside of mines right now, so exit: + results.setResultsReason( EventResultsReasons + .cancel_event__access_priority__block_is_not_in_a_mine ); + + results.setCancelEvent( true ); + results.setIgnoreEvent( true ); + } + else if ( !mine.hasMiningAccess(sPlayer) ) { + + results.setResultsReason( EventResultsReasons + .cancel_event__access_priority__player_has_no_access ); + results.setIgnoreEvent( true ); + results.setCancelEvent( true ); + + if ( sPlayer != null && + AutoFeaturesWrapper.getInstance() + .isBoolean( AutoFeatures.eventPriorityACCESSFailureTPToCurrentMine ) ) { + // run the `/mines tp` command for the player which will TP them to a + // mine they can access: + + String debugInfo = String.format( + "ACCESS failed: teleport %s to valid mine.", + sPlayer.getName() ); + + PrisonCommandTaskData cmdTask = new PrisonCommandTaskData( debugInfo, + "mines tp", 0 ); + cmdTask.setTaskMode( TaskMode.syncPlayer ); + + PrisonCommandTasks.submitTasks( sPlayer, cmdTask ); + + } + + } + else { + results.setResultsReason( EventResultsReasons + .results_passed__access_priority__player_has_access ); + + results.setIgnoreEvent( true ); + } + + } else if ( bbPriority.isMonitor() && !sBlock.isEmpty() && AutoFeaturesWrapper.getInstance().isBoolean( AutoFeatures.processMonitorEventsOnlyIfPrimaryBlockIsAIR ) ) { @@ -331,31 +382,31 @@ else if ( bbPriority.isMonitor() && !sBlock.isEmpty() && results.setCancelEvent( true ); } - else if ( bbPriority.isAccess() && !mine.hasMiningAccess(sPlayer) ) { - - results.setResultsReason( EventResultsReasons.cancel_event__player_has_no_access ); - results.setIgnoreEvent( true ); - results.setCancelEvent( true ); - - if ( sPlayer != null && - AutoFeaturesWrapper.getInstance() - .isBoolean( AutoFeatures.eventPriorityACCESSFailureTPToCurrentMine ) ) { - // run the `/mines tp` command for the player which will TP them to a - // mine they can access: - - String debugInfo = String.format( - "ACCESS failed: teleport %s to valid mine.", - sPlayer.getName() ); - - PrisonCommandTaskData cmdTask = new PrisonCommandTaskData( debugInfo, - "mines tp", 0 ); - cmdTask.setTaskMode( TaskMode.syncPlayer ); - - PrisonCommandTasks.submitTasks( sPlayer, cmdTask ); - - } - - } +// else if ( bbPriority.isAccess() && !mine.hasMiningAccess(sPlayer) ) { +// +// results.setResultsReason( EventResultsReasons.cancel_event__player_has_no_access ); +// results.setIgnoreEvent( true ); +// results.setCancelEvent( true ); +// +// if ( sPlayer != null && +// AutoFeaturesWrapper.getInstance() +// .isBoolean( AutoFeatures.eventPriorityACCESSFailureTPToCurrentMine ) ) { +// // run the `/mines tp` command for the player which will TP them to a +// // mine they can access: +// +// String debugInfo = String.format( +// "ACCESS failed: teleport %s to valid mine.", +// sPlayer.getName() ); +// +// PrisonCommandTaskData cmdTask = new PrisonCommandTaskData( debugInfo, +// "mines tp", 0 ); +// cmdTask.setTaskMode( TaskMode.syncPlayer ); +// +// PrisonCommandTasks.submitTasks( sPlayer, cmdTask ); +// +// } +// +// } else { MineTargetPrisonBlock targetBlock = mine.getTargetPrisonBlock( sBlock ); From a5c31a1aea21510aecf0b78f03e0ab68c60ab55f Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 3 Aug 2024 17:15:43 -0400 Subject: [PATCH 119/323] Debugging info: Expanded the debugging info for the smelting and blocking to show the progressions. This is important for tracking and understanding how and if they are working. Changed some of the coloring so it's easier to read and for various headers to standout. --- docs/changelog_v3.3.x.md | 7 +- .../mcprison/prison/spigot/SpigotUtil.java | 19 ++- .../autofeatures/AutoManagerFeatures.java | 136 ++++++++++-------- 3 files changed, 101 insertions(+), 61 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 955b1d061..450adfdea 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-beta.18c 2024-08-02 +# 3.3.0-beta.18c 2024-08-03 + + +* **Debugging info: Expanded the debugging info for the smelting and blocking to show the progressions.** +This is important for tracking and understanding how and if they are working. +Changed some of the coloring so it's easier to read and for various headers to standout. * **Bug Fix: BlockBreakEvent ACCESS Priority. This event was not being handled in the correct place, so other fast-fail checks were intercepting this ACCESS check.** 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 66f567c23..16f161361 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 @@ -201,7 +201,7 @@ public static SpigotItemStack getSpigotItemStack( PrisonBlock material, int amou } public static void getSpigotBlock( ItemStack iStack ) { - XMaterial xmat = XMaterial.matchXMaterial( iStack ); + //XMaterial xmat = XMaterial.matchXMaterial( iStack ); // SpigotCompatibility.getInstance(). } @@ -472,6 +472,17 @@ public static int itemStackRemoveAll( XMaterial xMat, Inventory inv ) { } + /** + *

This function will take a given XMaterial and remove all occurrences of it + * from a player's inventory, and add the quantity removed, to the ItemStack drop + * amount. This basically moves an item from the player's inventory, to the drop + * ItemStack. + *

+ * + * @param player + * @param xMat + * @param drop + */ public static void getAllDroppedItemTypesFromPlayerInventory( Player player, XMaterial xMat, SpigotItemStack drop ) { @@ -541,7 +552,8 @@ else if ( obj instanceof Map ) { * @param ratio */ public static void itemStackReplaceItems( List stacks, - XMaterial source, XMaterial target, int ratio ) { + XMaterial source, XMaterial target, int ratio, + StringBuilder debugInfo ) { // Removes all of the specified source types from all inventories: int sourceRemoved = itemStackRemoveAll( source, stacks ); @@ -560,6 +572,9 @@ public static void itemStackReplaceItems( List stacks, itemStackAddAll( stacks, target, targetCount ); } + debugInfo.append( "&d[&b" ).append( source.name() ).append( "&c:&b" ).append( sourceRemoved ) + .append( " &7->&b " ) + .append( target.name() ).append( "&c:&b" ).append( targetCount ).append( "&d]&3" ); } 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 e7677f642..9e4c972bb 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 @@ -597,23 +597,25 @@ private int applyAutoEventsDetails( PrisonMinesBlockBreakEvent pmEvent ) { pmEvent.getDebugInfo().append(" isAutoFeaturesEnabled=false ("); pmEvent.getDebugInfo().append( Output.get().getColorCodeError() ); - pmEvent.getDebugInfo().append("disabled"); + pmEvent.getDebugInfo().append(" disabled"); pmEvent.getDebugInfo().append( Output.get().getColorCodeDebug() ); pmEvent.getDebugInfo().append(")"); } else { pmEvent.getDebugInfo() - .append( " Pickup [") - .append( isAutoPickup ? "enabled: " : "disabled:" ) + .append( " &7Pickup&3 [") + .append( isAutoPickup ? "enabled: " : + Output.get().getColorCodeError() + "disabled:" + Output.get().getColorCodeDebug() ) .append( lorePickup ? "lore " : "" ) .append( permPickup ? "perm " : "" ) .append( configPickup ? "config " : "" ) .append( limit2minesPickup ? "mines" : "noLimit" ) .append( "] ") - .append( " Smelt [") - .append( isAutoSmelt ? "enabled: " : "disabled:" ) + .append( " &7Smelt&3 [") + .append( isAutoSmelt ? "enabled: " : + Output.get().getColorCodeError() + "disabled:" + Output.get().getColorCodeDebug() ) .append( loreSmelt ? "lore " : "" ) .append( permSmelt ? "perm " : "" ) .append( configSmelt ? "config " : "" ) @@ -621,8 +623,9 @@ private int applyAutoEventsDetails( PrisonMinesBlockBreakEvent pmEvent ) { .append( includePlayerInventoryWhenSmelting ? " includePlayerInventory" : "" ) .append( "] ") - .append( " Block [") - .append( isAutoBlock ? "enabled: " : "disabled:" ) + .append( " &7Block&3 [") + .append( isAutoBlock ? "enabled: " : + Output.get().getColorCodeError() + "disabled:" + Output.get().getColorCodeDebug() ) .append( loreBlock ? "lore " : "" ) .append( permBlock ? "perm " : "" ) .append( configBlock ? "config " : "" ) @@ -656,18 +659,22 @@ private int applyAutoEventsDetails( PrisonMinesBlockBreakEvent pmEvent ) { if ( configNormalDrop ) { pmEvent.getDebugInfo() - .append( "{br}|| (NormalDrop handling enabled: " ) - .append( "normalDropSmelt[" ) - .append( configNormalDropSmelt ? "enabled" : "disabled" ) +// .append( "{br}||") + .append( "(&7NormalDrop handling enabled&3: " ) + .append( "&7normalDropSmelt&3[" ) + .append( configNormalDropSmelt ? "enabled" : + Output.get().getColorCodeError() + "disabled:" + Output.get().getColorCodeDebug() ) .append( configNormalDropSmelt && includePlayerInventoryWhenSmelting ? " includePlayerInventory" : "" ) .append( "] " ) - .append( "normalDropBlock[" ) - .append( configNormalDropBlock ? "enabled" : "disabled" ) + .append( "&7normalDropBlock&3[" ) + .append( configNormalDropBlock ? "enabled" : + Output.get().getColorCodeError() + "disabled:" + Output.get().getColorCodeDebug() ) .append( configNormalDropBlock && includePlayerInventoryWhenBlocking ? " includePlayerInventory" : "" ) .append( "] " ) - .append( "normalDropCheckForFullInventory[" ) - .append( configNormalDropCheckForFullInventory ? "enabled" : "disabled" ) + .append( "&7normalDropCheckForFullInventory&3[" ) + .append( configNormalDropCheckForFullInventory ? "enabled" : + Output.get().getColorCodeError() + "disabled:" + Output.get().getColorCodeDebug() ) .append( "] " ) .append( ")" ); @@ -677,7 +684,10 @@ private int applyAutoEventsDetails( PrisonMinesBlockBreakEvent pmEvent ) { } else { - pmEvent.getDebugInfo().append(" [Warning: normalDrop handling is disabled] " ); + pmEvent.getDebugInfo().append( + Output.get().getColorCodeError() + + " [Warning: normalDrop handling is disabled] " + + Output.get().getColorCodeDebug() ); } } @@ -863,7 +873,7 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, sb.insert( 0, "bukkitDropMult=" ); } - debugInfo.append( " [autoPickupDrops:beforeFortune:: " ).append( sb ).append( "] "); + debugInfo.append( " [&7autoPickupDrops&3:beforeFortune:: " ).append( sb ).append( "] "); @@ -895,7 +905,7 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, .append( ":" ) .append( itemStack.getAmount() ); } - debugInfo.append( " [totalDrops:afterFortune:: " ).append( sb ).append( "] "); + debugInfo.append( " [&7totalDrops&3:afterFortune:: " ).append( sb ).append( "] "); } @@ -906,17 +916,21 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, // Smelt if ( isAutoSmelt ) { - debugInfo.append( "(autoSmelting: drops)" ); + debugInfo.append( "(&7autoSmelting&3: " ); - normalDropSmelt( pmEvent.getPlayer(), drops ); + normalDropSmelt( pmEvent.getPlayer(), drops, debugInfo ); + + debugInfo.append( " )" ); } // Block if ( isAutoBlock ) { - debugInfo.append( "(autoBlocking: drops)" ); + debugInfo.append( "(&7autoBlocking&3: " ); - normalDropBlock( pmEvent.getPlayer(), drops ); + normalDropBlock( pmEvent.getPlayer(), drops, debugInfo ); + + debugInfo.append( " ) " ); } String mineName = pmEvent.getMine() == null ? null : pmEvent.getMine().getName(); @@ -1021,7 +1035,7 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, amount, mineName ); if ( amount != 0 ) { - debugInfo.append( "(sold: " + itemStack.getName() + " qty: " + itemStack.getAmount() + + debugInfo.append( "(&7sold&3: " + itemStack.getName() + " qty: " + itemStack.getAmount() + " value: " + dFmt.format( amount ) + ") "); // Set to zero quantity since they have all been sold. @@ -1031,7 +1045,7 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, // Unable to sell since amount was zero. Not configured to be sold. pmEvent.setDebugColorCodeWarning(); - debugInfo.append( "(unsellable: " + itemStack.getName() + " qty: " + itemStack.getAmount() + ") "); + debugInfo.append( "(&7unsellable&3: " + itemStack.getName() + " qty: " + itemStack.getAmount() + ") "); pmEvent.setDebugColorCodeDebug(); autosellUnsellableCount += itemStack.getAmount(); } @@ -1063,7 +1077,8 @@ 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}|| " ); + debugInfo.append( " (&7WARNING: autosell leftovers&3: " + itemStack.getName() + " qty: " + itemStack.getAmount() + " value: " + dFmt.format( amount ) + " - " + ( amount == 0 ? " Items NOT in sellall shop!" : " CouldNotSell?") + @@ -1077,7 +1092,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( " (&7Debug-unsold-value-check&3: " + itemStack.getName() + " qty: " + itemStack.getAmount() + " value: " + dFmt.format( amount ) + ") "); } @@ -1113,7 +1128,8 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, if ( count > 0 || autosellTotal > 0 ) { - debugInfo.append( "{br}|| [autoPickupDrops total: qty: " + count + " value: " + dFmt.format( autosellTotal ) + +// debugInfo.append( "{br}|| " ); + debugInfo.append( " [&7autoPickupDrops total&3: qty: " + count + " value: " + dFmt.format( autosellTotal ) + " unsellableCount: " + autosellUnsellableCount ); if ( nanoTime > 0 ) { @@ -1224,16 +1240,20 @@ public int calculateNormalDrop( PrisonMinesBlockBreakEvent pmEvent ) { if ( isBoolean( AutoFeatures.normalDropSmelt ) ) { - pmEvent.getDebugInfo().append( "(normSmelting: drops)" ); + pmEvent.getDebugInfo().append( "(normSmelting: " ); - normalDropSmelt( pmEvent.getPlayer(), drops ); + normalDropSmelt( pmEvent.getPlayer(), drops, pmEvent.getDebugInfo() ); + + pmEvent.getDebugInfo().append( " ) " ); } if ( isBoolean( AutoFeatures.normalDropBlock ) ) { - pmEvent.getDebugInfo().append( "(normBlocking: drops)" ); + pmEvent.getDebugInfo().append( "(normBlocking: " ); + + normalDropBlock( pmEvent.getPlayer(), drops, pmEvent.getDebugInfo() ); - normalDropBlock( pmEvent.getPlayer(), drops ); + pmEvent.getDebugInfo().append( " ) " ); } @@ -2268,7 +2288,7 @@ else if ( isBoolean( AutoFeatures.pickupBlockNameListEnabled ) && pickupBlockNam * * @param drops */ - protected void normalDropSmelt( Player player, List drops ) { + protected void normalDropSmelt( Player player, List drops, StringBuilder debugInfo ) { boolean isAll = isBoolean( AutoFeatures.smeltAllBlocks ); @@ -2374,7 +2394,7 @@ else if ( sItemStack.getMaterial() != null ) { SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( player, source, drop ); } - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.STONE, 1 ); + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.STONE, 1, debugInfo ); } break; @@ -2389,7 +2409,7 @@ else if ( sItemStack.getMaterial() != null ) { SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( player, source, drop ); } - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.GOLD_INGOT, 1 ); + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.GOLD_INGOT, 1, debugInfo ); } break; @@ -2402,7 +2422,7 @@ else if ( sItemStack.getMaterial() != null ) { SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( player, source, drop ); } - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.IRON_INGOT, 1 ); + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.IRON_INGOT, 1, debugInfo ); } break; @@ -2414,7 +2434,7 @@ else if ( sItemStack.getMaterial() != null ) { SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( player, source, drop ); } - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.COAL, 1 ); + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.COAL, 1, debugInfo ); } break; @@ -2426,7 +2446,7 @@ else if ( sItemStack.getMaterial() != null ) { SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( player, source, drop ); } - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.DIAMOND, 1 ); + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.DIAMOND, 1, debugInfo ); } break; @@ -2438,7 +2458,7 @@ else if ( sItemStack.getMaterial() != null ) { SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( player, source, drop ); } - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.EMERALD, 1 ); + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.EMERALD, 1, debugInfo ); } break; @@ -2450,7 +2470,7 @@ else if ( sItemStack.getMaterial() != null ) { SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( player, source, drop ); } - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.LAPIS_LAZULI, 1 ); + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.LAPIS_LAZULI, 1, debugInfo ); } break; @@ -2462,7 +2482,7 @@ else if ( sItemStack.getMaterial() != null ) { SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( player, source, drop ); } - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.REDSTONE, 1 ); + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.REDSTONE, 1, debugInfo ); } break; @@ -2473,7 +2493,7 @@ else if ( sItemStack.getMaterial() != null ) { SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( player, source, drop ); } - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.QUARTZ, 1 ); + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.QUARTZ, 1, debugInfo ); } break; @@ -2484,7 +2504,7 @@ else if ( sItemStack.getMaterial() != null ) { SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( player, source, drop ); } - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.NETHERITE_SCRAP, 1 ); + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.NETHERITE_SCRAP, 1, debugInfo ); } break; @@ -2498,7 +2518,7 @@ else if ( sItemStack.getMaterial() != null ) { SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( player, source, drop ); } - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.COPPER_INGOT, 1); + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.COPPER_INGOT, 1, debugInfo); } break; @@ -2517,7 +2537,7 @@ else if ( sItemStack.getMaterial() != null ) { * * @param drops */ - protected void normalDropBlock( Player player, List drops ) { + protected void normalDropBlock( Player player, List drops, StringBuilder debugInfo ) { boolean isAll = isBoolean( AutoFeatures.smeltAllBlocks ); @@ -2555,7 +2575,7 @@ protected void normalDropBlock( Player player, List drops ) { SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( player, source, drop ); } - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.RAW_GOLD_BLOCK, 9 ); + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.RAW_GOLD_BLOCK, 9, debugInfo ); } break; @@ -2566,7 +2586,7 @@ protected void normalDropBlock( Player player, List drops ) { SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( player, source, drop ); } - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.GOLD_BLOCK, 9 ); + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.GOLD_BLOCK, 9, debugInfo ); } break; @@ -2577,7 +2597,7 @@ protected void normalDropBlock( Player player, List drops ) { SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( player, source, drop ); } - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.RAW_IRON_BLOCK, 9 ); + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.RAW_IRON_BLOCK, 9, debugInfo ); } break; @@ -2588,7 +2608,7 @@ protected void normalDropBlock( Player player, List drops ) { SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( player, source, drop ); } - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.IRON_BLOCK, 9 ); + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.IRON_BLOCK, 9, debugInfo ); } break; @@ -2599,7 +2619,7 @@ protected void normalDropBlock( Player player, List drops ) { SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( player, source, drop ); } - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.COAL_BLOCK, 9 ); + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.COAL_BLOCK, 9, debugInfo ); } break; @@ -2610,7 +2630,7 @@ protected void normalDropBlock( Player player, List drops ) { SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( player, source, drop ); } - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.DIAMOND_BLOCK, 9 ); + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.DIAMOND_BLOCK, 9, debugInfo ); } break; @@ -2621,7 +2641,7 @@ protected void normalDropBlock( Player player, List drops ) { SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( player, source, drop ); } - SpigotUtil.itemStackReplaceItems( drops, source,XMaterial.REDSTONE_BLOCK, 9 ); + SpigotUtil.itemStackReplaceItems( drops, source,XMaterial.REDSTONE_BLOCK, 9, debugInfo ); } break; @@ -2632,7 +2652,7 @@ protected void normalDropBlock( Player player, List drops ) { SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( player, source, drop ); } - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.EMERALD_BLOCK, 9 ); + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.EMERALD_BLOCK, 9, debugInfo ); } break; @@ -2643,7 +2663,7 @@ protected void normalDropBlock( Player player, List drops ) { SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( player, source, drop ); } - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.QUARTZ_BLOCK, 4 ); + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.QUARTZ_BLOCK, 4, debugInfo ); } break; @@ -2654,7 +2674,7 @@ protected void normalDropBlock( Player player, List drops ) { SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( player, source, drop ); } - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.PRISMARINE, 4 ); + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.PRISMARINE, 4, debugInfo ); } break; @@ -2665,7 +2685,7 @@ protected void normalDropBlock( Player player, List drops ) { SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( player, source, drop ); } - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.SNOW_BLOCK, 4 ); + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.SNOW_BLOCK, 4, debugInfo ); } break; @@ -2676,7 +2696,7 @@ protected void normalDropBlock( Player player, List drops ) { SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( player, source, drop ); } - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.GLOWSTONE, 4 ); + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.GLOWSTONE, 4, debugInfo ); } break; @@ -2687,7 +2707,7 @@ protected void normalDropBlock( Player player, List drops ) { SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( player, source, drop ); } - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.LAPIS_BLOCK, 9 ); + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.LAPIS_BLOCK, 9, debugInfo ); } break; @@ -2698,7 +2718,7 @@ protected void normalDropBlock( Player player, List drops ) { SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( player, source, drop ); } - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.RAW_COPPER_BLOCK, 9 ); + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.RAW_COPPER_BLOCK, 9, debugInfo ); } break; @@ -2709,7 +2729,7 @@ protected void normalDropBlock( Player player, List drops ) { SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( player, source, drop ); } - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.COPPER_BLOCK, 9 ); + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.COPPER_BLOCK, 9, debugInfo ); } break; From cb31375e518dd86077cc6dfe3e4301387ccd55a7 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 8 Aug 2024 03:30:05 -0400 Subject: [PATCH 120/323] Placeholders: Fixed a bug when the player is at the last possible rank on both the default and prestiges ladder. The fact that there isn't a next rank was causing problem when trying to get the next ranks ladder base multiplier, which does not exist. --- docs/changelog_v3.3.x.md | 7 ++++++- .../tech/mcprison/prison/ranks/managers/RankManager.java | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 450adfdea..698e9cc25 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-beta.18c 2024-08-03 +# 3.3.0-beta.18c 2024-08-08 + + + +* **Placeholders: Fixed a bug when the player is at the last possible rank on both the default and prestiges ladder.** +The fact that there isn't a next rank was causing problem when trying to get the next ranks ladder base multiplier, which does not exist. * **Debugging info: Expanded the debugging info for the smelting and blocking to show the progressions.** 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 272b289df..c6d5565cc 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 @@ -1215,7 +1215,12 @@ else if ( placeHolder == PrisonPlaceHolders.prison_top_player_penalty_raw_nnn_tp // RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); // PlayerRank pRank = rankPlayerFactory.createPlayerRank( rank ); - results = Double.toString( pRank.getLadderBasedRankMultiplier() ); + if ( pRank == null ) { + results = ""; + } + else { + results = Double.toString( pRank.getLadderBasedRankMultiplier() ); + } break; From ffc7c6fd64b9b7a6dde4fed75382e44753e0c0f9 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 9 Aug 2024 03:39:19 -0400 Subject: [PATCH 121/323] Economy: CoinsEngine: fixed a problem with using the wrong plugin signature. This now works as expected. --- docs/changelog_v3.3.x.md | 5 ++++- .../prison/spigot/economies/CoinsEngineEconomy.java | 2 +- .../prison/spigot/economies/CoinsEngineEconomyWrapper.java | 6 +++--- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 698e9cc25..fb41cee3d 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-beta.18c 2024-08-08 +# 3.3.0-beta.18c 2024-08-09 +* **Economy: CoinsEngine: fixed a problem with using the wrong plugin signature.** +This now works as expected. This was tested with gemsEconommy such that some currencies from both were actively being used. + * **Placeholders: Fixed a bug when the player is at the last possible rank on both the default and prestiges ladder.** The fact that there isn't a next rank was causing problem when trying to get the next ranks ladder base multiplier, which does not exist. diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/CoinsEngineEconomy.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/CoinsEngineEconomy.java index 95de2fc10..9c9980534 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/CoinsEngineEconomy.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/CoinsEngineEconomy.java @@ -11,7 +11,7 @@ public class CoinsEngineEconomy private boolean availableAsAnAlternative = false; public CoinsEngineEconomy() { - super( "CoinsEngineEconomy", "CoinsEngineEconomy" ); + super( "CoinsEngine", "CoinsEngine" ); } /** 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 index c3e7fca1c..2744aeef0 100644 --- 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 @@ -43,7 +43,7 @@ public Currency getCurrency( String currencyNamme ) { public double getBalance(Player player) { - Output.get().logWarn( "CoinsEngineEconomy getBalance() - Fail: MUST include a currencyName."); + Output.get().logWarn( "CoinsEngine getBalance() - Fail: MUST include a currencyName."); return getBalance(player, null, false); } @@ -64,7 +64,7 @@ public double getBalance(Player player, String currencyName, boolean quite ) { public void addBalance(Player player, double amount) { - Output.get().logWarn( "CoinsEngineEconomy addBalance() - Fail: MUST include a currencyName."); + Output.get().logWarn( "CoinsEngine addBalance() - Fail: MUST include a currencyName."); addBalance(player, amount, null); } @@ -85,7 +85,7 @@ public void addBalance(Player player, double amount, String currencyName) { public void withdraw(Player player, double amount) { - Output.get().logWarn( "CoinsEngineEconomy withdraw() - Fail: MUST include a currencyName."); + Output.get().logWarn( "CoinsEngine withdraw() - Fail: MUST include a currencyName."); withdraw(player, amount, null); } From 9d5c4c2217a05c2835b976c76ec46ba63c6be499 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 13 Aug 2024 21:54:25 -0400 Subject: [PATCH 122/323] Integrations: Backpacks and prison versions reporting of integrations. Fixed an issue with backpacks not being included in the sellall activity when they are enabled in the sellall settings. Added BACKPACKs to the IntegrationType and made changes to include the listings of all backpacks and their status in the startup information and prison versions. --- docs/changelog_v3.3.x.md | 8 +- .../backpacks/PrisonCoreBackpackMessages.java | 317 ++++++++++++++++++ .../prison/gui/PrisonCoreGuiMessages.java | 3 + .../integration/IntegrationManager.java | 5 +- .../prison/integration/IntegrationType.java | 7 +- .../mcprison/prison/spigot/SpigotPrison.java | 7 + .../mcprison/prison/spigot/SpigotUtil.java | 4 +- .../spigot/backpacks/BackpacksUtil.java | 91 ++++- .../IntegrationMinepacksPlugin.java | 71 +++- .../prison/spigot/sellall/SellAllUtil.java | 21 +- 10 files changed, 513 insertions(+), 21 deletions(-) create mode 100644 prison-core/src/main/java/tech/mcprison/prison/backpacks/PrisonCoreBackpackMessages.java diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index fb41cee3d..19ed8199f 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-beta.18c 2024-08-09 +# 3.3.0-beta.18c 2024-08-13 + + +* **Integrations: Backpacks and prison versions reporting of integrations.** +Fixed an issue with backpacks not being included in the sellall activity when they are enabled in the sellall settings. +Added BACKPACKs to the IntegrationType and made changes to include the listings of all backpacks and their status in the startup information and prison versions. + * **Economy: CoinsEngine: fixed a problem with using the wrong plugin signature.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/backpacks/PrisonCoreBackpackMessages.java b/prison-core/src/main/java/tech/mcprison/prison/backpacks/PrisonCoreBackpackMessages.java new file mode 100644 index 000000000..d68761149 --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/backpacks/PrisonCoreBackpackMessages.java @@ -0,0 +1,317 @@ +package tech.mcprison.prison.backpacks; + +import java.text.DecimalFormat; + +import tech.mcprison.prison.Prison; +import tech.mcprison.prison.integration.IntegrationCore; +import tech.mcprison.prison.integration.IntegrationType; + +public class PrisonCoreBackpackMessages + extends IntegrationCore { + + public PrisonCoreBackpackMessages() { + super( "PrisonBackpacks", "Prison", IntegrationType.BACKPACK ); + } + + protected String guiClickToDecreaseMsg() { + return Prison.get().getLocaleManager() + .getLocalizable( "core_gui__click_to_decrease" ) + .localize(); + } + protected String guiClickToIncreaseMsg() { + return Prison.get().getLocaleManager() + .getLocalizable( "core_gui__click_to_increase" ) + .localize(); + } + + + protected String guiClickToCancelMsg() { + return Prison.get().getLocaleManager() + .getLocalizable( "core_gui__click_to_cancel" ) + .localize(); + } + protected String guiClickToCloseMsg() { + return Prison.get().getLocaleManager() + .getLocalizable( "core_gui__click_to_close" ) + .localize(); + } + protected String guiClickToConfirmMsg() { + return Prison.get().getLocaleManager() + .getLocalizable( "core_gui__click_to_confirm" ) + .localize(); + } + protected String guiClickToDeleteMsg() { + return Prison.get().getLocaleManager() + .getLocalizable( "core_gui__click_to_delete" ) + .localize(); + } + protected String guiClickToDisableMsg() { + return Prison.get().getLocaleManager() + .getLocalizable( "core_gui__click_to_disable" ) + .localize(); + } + protected String guiClickToEditMsg() { + return Prison.get().getLocaleManager() + .getLocalizable( "core_gui__click_to_edit" ) + .localize(); + } + protected String guiClickToEnableMsg() { + return Prison.get().getLocaleManager() + .getLocalizable( "core_gui__click_to_enable" ) + .localize(); + } + protected String guiClickToOpenMsg() { + return Prison.get().getLocaleManager() + .getLocalizable( "core_gui__click_to_open" ) + .localize(); + } + + protected String guiLeftClickToConfirmMsg() { + return Prison.get().getLocaleManager() + .getLocalizable( "core_gui__left_click_to_confirm" ) + .localize(); + } + protected String guiLeftClickToResetMsg() { + return Prison.get().getLocaleManager() + .getLocalizable( "core_gui__left_click_to_reset" ) + .localize(); + } + protected String guiLeftClickToOpenMsg() { + return Prison.get().getLocaleManager() + .getLocalizable( "core_gui__left_click_to_open" ) + .localize(); + } + protected String guiLeftClickToEditMsg() { + return Prison.get().getLocaleManager() + .getLocalizable( "core_gui__left_click_to_edit" ) + .localize(); + } + + protected String guiRightClickToCancelMsg() { + return Prison.get().getLocaleManager() + .getLocalizable( "core_gui__right_click_to_cancel" ) + .localize(); + } + protected String guiRightClickToDeleteMsg() { + return Prison.get().getLocaleManager() + .getLocalizable( "core_gui__right_click_to_delete" ) + .localize(); + } + protected String guiRightClickToDisableMsg() { + return Prison.get().getLocaleManager() + .getLocalizable( "core_gui__right_click_to_disable" ) + .localize(); + } + protected String guiRightClickToEnableMsg() { + return Prison.get().getLocaleManager() + .getLocalizable( "core_gui__right_click_to_enable" ) + .localize(); + } + protected String guiRightClickToToggleMsg() { + return Prison.get().getLocaleManager() + .getLocalizable( "core_gui__right_click_to_toggle" ) + .localize(); + } + + + protected String guiRightClickShiftToDeleteMsg() { + return Prison.get().getLocaleManager() + .getLocalizable( "core_gui__right_click_and_shift_to_delete" ) + .localize(); + } + protected String guiRightClickShiftToDisableMsg() { + return Prison.get().getLocaleManager() + .getLocalizable( "core_gui__right_click_and_shift_to_disable" ) + .localize(); + } + protected String guiRightClickShiftToToggleMsg() { + return Prison.get().getLocaleManager() + .getLocalizable( "core_gui__right_click_and_shift_to_toggle" ) + .localize(); + } + + + + protected String guiPageNextMsg() { + + return Prison.get().getLocaleManager() + .getLocalizable( "core_gui__page_next" ) + .localize(); + } + protected String guiPagePriorMsg() { + + return Prison.get().getLocaleManager() + .getLocalizable( "core_gui__page_prior" ) + .localize(); + } + + protected String guiPageToolsCloseMsg() { + + return Prison.get().getLocaleManager() + .getLocalizable( "core_gui__page_tools_close" ) + .localize(); + } + protected String guiPageToolsGoBackMsg() { + + return Prison.get().getLocaleManager() + .getLocalizable( "core_gui__page_tools_go_back" ) + .localize(); + } + private String formmatPageToolsPlaceholders( String msg, int currentPage, int maxPage ) { + + if ( maxPage < 1 ) { + maxPage = 1; + } + int priorPage = currentPage == 1 ? 1 : currentPage - 1; + int nextPage = currentPage == maxPage ? maxPage : currentPage + 1; + + msg = msg.replace("{first_page}", "1" ) + .replace("{prior_page}", Integer.toString(priorPage) ) + .replace("{current_page}", Integer.toString(currentPage)) + .replace("{next_page}", Integer.toString(nextPage)) + .replace("{last_page}", Integer.toString(maxPage)) + ; + + return msg; + } + protected String guiPageToolsCloseMsg( int currentPage, int maxPage ) { + + String msg = Prison.get().getLocaleManager() + .getLocalizable( "core_gui__page_tools_close" ) + .localize(); + + return formmatPageToolsPlaceholders( msg, currentPage, maxPage ); + } + protected String guiPageToolsFirstPageMsg( int currentPage, int maxPage ) { + + String msg = Prison.get().getLocaleManager() + .getLocalizable( "core_gui__page_tools_first_page" ) + .localize(); + + return formmatPageToolsPlaceholders( msg, currentPage, maxPage ); + } + protected String guiPageToolsPriorPageMsg( int currentPage, int maxPage ) { + + String msg = Prison.get().getLocaleManager() + .getLocalizable( "core_gui__page_tools_prior_page" ) + .localize(); + + return formmatPageToolsPlaceholders( msg, currentPage, maxPage ); + } + protected String guiPageToolsCurrentPageMsg( int currentPage, int maxPage ) { + + String msg = Prison.get().getLocaleManager() + .getLocalizable( "core_gui__page_tools_current_page" ) + .localize(); + + return formmatPageToolsPlaceholders( msg, currentPage, maxPage ); + } + protected String guiPageToolsNextPageMsg( int currentPage, int maxPage ) { + + String msg = Prison.get().getLocaleManager() + .getLocalizable( "core_gui__page_tools_next_page" ) + .localize(); + + return formmatPageToolsPlaceholders( msg, currentPage, maxPage ); + } + protected String guiPageToolsLastPageMsg( int currentPage, int maxPage ) { + + String msg = Prison.get().getLocaleManager() + .getLocalizable( "core_gui__page_tools_last_page" ) + .localize(); + + return formmatPageToolsPlaceholders( msg, currentPage, maxPage ); + } + + + + protected String guiPriceMsg( Double price ) { + + DecimalFormat dFmt = Prison.get().getDecimalFormat( "#,##0.00" ); + String value = price == null ? dFmt.format(0) : dFmt.format(price); + + return guiPriceMsg( value ); + } + protected String guiPriceMsg( Integer price ) { + + DecimalFormat dFmt = Prison.get().getDecimalFormatInt(); + String value = price == null ? dFmt.format(0) : dFmt.format(price); + + return guiPriceMsg( value ); + } + protected String guiPriceMsg( String price ) { + + return Prison.get().getLocaleManager() + .getLocalizable( "core_gui__price" ) + .withReplacements( price ) + .localize(); + } + + + protected String guiConfirmMsg( String prestigeName, double value ) { + + DecimalFormat dFmt = Prison.get().getDecimalFormat( "#,##0.0" ); + String valueStr = dFmt.format(value); + + return Prison.get().getLocaleManager() + .getLocalizable( "core_gui__confirm" ) + .withReplacements( prestigeName, valueStr ) + .localize(); + } + + + protected String guiDelayMsg( int value ) { + DecimalFormat dFmt = Prison.get().getDecimalFormatInt(); + String valueStr = dFmt.format(value); + + return guiDelayMsg( valueStr ); + } + protected String guiDelayMsg( String value ) { + + return Prison.get().getLocaleManager() + .getLocalizable( "core_gui__delay" ) + .withReplacements( value ) + .localize(); + } + + protected String guiMultiplierMsg( double value ) { + + DecimalFormat dFmt = Prison.get().getDecimalFormat( "#,##0.0" ); + String valueStr = dFmt.format(value); + + return guiMultiplierMsg( valueStr ); + } + protected String guiMultiplierMsg( String value ) { + + return Prison.get().getLocaleManager() + .getLocalizable( "core_gui__multiplier" ) + .withReplacements( value ) + .localize(); + } + + protected String guiValueMsg( String value ) { + + return Prison.get().getLocaleManager() + .getLocalizable( "core_gui__value" ) + .withReplacements( value ) + .localize(); + } + + protected String guiPermissionMsg( String prestigeName ) { + + return Prison.get().getLocaleManager() + .getLocalizable( "core_gui__permission" ) + .withReplacements( prestigeName ) + .localize(); + } + + protected String guiPrestigeNameMsg( String prestigeName ) { + + return Prison.get().getLocaleManager() + .getLocalizable( "core_gui__prestige_name" ) + .withReplacements( prestigeName ) + .localize(); + } + + +} diff --git a/prison-core/src/main/java/tech/mcprison/prison/gui/PrisonCoreGuiMessages.java b/prison-core/src/main/java/tech/mcprison/prison/gui/PrisonCoreGuiMessages.java index e9bdbbd4b..fa4d86723 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/gui/PrisonCoreGuiMessages.java +++ b/prison-core/src/main/java/tech/mcprison/prison/gui/PrisonCoreGuiMessages.java @@ -6,6 +6,9 @@ public class PrisonCoreGuiMessages { + public PrisonCoreGuiMessages() { + super(); + } protected String guiClickToDecreaseMsg() { return Prison.get().getLocaleManager() diff --git a/prison-core/src/main/java/tech/mcprison/prison/integration/IntegrationManager.java b/prison-core/src/main/java/tech/mcprison/prison/integration/IntegrationManager.java index 96d190737..68e01dbf5 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/integration/IntegrationManager.java +++ b/prison-core/src/main/java/tech/mcprison/prison/integration/IntegrationManager.java @@ -237,9 +237,10 @@ public List getIntegrationComponents(boolean isBasic) { for ( IntegrationType integrationType : IntegrationType.values() ) { - if ( integrationType == IntegrationType.WORLDGUARD ) { + + if ( integrationType == IntegrationType.WORLDGUARD ) { // Skip this integration type: - break; + continue; } boolean activeIntegration = false; diff --git a/prison-core/src/main/java/tech/mcprison/prison/integration/IntegrationType.java b/prison-core/src/main/java/tech/mcprison/prison/integration/IntegrationType.java index 9fb735d4a..3a8e4febe 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/integration/IntegrationType.java +++ b/prison-core/src/main/java/tech/mcprison/prison/integration/IntegrationType.java @@ -5,6 +5,11 @@ */ public enum IntegrationType { - ECONOMY, PERMISSION, PLACEHOLDER, WORLDGUARD, CUSTOMBLOCK + ECONOMY, + PERMISSION, + PLACEHOLDER, + CUSTOMBLOCK, + BACKPACK, + WORLDGUARD } 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 ddca20832..2d21896de 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 @@ -62,6 +62,7 @@ import tech.mcprison.prison.spigot.autofeatures.AutoManagerFeatures; import tech.mcprison.prison.spigot.autofeatures.events.AutoManagerBlockBreakEvents; import tech.mcprison.prison.spigot.backpacks.BackpacksListeners; +import tech.mcprison.prison.spigot.backpacks.BackpacksUtil; import tech.mcprison.prison.spigot.block.OnBlockBreakEventListener; import tech.mcprison.prison.spigot.bstats.PrisonBStats; import tech.mcprison.prison.spigot.commands.PrisonSpigotBackpackCommands; @@ -87,6 +88,7 @@ import tech.mcprison.prison.spigot.economies.TheNewEconomy; import tech.mcprison.prison.spigot.economies.VaultEconomy; import tech.mcprison.prison.spigot.gui.ListenersPrisonManager; +import tech.mcprison.prison.spigot.integrations.IntegrationMinepacksPlugin; import tech.mcprison.prison.spigot.permissions.LuckPermissions; import tech.mcprison.prison.spigot.permissions.LuckPerms5; import tech.mcprison.prison.spigot.permissions.VaultPermissions; @@ -975,6 +977,11 @@ private void initIntegrations() { registerIntegration(new CustomItems()); + + registerIntegration( IntegrationMinepacksPlugin.getInstance() ); + registerIntegration( BackpacksUtil.get() ); + + // registerIntegration(new WorldGuard6Integration()); // registerIntegration(new WorldGuard7Integration()); } 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 16f161361..8c1479617 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 @@ -404,7 +404,7 @@ public static int itemStackRemoveAll(Player player, XMaterial xMat ) { removed += itemStackRemoveAll( xMat, player.getInventory() ); - // Insert overflow in to Prison's backpack: + // Then remove from Prison's backpack: if ( SpigotPrison.getInstance().getConfig().getString("backpacks").equalsIgnoreCase("true")) { String id = null; @@ -414,7 +414,7 @@ public static int itemStackRemoveAll(Player player, XMaterial xMat ) { } - // Insert overflow in to Minepacks backpack: + // Then remove from Minepacks backpack: if ( IntegrationMinepacksPlugin.getInstance().isEnabled() ) { removed += IntegrationMinepacksPlugin.getInstance().itemStackRemoveAll(player, xMat); } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/backpacks/BackpacksUtil.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/backpacks/BackpacksUtil.java index 1140f941a..daac77071 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/backpacks/BackpacksUtil.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/backpacks/BackpacksUtil.java @@ -22,20 +22,24 @@ import com.cryptomorin.xseries.XMaterial; +import at.pcgamingfreaks.Minepacks.Bukkit.API.Backpack; import tech.mcprison.prison.Prison; -import tech.mcprison.prison.gui.PrisonCoreGuiMessages; +import tech.mcprison.prison.backpacks.PrisonCoreBackpackMessages; import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.SpigotUtil; 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.game.SpigotPlayer; +import tech.mcprison.prison.spigot.inventory.SpigotInventory; +import tech.mcprison.prison.spigot.sellall.SellAllData; +import tech.mcprison.prison.spigot.sellall.SellAllUtil; /** * @author GABRYCA * */ public class BackpacksUtil - extends PrisonCoreGuiMessages { + extends PrisonCoreBackpackMessages { private static BackpacksUtil instance; private Configuration backpacksConfig = SpigotPrison.getInstance().getBackpacksConfig(); @@ -46,6 +50,47 @@ public class BackpacksUtil private final Compatibility compat = SpigotCompatibility.getInstance(); private final int backpackDefaultSize = Integer.parseInt(backpacksConfig.getString("Options.BackPack_Default_Size")); + + private BackpacksUtil() { + super(); + + } + + + private static BackpacksUtil getInstance() { + if (instance == null && SpigotPrison.getInstance().getConfig().getString("backpacks") != null && SpigotPrison.getInstance().getConfig().getString("backpacks").equalsIgnoreCase("true")){ + instance = new BackpacksUtil(); + } + + return instance; + } + + @Override + public boolean hasIntegrated() { + return isEnabled(); + } + + /** + * Remove reference to Prison backpacks and then get a new instance, which will basically + * be similar to reloading the integration. + */ + @Override + public void disableIntegration() { + + + } + + @Override + public String getDisplayName() + { + return super.getDisplayName(); + } + + @Override + public String getPluginSourceURL() { + return "These backpacks are a part of prison."; + } + /** * Check if Backpacks's enabled. * */ @@ -94,7 +139,7 @@ public boolean reachedBackpacksLimit(Player p){ } /** - * Get SellAll instance. + * Get Backpack instance. * */ public static BackpacksUtil get() { return getInstance(); @@ -754,13 +799,15 @@ private boolean backpacksLimitSet(OfflinePlayer p, int limit) { // backpacksConfig = bpTemp.getFileBackpacksConfig(); // } - private static BackpacksUtil getInstance() { - if (instance == null && SpigotPrison.getInstance().getConfig().getString("backpacks") != null && SpigotPrison.getInstance().getConfig().getString("backpacks").equalsIgnoreCase("true")){ - instance = new BackpacksUtil(); - } - - return instance; - } + + // This NEEDS to be at the top of the class... it's that important. +// private static BackpacksUtil getInstance() { +// if (instance == null && SpigotPrison.getInstance().getConfig().getString("backpacks") != null && SpigotPrison.getInstance().getConfig().getString("backpacks").equalsIgnoreCase("true")){ +// instance = new BackpacksUtil(); +// } +// +// return instance; +// } private boolean checkOwnBackpack(Player p) { updateCachedBackpack(); @@ -1587,4 +1634,28 @@ private Player getOnlinePlayer(String name, String id) { } return null; } + + public List sellInventoryItems( Player player, double multiplier ) { + List soldItems = new ArrayList<>(); + + + if ( isEnabled() ) { + + // WARNING! This is WRONG! There is no way to tell what are valid IDs. + // So just using null for auto sell. Players may not want + // some backpacks to be used by autosell. And some players may + // want more than one backpack to autosell? + String id = null; + + Inventory inv = getBackpackOwn( player, id ); + + SpigotInventory sInventory = new SpigotInventory( inv ); + + soldItems.addAll( SellAllUtil.get().sellInventoryItems( sInventory, multiplier ) ); + + saveInventory(player, inv, id); + } + + return soldItems; + } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/integrations/IntegrationMinepacksPlugin.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/integrations/IntegrationMinepacksPlugin.java index 770516843..670c03796 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/integrations/IntegrationMinepacksPlugin.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/integrations/IntegrationMinepacksPlugin.java @@ -1,6 +1,8 @@ package tech.mcprison.prison.spigot.integrations; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import org.bukkit.Bukkit; import org.bukkit.entity.Player; @@ -12,29 +14,40 @@ import at.pcgamingfreaks.Minepacks.Bukkit.API.Backpack; import at.pcgamingfreaks.Minepacks.Bukkit.API.MinepacksPlugin; +import tech.mcprison.prison.integration.IntegrationCore; +import tech.mcprison.prison.integration.IntegrationType; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.spigot.SpigotUtil; import tech.mcprison.prison.spigot.block.SpigotItemStack; +import tech.mcprison.prison.spigot.inventory.SpigotInventory; +import tech.mcprison.prison.spigot.sellall.SellAllData; +import tech.mcprison.prison.spigot.sellall.SellAllUtil; public class IntegrationMinepacksPlugin + extends IntegrationCore { private static IntegrationMinepacksPlugin instance = null; private MinepacksPlugin minepacks = null; + /** + * Register as a BACKPACK integration. + */ private IntegrationMinepacksPlugin() { - super(); + super( "Minepacks", "Minepacks", IntegrationType.BACKPACK ); try { Plugin bukkitPlugin = Bukkit.getPluginManager().getPlugin("Minepacks"); if( bukkitPlugin instanceof MinepacksPlugin ) { this.minepacks = (MinepacksPlugin) bukkitPlugin; + + Output.get().logInfo( "&6Enabled Minepacks integration." ); } } catch ( Exception e ) { - Output.get().logWarn( "Unable to Minepacks integration.", e ); + Output.get().logWarn( "&dUnable to enable Minepacks integration.", e ); } } @@ -50,6 +63,7 @@ public static IntegrationMinepacksPlugin getInstance() { return instance; } + public boolean isEnabled() { return minepacks != null; } @@ -58,6 +72,33 @@ public MinepacksPlugin getMinepacks() { return minepacks; } + + @Override + public boolean hasIntegrated() { + return isEnabled(); + } + + /** + * Remove reference to Minepacks and then get a new instance, which will basically + * be similar to reloading the integration to Minepacks. + */ + @Override + public void disableIntegration() { + minepacks = null; + } + + @Override + public String getDisplayName() + { + return super.getDisplayName(); + } + + @Override + public String getPluginSourceURL() { + return "https://www.spigotmc.org/resources/minepacks-backpack-plugin-mc-1-7-1-21.19286/"; + } + + public HashMap addItems( Player player, HashMap items ) { @@ -206,6 +247,32 @@ public int itemStackRemoveAll(Player player, XMaterial xMat) { } return removed; } + + + public List sellInventoryItems( Player player, double multiplier ) { + List soldItems = new ArrayList<>(); + + + if ( isEnabled() ) { + Backpack bp = getMinepacks().getBackpackCachedOnly( player ); + + if ( bp != null ) { + + Inventory inv = bp.getInventory(); + + SpigotInventory sInventory = new SpigotInventory( inv ); + + soldItems.addAll( SellAllUtil.get().sellInventoryItems( sInventory, multiplier ) ); + + if ( soldItems.size() > 0 ) { + bp.setChanged(); + bp.save(); + } + } + } + + return soldItems; + } // private int itemCount(XMaterial source, Inventory inv ) { // int count = 0; 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 d0bccebe9..b946abb2d 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 @@ -34,12 +34,14 @@ 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.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; @@ -772,7 +774,19 @@ public List sellPlayerItems(Player p) { SpigotPlayerInventory spInventory = sPlayer.getSpigotPlayerInventory(); - return sellInventoryItems( spInventory, multiplier ); + List soldData = sellInventoryItems( spInventory, multiplier ); + + if ( isSellAllBackpackItemsEnabled && BackpacksUtil.isEnabled() ) { + BackpacksUtil bpUtil = BackpacksUtil.get(); + + soldData.addAll( bpUtil.sellInventoryItems( p, multiplier ) ); + } + + if ( isSellAllMinesBackpacksPluginEnabled && IntegrationMinepacksPlugin.getInstance().isEnabled() ) { + soldData.addAll( IntegrationMinepacksPlugin.getInstance().sellInventoryItems( p, multiplier ) ); + } + + return soldData; } /** @@ -828,7 +842,7 @@ public List sellPlayerItemStacks(Player p, } - private List sellInventoryItems( tech.mcprison.prison.internal.inventory.Inventory inventory, + public List sellInventoryItems( tech.mcprison.prison.internal.inventory.Inventory inventory, double multiplier ) { List soldItems = new ArrayList<>(); @@ -2642,7 +2656,8 @@ public boolean sellAllSell(Player p, if ( PrisonRanks.getInstance() != null && PrisonRanks.getInstance().isEnabled() ) { - RankPlayer rankPlayer = PrisonRanks.getInstance().getPlayerManager().getPlayer(sPlayer.getUUID(), sPlayer.getName()); + RankPlayer rankPlayer = sPlayer.getRankPlayer(); +// RankPlayer rankPlayer = PrisonRanks.getInstance().getPlayerManager().getPlayer(sPlayer.getUUID(), sPlayer.getName()); rankPlayer.addBalance(sellAllCurrency, money); From 758d8a9beaa1963d32ac01c010651843a15c8b86 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 13 Aug 2024 22:28:21 -0400 Subject: [PATCH 123/323] Sellall: Enchantments: Prevent items with enchantments from being sold. Unlike lore, there is no way to bypass this. Sellall cannot sell anything that is enchanted. There was an issue that would "sell" enchanted items, but would not remove them from the inventory unless the player was holding it in their hands, which would allow the item to be sold multiple times. --- docs/changelog_v3.3.x.md | 5 ++++ .../prison/spigot/sellall/SellAllUtil.java | 24 ++++++++++++++----- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 19ed8199f..8ce3c661a 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-beta.18c 2024-08-13 +* **Sellall: Enchantments: Prevent items with enchantments from being sold.** +Unlike lore, there is no way to bypass this. Sellall cannot sell anything that is enchanted. +There was an issue that would "sell" enchanted items, but would not remove them from the inventory unless the player was holding it in their hands, which would allow the item to be sold multiple times. + + * **Integrations: Backpacks and prison versions reporting of integrations.** Fixed an issue with backpacks not being included in the sellall activity when they are enabled in the sellall settings. Added BACKPACKs to the IntegrationType and made changes to include the listings of all backpacks and their status in the startup information and prison versions. 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 b946abb2d..47bcb6f6f 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 @@ -922,13 +922,25 @@ private SellAllData sellItemStack( SpigotItemStack iStack, double multiplier ) { if ( pBlockSellAll != null ) { - if ( !pBlockSellAll.isLoreAllowed() && iStack.getLore().size() > 0 ) { - String msg = String.format( - "Sellall: Cannot sell item '%s' (qty %s) because it has lore which is not allowed. ", - iStack.getDisplayName(), - Integer.toString( iStack.getAmount() ) - ); + if ( iStack != null && iStack.getEnchantments() != null && iStack.getEnchantments().size() > 0 ) { + // Cannot sell enchanted items: if ( Output.get().isDebug() ) { + String msg = String.format( + "Sellall: Cannot sell item '%s' (qty %s) because it has enchantments which is not allowed. ", + (iStack.getDisplayName() != null ? iStack.getDisplayName() : iStack.getName() ), + Integer.toString( iStack.getAmount() ) + ); + Output.get().logInfo( msg ); + } + } + + else if ( !pBlockSellAll.isLoreAllowed() && iStack.getLore().size() > 0 ) { + if ( Output.get().isDebug() ) { + String msg = String.format( + "Sellall: Cannot sell item '%s' (qty %s) because it has lore which is not allowed. ", + (iStack.getDisplayName() != null ? iStack.getDisplayName() : iStack.getName() ), + Integer.toString( iStack.getAmount() ) + ); Output.get().logInfo( msg ); } From 693b70014673b24f51fca8ce18a1eb5d66e99710 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 14 Aug 2024 00:05:09 -0400 Subject: [PATCH 124/323] Prison backpacks: On the last commit for setting up the integrations for backpacks, I overlooked an issue when prison backpacks were disabled. This issue was fixed. It was causing a failure on startup which prevented prison from loading due to causing the integration manager to fail. --- docs/changelog_v3.3.x.md | 4 ++ .../prison/spigot/SpigotPlatform.java | 3 +- .../mcprison/prison/spigot/SpigotUtil.java | 2 +- .../spigot/backpacks/BackpacksUtil.java | 43 +++++++++++++------ .../gui/backpacks/BackpacksAdminGUI.java | 6 ++- .../prison/spigot/sellall/SellAllUtil.java | 2 +- 6 files changed, 41 insertions(+), 19 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 8ce3c661a..5b010f040 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-beta.18c 2024-08-13 +* **Prison backpacks: On the last commit for setting up the integrations for backpacks, I overlooked an issue when prison backpacks were disabled.** +This issue was fixed. It was causing a failure on startup which prevented prison from loading due to causing the integration manager to fail. + + * **Sellall: Enchantments: Prevent items with enchantments from being sold.** Unlike lore, there is no way to bypass this. Sellall cannot sell anything that is enchanted. There was an issue that would "sell" enchanted items, but would not remove them from the inventory unless the player was holding it in their hands, which would allow the item to be sold multiple times. 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 85e526e99..674522219 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 @@ -3424,7 +3424,8 @@ public List getPlayerOldBackpacks( Player player ) { getPlayer( player.getName() ).orElse(null); - if ( sPlayer != null && getConfigBooleanFalse( "backpacks" ) && BackpacksUtil.isEnabled() ) { + if ( sPlayer != null && getConfigBooleanFalse( "backpacks" ) && + BackpacksUtil.getInstance().isEnabled() ) { BackpacksUtil backpackUtil = BackpacksUtil.get(); 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 8c1479617..75a8ba2bf 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 @@ -258,7 +258,7 @@ public static HashMap addItemToPlayerInventory( player.updateInventory(); // Insert overflow in to Prison's backpack: - if ( BackpacksUtil.isEnabled() ) { + if ( BackpacksUtil.getInstance().isEnabled() ) { BackpacksUtil bpUtil = BackpacksUtil.get(); if (overflow.size() > 0 && diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/backpacks/BackpacksUtil.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/backpacks/BackpacksUtil.java index daac77071..0d4cb278e 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/backpacks/BackpacksUtil.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/backpacks/BackpacksUtil.java @@ -22,7 +22,6 @@ import com.cryptomorin.xseries.XMaterial; -import at.pcgamingfreaks.Minepacks.Bukkit.API.Backpack; import tech.mcprison.prison.Prison; import tech.mcprison.prison.backpacks.PrisonCoreBackpackMessages; import tech.mcprison.prison.spigot.SpigotPrison; @@ -41,6 +40,8 @@ public class BackpacksUtil extends PrisonCoreBackpackMessages { + private boolean enabled = false; + private static BackpacksUtil instance; private Configuration backpacksConfig = SpigotPrison.getInstance().getBackpacksConfig(); private File backpacksFile = new File(SpigotPrison.getInstance().getDataFolder() + "/backpacks/backpacksData.yml"); @@ -54,18 +55,42 @@ public class BackpacksUtil private BackpacksUtil() { super(); + + String backpackConfig = SpigotPrison.getInstance().getConfig().getString("backpacks"); + + this.enabled = backpackConfig != null && + backpackConfig.equalsIgnoreCase("true"); + } - private static BackpacksUtil getInstance() { - if (instance == null && SpigotPrison.getInstance().getConfig().getString("backpacks") != null && SpigotPrison.getInstance().getConfig().getString("backpacks").equalsIgnoreCase("true")){ + public static BackpacksUtil getInstance() { + if (instance == null ){ instance = new BackpacksUtil(); } return instance; } - @Override + +// /** +// * Check if Backpacks's enabled. +// * */ +// public static boolean isPrisonBackpacksEnabled(){ +// +// return getInstance().isEnabled(); +// } + + + public boolean isEnabled() { + return enabled; + } + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + + @Override public boolean hasIntegrated() { return isEnabled(); } @@ -90,16 +115,6 @@ public String getDisplayName() public String getPluginSourceURL() { return "These backpacks are a part of prison."; } - - /** - * Check if Backpacks's enabled. - * */ - public static boolean isEnabled(){ - if (SpigotPrison.getInstance().getConfig().getString("backpacks") != null){ - return SpigotPrison.getInstance().getConfig().getString("backpacks").equalsIgnoreCase("true"); - } - return false; - } /** * Get Backpacks DATA config. diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/backpacks/BackpacksAdminGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/backpacks/BackpacksAdminGUI.java index e43c2572e..b350f3653 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/backpacks/BackpacksAdminGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/backpacks/BackpacksAdminGUI.java @@ -1,7 +1,9 @@ package tech.mcprison.prison.spigot.gui.backpacks; -import com.cryptomorin.xseries.XMaterial; import org.bukkit.entity.Player; + +import com.cryptomorin.xseries.XMaterial; + import tech.mcprison.prison.output.Output; import tech.mcprison.prison.spigot.backpacks.BackpacksUtil; import tech.mcprison.prison.spigot.configs.MessagesConfig; @@ -24,7 +26,7 @@ public BackpacksAdminGUI(Player p) { public void open(){ - if (!BackpacksUtil.isEnabled()){ + if (!BackpacksUtil.getInstance().isEnabled()){ Output.get().sendWarn(new SpigotPlayer(p), messages.getString(MessagesConfig.StringID.spigot_message_gui_backpack_disabled)); p.closeInventory(); return; 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 47bcb6f6f..fe2804723 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 @@ -776,7 +776,7 @@ public List sellPlayerItems(Player p) { List soldData = sellInventoryItems( spInventory, multiplier ); - if ( isSellAllBackpackItemsEnabled && BackpacksUtil.isEnabled() ) { + if ( isSellAllBackpackItemsEnabled && BackpacksUtil.getInstance().isEnabled() ) { BackpacksUtil bpUtil = BackpacksUtil.get(); soldData.addAll( bpUtil.sellInventoryItems( p, multiplier ) ); From 0e6d259e74b2437f797dbaf1e6c83ae65dbb0822 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 15 Aug 2024 03:53:30 -0400 Subject: [PATCH 125/323] BlockBreak: RevEnchants was firing one of their multi-block break events with NO blocks include. Had to handle a null condition and cancel the event. --- docs/changelog_v3.3.x.md | 6 +++++- .../events/AutoManagerRevEnchantsExplosiveEvent.java | 5 ++++- .../events/AutoManagerRevEnchantsJackHammerEvent.java | 5 ++++- .../prison/spigot/block/OnBlockBreakMines.java | 11 ++++++++++- 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 5b010f040..8d48bb0f7 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-beta.18c 2024-08-13 +# 3.3.0-beta.18c 2024-08-15 + + +* **BlockBreak: RevEnchants was firing one of their multi-block break events with NO blocks include. ** +Had to handle a null condition and cancel the event. * **Prison backpacks: On the last commit for setting up the integrations for backpacks, I overlooked an issue when prison backpacks were disabled.** 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 595c9291a..2231fb2b0 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 @@ -275,8 +275,11 @@ public void handleRevEnchantsExplosiveEvent( ExplosiveEvent e, BlockBreakPriorit // 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. + + Block bBlock = e.getBlocks().size() >= 0 ? e.getBlocks().get( 0 ) : null; + MinesEventResults eventResults = ignoreMinesBlockBreakEvent( e, - e.getPlayer(), e.getBlocks().get( 0 ), + e.getPlayer(), bBlock, bbPriority, true ); if ( eventResults.isIgnoreEvent() ) { 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 6af193697..cadc4736f 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 @@ -283,8 +283,11 @@ public void handleRevEnchantsJackHammerEvent( JackHammerEvent e, BlockBreakPrior // 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. + + Block bBlock = e.getBlocks().size() >= 0 ? e.getBlocks().get( 0 ) : null; + MinesEventResults eventResults = ignoreMinesBlockBreakEvent( e, - e.getPlayer(), e.getBlocks().get( 0 ), + e.getPlayer(), bBlock, bbPriority, true ); if ( eventResults.isIgnoreEvent() ) { 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 94ab42dab..f37715d60 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 @@ -39,6 +39,7 @@ public class OnBlockBreakMines enum EventResultsReasons { result_reason_not_yet_set, results_passed, + cancel_event__block_is_null, cancel_event__block_is_locked, ignore_event__block_is_not_in_a_mine, cancel_event__mine_mutex__mine_resetting, @@ -299,7 +300,15 @@ protected MinesEventResults ignoreMinesBlockBreakEvent( Player player, SpigotBlock sBlock = SpigotBlock.getSpigotBlock( block ); results.setSpigotBlock( sBlock ); - if ( BlockUtils.getInstance().isUnbreakable( sBlock ) ) { + if ( block == null ) { + + results.setResultsReason( EventResultsReasons.cancel_event__block_is_null); + + results.setCancelEvent( true ); + results.setIgnoreEvent( true ); + } + + else if ( BlockUtils.getInstance().isUnbreakable( sBlock ) ) { results.setResultsReason( EventResultsReasons.cancel_event__block_is_locked ); results.setCancelEvent( true ); From e36cb44dea2d02baac14fa715d971cb4925f7b1e Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 15 Aug 2024 03:56:17 -0400 Subject: [PATCH 126/323] AutoFeatures: Add support for using RevEnchant's fortune enchantment level using NBT data. Not 100% this works because I cannot test it since I do not own the RevEnchants plugin. --- docs/changelog_v3.3.x.md | 5 ++ .../autofeatures/AutoFeaturesFileConfig.java | 2 + .../prison/spigot/SpigotPlatform.java | 5 ++ .../autofeatures/AutoManagerFeatures.java | 52 ++++++++++++++++++- .../prison/spigot/nbt/PrisonNBTUtil.java | 34 ++++++++++++ 5 files changed, 96 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 8d48bb0f7..b7c7a2129 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-beta.18c 2024-08-15 +* **AutoFeatures: Add support for using RevEnchant's fortune enchantment level using NBT data.** +Not 100% this works because I cannot test it since I do not own the RevEnchants plugin. + + + * **BlockBreak: RevEnchants was firing one of their multi-block break events with NO blocks include. ** Had to handle a null condition and cancel the event. 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 6c9891d52..408039a9c 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 @@ -323,6 +323,8 @@ public enum AutoFeatures { isUseTokenEnchantsFortuneLevel(fortuneFeature, false ), + isUseRevEnchantsFortuneLevel(fortuneFeature, false ), + fortuneMultiplierGlobal(fortuneFeature, 1.0 ), fortuneMultiplierMax(fortuneFeature, 0 ), 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 674522219..07d956db7 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 @@ -2458,6 +2458,11 @@ public List getActiveFeatures( boolean showLaddersAndRanks ) { (isUseTEFortuneLevel ? "" : "+"), isUseTEFortuneLevel) ); + boolean isUseRevFortuneLevel = afw.isBoolean( AutoFeatures.isUseRevEnchantsFortuneLevel ); + results.add( String.format("%s. . Use RevEnchants Fortune Level:&b %b", + (isUseRevFortuneLevel ? "" : "+"), + isUseRevFortuneLevel) ); + 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)", 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 9e4c972bb..5fb9b6e0d 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 @@ -28,6 +28,7 @@ import com.vk2gpz.tokenenchant.api.ITokenEnchant; import com.vk2gpz.tokenenchant.api.TokenEnchantAPI; +import me.revils.revenchants.api.RevEnchantsApi; import tech.mcprison.prison.Prison; import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; import tech.mcprison.prison.autofeatures.AutoFeaturesWrapper; @@ -50,6 +51,7 @@ import tech.mcprison.prison.spigot.compat.SpigotCompatibility; import tech.mcprison.prison.spigot.game.SpigotHandlerList; import tech.mcprison.prison.spigot.game.SpigotPlayer; +import tech.mcprison.prison.spigot.nbt.PrisonNBTUtil; import tech.mcprison.prison.spigot.sellall.SellAllUtil; import tech.mcprison.prison.spigot.utils.tasks.PlayerAutoRankupTask; import tech.mcprison.prison.tasks.PrisonCommandTaskData; @@ -384,6 +386,7 @@ protected boolean hasFortune(SpigotItemStack itemInHand){ protected int getFortune(SpigotItemStack itemInHand, StringBuilder debugInfo ){ int fortLevel = 0; boolean usedTEFortune = false; + boolean usedRevEnchantsFortune = false; if ( isBoolean( AutoFeatures.isUseTokenEnchantsFortuneLevel ) && itemInHand != null && @@ -421,17 +424,62 @@ protected int getFortune(SpigotItemStack itemInHand, StringBuilder debugInfo ){ } catch ( Exception e2 ) { // Ignore - Cannot use TE + + debugInfo.append( " &4WARNING: Feature enabled but TokenEnchants is not found.&3" ); } } - if ( !usedTEFortune ) { - debugInfo.append( " &4WARNING: Feature enabled but TE not found.&3" ); + debugInfo.append(")"); + } + + + if ( isBoolean( AutoFeatures.isUseRevEnchantsFortuneLevel ) && + itemInHand != null && + itemInHand.getBukkitStack() != null ) { + + debugInfo.append( " (useRevEnchantsFortuneLevel:"); + + try { + Class.forName( "me.revils.revenchants.api.RevEnchantApi", false, this.getClass().getClassLoader() ); + + boolean has1 = PrisonNBTUtil.hasNBTInt( itemInHand.getBukkitStack(), "tag"); + boolean has2 = PrisonNBTUtil.hasNBTInt( itemInHand.getBukkitStack(), "tag.Enchants"); + boolean has3 = PrisonNBTUtil.hasNBTInt( itemInHand.getBukkitStack(), "tag.Enchants.Fortune"); + + if ( RevEnchantsApi.isTool( itemInHand.getBukkitStack() ) && + PrisonNBTUtil.hasNBTInt( itemInHand.getBukkitStack(), "tag.Enchants.Fortune") ) { + + int fortRevEnchants = PrisonNBTUtil.getNBTInt( itemInHand.getBukkitStack(), "tag.Enchants.Fortune"); + + if ( fortRevEnchants > -1 ) { + + fortLevel = fortRevEnchants; + + debugInfo.append( "used RevEnchant NBT: level " ).append( fortLevel ); + } + else { + + debugInfo.append( "RevEnchantAPI returned -1 (no fortune) " ).append( fortLevel ); + } + + + usedRevEnchantsFortune = true; + } + } + catch ( Exception e ) { + // ignore: could not use RevEnchants + + debugInfo.append( " &4WARNING: Feature enabled but RevEnchants is not found.&3" ); + } debugInfo.append(")"); } + + + try { if ( !usedTEFortune && itemInHand != null && 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 abdc67c7f..7a2a19ca3 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 @@ -153,6 +153,40 @@ public static void setNBTBoolean( ItemStack bukkitStack, String key, boolean val } + public static boolean hasNBTInt( ItemStack bukkitStack, String key ) { + int results = -1; + + results = getNBTInt( bukkitStack, key ); + + return results != -1; + } + + + public static int getNBTInt( ItemStack bukkitStack, String key ) { + int results = -1; + + try { + Function gsFnc = nbt -> { + Integer value = nbt.getInteger(key); + +// if ( Output.get().isDebug() ) { +// Output.get().logInfo( "PrisonNBTUtil.getNBTString():ItemStack: %s", nbt.toString() ); +// } + return value; + }; + + results = NBT.get(bukkitStack, gsFnc ); + } + catch (Exception e) { + Output.get().logInfo( + "PrisonNBTUtil.getNBTInt(): Failure trying to use NBTs. " + + "Contact prison support. The NBT library may need to be updated. [%s]", + e.getMessage() + ); + } + + return results; + } public static boolean hasNBTString( Entity entity, String key ) { String results = null; From 8ff014888605881783c79b4b1ae7d59cbc2de115 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 17 Aug 2024 21:47:59 -0400 Subject: [PATCH 127/323] Gradle: Modified the gradle configs to "force" it to compile with java 1.8, which is what it needs to be for it to work with spigot 1.8 through 1.15 or so. --- docs/changelog_v3.3.x.md | 5 ++++- gradle/libs.versions.toml | 7 ++++++- prison-core/build.gradle | 18 ++++++++++++++++++ prison-mines/build.gradle | 17 +++++++++++++++++ prison-misc/build.gradle | 18 ++++++++++++++++++ prison-ranks/build.gradle | 18 ++++++++++++++++++ prison-sellall/build.gradle | 17 +++++++++++++++++ prison-spigot-alt/build.gradle | 18 ++++++++++++++++++ prison-spigot/build.gradle | 18 +++++++++++++++++- prison-worldguard6/build.gradle | 17 ++++++++++++++++- prison-worldguard7/build.gradle | 17 ++++++++++++++++- 11 files changed, 165 insertions(+), 5 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index b7c7a2129..85a6e3b71 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-beta.18c 2024-08-15 +# 3.3.0-beta.18c 2024-08-17 + + +* **Gradle: Modified the gradle configs to "force" it to compile with java 1.8, which is what it needs to be for it to work with spigot 1.8 through 1.15 or so.** * **AutoFeatures: Add support for using RevEnchant's fortune enchantment level using NBT data.** diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 8bd638cde..1f2602b45 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -13,7 +13,7 @@ # https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 # https://mvnrepository.com/artifact/com.google.guava/guava # -## NOTE: mavenrepository.com is not the offical repo. +## NOTE: mavenrepository.com is not the official repo. ## NOTE: This item-nbt MUST use the API and not the plugin version! ## Good: https://repo.codemc.io/service/rest/repository/browse/maven-public/de/tr7zw/item-nbt-api/ ## Bad?: https://repo.codemc.io/service/rest/repository/browse/maven-public/de/tr7zw/item-nbt-api-plugin/2.11.3/ @@ -78,6 +78,11 @@ spigotApi = { module = "org.spigotmc:spigot-api", version.ref = "spigotApi" } vault = { module = "com.github.MilkBowl:VaultAPI", version.ref = "vault" } + + +## VaultUnlocked does not stand by itself.. it's using the vault signatures, but has a vault2 package name: +##vaultUnlocked = { module = "com.github.MilkBowl:VaultUnlockedAPI", version.ref = "vaultUnlocked" } + xseries = { module = "com.github.cryptomorin:XSeries", version.ref = "xseries" } diff --git a/prison-core/build.gradle b/prison-core/build.gradle index 8deb786e6..d3ff451ae 100644 --- a/prison-core/build.gradle +++ b/prison-core/build.gradle @@ -20,6 +20,24 @@ compileJava.options.encoding = 'UTF-8' compileTestJava.options.encoding = "UTF-8" + +ext.targetArchiveClassifier = 'Java1.8' +//ext.targetArchiveClassifier = 'Java16' + +// Lists all versions of java that are available to the toolchain +// $ ./gradlew -q javaToolchains + +// Specify the java version's location as found in the javaToolchains. +// $ ./gradlew build -Dorg.gradle.java.home="C:\Program Files\Java\jdk1.8.0_291" + +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(8)) +// languageVersion.set(JavaLanguageVersion.of(16)) + } +} + + dependencies { implementation( libs.commons.lang3 ) diff --git a/prison-mines/build.gradle b/prison-mines/build.gradle index 5f24da4ac..ebf4282a5 100644 --- a/prison-mines/build.gradle +++ b/prison-mines/build.gradle @@ -5,6 +5,23 @@ group 'tech.mcprison' compileJava.options.encoding = 'UTF-8' compileTestJava.options.encoding = "UTF-8" + +ext.targetArchiveClassifier = 'Java1.8' +//ext.targetArchiveClassifier = 'Java16' + +// Lists all versions of java that are available to the toolchain +// $ ./gradlew -q javaToolchains + +// Specify the java version's location as found in the javaToolchains. +// $ ./gradlew build -Dorg.gradle.java.home="C:\Program Files\Java\jdk1.8.0_291" + +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(8)) +// languageVersion.set(JavaLanguageVersion.of(16)) + } +} + dependencies { implementation project(':prison-core') testImplementation group: 'junit', name: 'junit', version: '4.12' diff --git a/prison-misc/build.gradle b/prison-misc/build.gradle index f7695a752..af3456755 100644 --- a/prison-misc/build.gradle +++ b/prison-misc/build.gradle @@ -21,6 +21,24 @@ group 'tech.mcprison' compileJava.options.encoding = 'UTF-8' compileTestJava.options.encoding = "UTF-8" + +ext.targetArchiveClassifier = 'Java1.8' +//ext.targetArchiveClassifier = 'Java16' + +// Lists all versions of java that are available to the toolchain +// $ ./gradlew -q javaToolchains + +// Specify the java version's location as found in the javaToolchains. +// $ ./gradlew build -Dorg.gradle.java.home="C:\Program Files\Java\jdk1.8.0_291" + +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(8)) +// languageVersion.set(JavaLanguageVersion.of(16)) + } +} + + repositories { maven { diff --git a/prison-ranks/build.gradle b/prison-ranks/build.gradle index cc15db280..dd6a2a442 100644 --- a/prison-ranks/build.gradle +++ b/prison-ranks/build.gradle @@ -3,6 +3,24 @@ group 'tech.mcprison' compileJava.options.encoding = 'UTF-8' compileTestJava.options.encoding = "UTF-8" + +ext.targetArchiveClassifier = 'Java1.8' +//ext.targetArchiveClassifier = 'Java16' + +// Lists all versions of java that are available to the toolchain +// $ ./gradlew -q javaToolchains + +// Specify the java version's location as found in the javaToolchains. +// $ ./gradlew build -Dorg.gradle.java.home="C:\Program Files\Java\jdk1.8.0_291" + +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(8)) +// languageVersion.set(JavaLanguageVersion.of(16)) + } +} + + dependencies { implementation project(':prison-core') testImplementation group: 'junit', name: 'junit', version: '4.12' diff --git a/prison-sellall/build.gradle b/prison-sellall/build.gradle index 4b47bc2a0..6c6ebded1 100644 --- a/prison-sellall/build.gradle +++ b/prison-sellall/build.gradle @@ -23,6 +23,23 @@ compileJava.options.encoding = 'UTF-8' compileTestJava.options.encoding = "UTF-8" +ext.targetArchiveClassifier = 'Java1.8' +//ext.targetArchiveClassifier = 'Java16' + +// Lists all versions of java that are available to the toolchain +// $ ./gradlew -q javaToolchains + +// Specify the java version's location as found in the javaToolchains. +// $ ./gradlew build -Dorg.gradle.java.home="C:\Program Files\Java\jdk1.8.0_291" + +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(8)) +// languageVersion.set(JavaLanguageVersion.of(16)) + } +} + + dependencies { implementation project(':prison-core') implementation project(':prison-mines') diff --git a/prison-spigot-alt/build.gradle b/prison-spigot-alt/build.gradle index 255458369..8834fddd2 100644 --- a/prison-spigot-alt/build.gradle +++ b/prison-spigot-alt/build.gradle @@ -24,6 +24,24 @@ compileJava.options.encoding = 'UTF-8' compileTestJava.options.encoding = "UTF-8" +ext.targetArchiveClassifier = 'Java1.8' +//ext.targetArchiveClassifier = 'Java16' + +// Lists all versions of java that are available to the toolchain +// $ ./gradlew -q javaToolchains + +// Specify the java version's location as found in the javaToolchains. +// $ ./gradlew build -Dorg.gradle.java.home="C:\Program Files\Java\jdk1.8.0_291" + +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(8)) +// languageVersion.set(JavaLanguageVersion.of(16)) + } +} + + + // NOTE: The sourceCompatibility will be removed in gradle v9.x. // Not going to worry about this, since this sub-proect is not being used. // More info: diff --git a/prison-spigot/build.gradle b/prison-spigot/build.gradle index 2a6f8150e..b77687e21 100644 --- a/prison-spigot/build.gradle +++ b/prison-spigot/build.gradle @@ -32,7 +32,23 @@ group 'tech.mcprison' compileJava.options.encoding = 'UTF-8' compileTestJava.options.encoding = "UTF-8" -//sourceCompatibility = 1.8 + +ext.targetArchiveClassifier = 'Java1.8' +//ext.targetArchiveClassifier = 'Java16' + +// Lists all versions of java that are available to the toolchain +// $ ./gradlew -q javaToolchains + +// Specify the java version's location as found in the javaToolchains. +// $ ./gradlew build -Dorg.gradle.java.home="C:\Program Files\Java\jdk1.8.0_291" + +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(8)) +// languageVersion.set(JavaLanguageVersion.of(16)) + } +} + repositories { diff --git a/prison-worldguard6/build.gradle b/prison-worldguard6/build.gradle index 224f74b31..68a0a5551 100644 --- a/prison-worldguard6/build.gradle +++ b/prison-worldguard6/build.gradle @@ -23,7 +23,22 @@ apply plugin: 'java' compileJava.options.encoding = 'UTF-8' compileTestJava.options.encoding = "UTF-8" -//sourceCompatibility = 1.8 + +ext.targetArchiveClassifier = 'Java1.8' +//ext.targetArchiveClassifier = 'Java16' + +// Lists all versions of java that are available to the toolchain +// $ ./gradlew -q javaToolchains + +// Specify the java version's location as found in the javaToolchains. +// $ ./gradlew build -Dorg.gradle.java.home="C:\Program Files\Java\jdk1.8.0_291" + +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(8)) +// languageVersion.set(JavaLanguageVersion.of(16)) + } +} // https://www.spigotmc.org/wiki/spigot-gradle/ diff --git a/prison-worldguard7/build.gradle b/prison-worldguard7/build.gradle index c8b574c24..fdc02bb26 100644 --- a/prison-worldguard7/build.gradle +++ b/prison-worldguard7/build.gradle @@ -23,7 +23,22 @@ apply plugin: 'java' compileJava.options.encoding = 'UTF-8' compileTestJava.options.encoding = "UTF-8" -//sourceCompatibility = 1.8 + +ext.targetArchiveClassifier = 'Java1.8' +//ext.targetArchiveClassifier = 'Java16' + +// Lists all versions of java that are available to the toolchain +// $ ./gradlew -q javaToolchains + +// Specify the java version's location as found in the javaToolchains. +// $ ./gradlew build -Dorg.gradle.java.home="C:\Program Files\Java\jdk1.8.0_291" + +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(8)) +// languageVersion.set(JavaLanguageVersion.of(16)) + } +} // https://www.spigotmc.org/wiki/spigot-gradle/ From 33ce8a948d82c59719a0bc62ccab12b5450003d0 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 17 Aug 2024 21:58:05 -0400 Subject: [PATCH 128/323] PrisonEnchants update: Updated support for Pulsi's PrisonEnchants plugin. The structure of the API changed with v2.0. Another change happened with v2.2.1. Prison now supports all versions from v1.0.0, v2.x, and v2.2.1 and newer. Created a pseudo API class in the prison-misc project to be able to compile for all three versions of support. --- docs/changelog_v3.3.x.md | 5 + .../PrisonEnchants-API-v1.0__v2.jardesc | 16 +++ .../events/PEExplosionEvent.java | 118 ++++++++++++++++++ prison-spigot/lib/PrisonEnchants-API-1.0.jar | Bin 1479 -> 0 bytes ...Enchants-API-v1.0_v2.2.1___prison-misc.jar | Bin 0 -> 1965 bytes 5 files changed, 139 insertions(+) create mode 100644 prison-misc/PrisonEnchants-API-v1.0__v2.jardesc create mode 100644 prison-misc/src/main/java/me/pulsi_/prisonenchants/events/PEExplosionEvent.java delete mode 100644 prison-spigot/lib/PrisonEnchants-API-1.0.jar create mode 100644 prison-spigot/lib/PrisonEnchants-API-v1.0_v2.2.1___prison-misc.jar diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 85a6e3b71..95277b8df 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-beta.18c 2024-08-17 +* **PrisonEnchants update: Updated support for Pulsi's PrisonEnchants plugin.** +The structure of the API changed with v2.0. Another change happened with v2.2.1. +Prison now supports all versions from v1.0.0, v2.x, and v2.2.1 and newer. +Created a pseudo API class in the prison-misc project to be able to compile for all three versions of support. + * **Gradle: Modified the gradle configs to "force" it to compile with java 1.8, which is what it needs to be for it to work with spigot 1.8 through 1.15 or so.** diff --git a/prison-misc/PrisonEnchants-API-v1.0__v2.jardesc b/prison-misc/PrisonEnchants-API-v1.0__v2.jardesc new file mode 100644 index 000000000..d9a68db20 --- /dev/null +++ b/prison-misc/PrisonEnchants-API-v1.0__v2.jardesc @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/prison-misc/src/main/java/me/pulsi_/prisonenchants/events/PEExplosionEvent.java b/prison-misc/src/main/java/me/pulsi_/prisonenchants/events/PEExplosionEvent.java new file mode 100644 index 000000000..35008ec65 --- /dev/null +++ b/prison-misc/src/main/java/me/pulsi_/prisonenchants/events/PEExplosionEvent.java @@ -0,0 +1,118 @@ +package me.pulsi_.prisonenchants.events; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Location; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +/** + * Support for Prison Enchant's v1.0 and v2.0 of the API... + * + * + * + { + // PrisonEnchants-API-v1.0.0: + //me.pulsi_.prisonenchants.events.PEExplosionEvent + + PEExplosionEvent peEE = new PEExplosionEvent(); + Block block = peEE.getBlockBroken(); + String eventName = peEE.getEventName(); + List explodedBlocks = peEE.getExplodedBlocks(); + HandlerList handlers = peEE.getHandlers(); + HandlerList handlerList = peEE.getHandlerList(); + Player player = peEE.getPlayer(); + boolean async = peEE.isAsynchronous(); + boolean canceled = peEE.isCancelled(); + peEE.setCancelled(false); + + } + { + // PrisonEnchants-API-v2.2.0: + //me.pulsi_.prisonenchants.events.PEExplosionEvent + + PEExplosionEvent peEE = new PEExplosionEvent(); + List blocks = peEE.getBlocks(); + PEEnchant enchantSource = peEE.getEnchantSource(); // not needed + String eventName = peEE.getEventName(); + HandlerList handlers = peEE.getHandlers(); + HandlerList handlerList = peEE.getHandlerList(); + Player player = peEE.getPlayer(); + boolean async = peEE.isAsynchronous(); + boolean canceled = peEE.isCancelled(); + peEE.setBlocks( blocks ); + peEE.setCancelled(false); + } + { + // PrisonEnchants-API-v2.2.1: + //me.pulsi_.prisonenchants.events.PEExplosionEvent + NOTE: v2.2.1 adds the function getOrigin(); + + Location locationOfOriginalBlock = peEE.getOrigin(); + } + * + */ +public class PEExplosionEvent + extends Event { + + public String getEventName() { + return ""; + } + + /** + * PrisonEnchants v1.0: + * @return + */ + public Block getBlockBroken() { + Block results = null; + return results; + } + + /** + * PrisonEnchants v1.0: + * @return + */ + public List getExplodedBlocks() { + List results = new ArrayList<>(); + return results; + } + + /** + * PrisonEnchants v2.2: + * @return + */ + public List getBlocks() { + List results = new ArrayList<>(); + return results; + } + + public HandlerList getHandlers() { + return null; + } + public static HandlerList getHandlerList() { + return null; + } + + public Player getPlayer() { + return null; + } + + public Location getOrigin() { + return null; + } + +// public boolean isAsynchronous() { +// return true; +// } + + public boolean isCancelled() { + return true; + } + + public void setCancelled( boolean cancel ) { + } + +} diff --git a/prison-spigot/lib/PrisonEnchants-API-1.0.jar b/prison-spigot/lib/PrisonEnchants-API-1.0.jar deleted file mode 100644 index a5fc3fe07cbd936f49983d376ea8384faad09f01..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1479 zcmWIWW@h1HVBp|j=-`zLW&i>v5CH_tK%ASZ&&&{jQwdNbNJ&9yPH|>DipmLShDoBR zEGWt>&d*EDOU_8lD=EgSQ30RE)Us4;`ps1wCYb`AZ_B~JU`B-g09V(Ff}H%~%=|o8 zkcoQ9If=!^YeR1P2?vVAw#PLXIW-0?2+><~fp5Aai+(_5Lx@KX4`-W8+=(r=jS~}Z z`7C$YcVPZU$180v!uALHjouZf$=qU;@~oM;dH46Y?DaP{`_=#b_fPl$SDcZ~+@iHn z=Gn&rJxrpa^%z70|JYMXP@2Xz4g*osrB=BeP-OvEAU{}!)NPNZ%3`0T~WSQdlKIs z{|}QSw(7pDn>_t#`*Q6CS9V;U!jsN-WY(@C)yu_2yY4nwZ4^4J)#h<*USY~hzq`*| zHo5Abybx}n^KV&Q)RS+~dozO476fR%e6}x7`qB33KHJpJude6bxYz5h-pBB^lZLMM z6@2PL1eY99U%0~gNASESewCAopL)u%9yXRdzS3>?afYMkH9uc`EE%dlF~pg-XGJmZ zk}IujmtNH{KNb(+dB|#eR3Tx)t;Z%Bj$53+Xm<+oB=>5q@^0buVKNeGn$gqJ!Y9dD zsJJG0&5x}XS7R!hgYHaGKey1>C0$8jU1<2EX$loFv6_#hmFI1_V)F7)tuJSM@S)2k zOI0o|deRs&X~FV3Hq+l|7n*U!^Y{H1zgOR@&zxT72);?1PUT zKiuL?C{O-8C3?bpaTQNi&uw`j3np%Q{a~U$lK56m7 z%M>IhTVaFH=Zm5bt?0pLi~__AAPKU*4WBX4 qf(UFH1H|_rN1+!)a03~R5n~$GVky9zl?`MLD-b3zGBEhFfOr5{&K8LP diff --git a/prison-spigot/lib/PrisonEnchants-API-v1.0_v2.2.1___prison-misc.jar b/prison-spigot/lib/PrisonEnchants-API-v1.0_v2.2.1___prison-misc.jar new file mode 100644 index 0000000000000000000000000000000000000000..dcb730d7d002f0b8552c5aab81f5cc9567054201 GIT binary patch literal 1965 zcmbW2dpy(oAIHDO4kn$+mfU~KHOwWq2wCpdkcOk7b_(e*do<$Yfvn$}9GBy6I_bC- zF44+uOBzc$cK$dyJs!W`AH6=0&*O7>KOXPbYm9N-d5X=vv7n0whuDe?Zq}R&R!^3XgG15tmsy8R~3lm>+Y0JXv zn)iW8upNi&a&orl+2Wx5ni~@tKbgS2ZC$M=dG(rUBeuDT#Rxt$$!f0L8|bd6zg~tP z?ePDFBNINamcmsLwgl<@YA~P)b&nS9G<1Z#lN^**206i(>aOuydb%9`Xiayln;xxB za0Ca0D<0wKelKH3f5Bk-fh6U1SCgn3<-72+VCuEGMr9%PGrPM!( zpDz65w1%8hC^{UoK(Nejumt5dkin&fb#;BWQChd!-uB@$GZAfLi-^1zjfQqUiF3mE z&hq`Ru~$Pn?B{;)rvVK_Dw}7s(FkRf9{?AT?NX*Vjh;%>7ZGvN_xQ`9bu&v0zUQZw zWVC&6D9GDfsdsl^M+HXi(rYRBmEl{)i>9cPw(UagLiK|Wi#wQP>jSL8E|;piMO~wA z*hAl2RR@IEa@3;OS{6?1(?&(cn)`5JZ*83~{^#_XdM@T=wQovNw#b%Ze+U-a^k^it zCszaKuXQPq;SCw4YsQ@+Y=j9;&!kO|S(IZB5_>bi;Ek{tKAbG^-Cm%!*^vpoykor@ zaWk#+<*wn?J(jVq$d0Pg+NrZs#k%?3Bm%0pN$}Bi1+CD-M{Z=bw-_HM%i3Yy@}mA| zp|4a46mRVG#@h~Ix?|!H(j!HLcHSIgDHwY%{6gklVQeMsbJcqd_|E8{h~0DCm;&xe zWX^B%)UhCBc`;QwoNIIKP4`9xtssd?<@26{iPM0-@i-Otsdy`js7G4)6i zy9E_RCQNI0Tfd&mm>owK3m9&N`N<kDJ00y(%}Uh9OOeDIhDav>g_a3&oO!eHa3c-jf-5v%Gk1c_lzaFOQBH=Ttn! zEZO%8=R~gPn8{;pq$-Gd=!dR#bTkwz_clSnxS$Zz1 zk~fzVVg4*TT@dAZ3rw@T4L5(~TQF?8PnVfvZp?wV66gEdqNp@^+PS-^M%Ag~x)j{? zzU0!f>8hrvxsM-b6c#!$#}Yb%42nd7jtZ9rUY(*;HL^~JXe{J`O_5H=`g=n}S1wbB zQ!mi}7;!(aq&H*QLB!s_^M(H_zBUlD=MZgocjBYUCa0BwS(W~JJnXCyWK9N?%r+Hn zc6J@z2x=b~1F4r74X*JhIfgKWxKl7iIsPo2r>;9$mf=!$b+Y>9)Q-WCnmg~BZFN?6 zWz*Coj5=cOy2K z9CzobXM(#d~j9qt{mE@j}s3wIO3U9u)-_$ Date: Sat, 17 Aug 2024 22:05:07 -0400 Subject: [PATCH 129/323] PrisonEnchants update: Updated support for Pulsi's PrisonEnchants plugin. The structure of the API changed with v2.0. Another change happened with v2.2.1. Prison now supports all versions from v1.0.0, v2.x, and v2.2.1 and newer. Created a pseudo API class in the prison-misc project to be able to compile for all three versions of support. --- .../events/AutoManagerPrisonEnchants.java | 204 +++++++++++++++++- 1 file changed, 198 insertions(+), 6 deletions(-) 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 f3b5359fe..4e72d924d 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 @@ -1,6 +1,11 @@ package tech.mcprison.prison.spigot.autofeatures.events; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; + import org.bukkit.Bukkit; +import org.bukkit.Location; import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.event.Event; @@ -13,8 +18,8 @@ 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.autofeatures.AutoFeaturesWrapper; import tech.mcprison.prison.mines.features.MineBlockEvent.BlockEventType; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.spigot.SpigotPrison; @@ -22,12 +27,35 @@ import tech.mcprison.prison.spigot.autofeatures.AutoManagerFeatures; import tech.mcprison.prison.spigot.block.BlockBreakPriority; +/** + *

This supports Pulsi's plugin, PrisonEnchants. There are three different versions + * and prison supports them all. + *

+ * + *
    + *
  • v1.x - Older versions of PEExplosionEvent. + * Uses functions: getBlockBroken() and getExplodedBlocks().
  • + *
  • v2.0.0 through v2.2.0 - Uses functions: getBlocks(). Does not + * have the original broken block.
  • + *
  • v2.2.1 + - Uses functions: getBlocks() and + * + *
+ */ public class AutoManagerPrisonEnchants extends AutoManagerFeatures implements PrisonEventManager { + private PEExplosionEventVersion peApiVersion; + private BlockBreakPriority bbPriority; + public enum PEExplosionEventVersion { + undefined, + pev1_0_0, + pev2_0_0, + pev2_2_1; + } + public AutoManagerPrisonEnchants() { super(); } @@ -35,6 +63,8 @@ public AutoManagerPrisonEnchants() { public AutoManagerPrisonEnchants( BlockBreakPriority bbPriority ) { super(); + this.peApiVersion = PEExplosionEventVersion.undefined; + this.bbPriority = bbPriority; } @@ -70,7 +100,9 @@ public AutoManagerPEExplosiveEventListener( BlockBreakPriority bbPriority ) { @EventHandler(priority=EventPriority.NORMAL) public void onPrisonEnchantsExplosiveEvent( PEExplosionEvent e, BlockBreakPriority bbPriority ) { - if ( isDisabled( e.getBlockBroken().getLocation().getWorld().getName() ) || + Block block = getBlock( e ); + + if ( isDisabled( block.getLocation().getWorld().getName() ) || bbPriority.isDisabled() ) { return; } @@ -85,6 +117,7 @@ public void onPrisonEnchantsExplosiveEvent( PEExplosionEvent e, BlockBreakPriori } + @SuppressWarnings("unused") @Override public void initialize() { @@ -108,6 +141,86 @@ public void initialize() { Output.get().logInfo( "AutoManager: Trying to register Pulsi_'s PrisonEnchants" ); +// { +// // PrisonEnchants-API-v1.0.0: +// //me.pulsi_.prisonenchants.events.PEExplosionEvent +// +// PEExplosionEvent peEE = new PEExplosionEvent(); +// Block block = peEE.getBlockBroken(); +// String eventName = peEE.getEventName(); +// List explodedBlocks = peEE.getExplodedBlocks(); +// HandlerList handlers = peEE.getHandlers(); +// HandlerList handlerList = peEE.getHandlerList(); +// Player player = peEE.getPlayer(); +// boolean async = peEE.isAsynchronous(); +// boolean canceled = peEE.isCancelled(); +// peEE.setCancelled(false); +// +// } +// { +// // PrisonEnchants-API-v2.2.0: +// //me.pulsi_.prisonenchants.events.PEExplosionEvent +// +// PEExplosionEvent peEE = new PEExplosionEvent(); +// List blocks = peEE.getBlocks(); +// PEEnchant enchantSource = peEE.getEnchantSource(); // not needed +// String eventName = peEE.getEventName(); +// HandlerList handlers = peEE.getHandlers(); +// HandlerList handlerList = peEE.getHandlerList(); +// Player player = peEE.getPlayer(); +// boolean async = peEE.isAsynchronous(); +// boolean canceled = peEE.isCancelled(); +// peEE.setBlocks( blocks ); +// peEE.setCancelled(false); +// } +// { +// // PrisonEnchants-API-v2.2.1: +// //me.pulsi_.prisonenchants.events.PEExplosionEvent +// NOTE: v2.2.1 adds the function getOrigin(); +// +// Location locationOfOriginalBlock = peEE.getOrigin(); +// } + + + + + Class klass = PEExplosionEvent.class; + if ( hasMethod( "getBlockBroken", klass ) && + hasMethod( "getExplodedBlocks", klass ) ) { + + setPeApiVersion( PEExplosionEventVersion.pev1_0_0 ); + } + else if ( hasMethod( "getBlocks", klass ) && + !hasMethod( "getOrigin", klass ) ) { + + setPeApiVersion( PEExplosionEventVersion.pev2_0_0 ); + } + else if ( hasMethod( "getBlocks", klass ) && + hasMethod( "getOrigin", klass ) ) { + + setPeApiVersion( PEExplosionEventVersion.pev2_2_1 ); + } + + + String msg = ""; + if ( getPeApiVersion() == PEExplosionEventVersion.undefined ) { + msg = "&cWarning: AutoFeatures has been configured to use Pulsi's " + + "PrisonEnchant's PEExplosionEvent but the plugin is not " + + "loaded or active."; + } + else if ( getPeApiVersion() == PEExplosionEventVersion.pev2_2_1 ) { + msg = "&6PEExplosionEvent API based on v2.2.1 or newer has been found and registered."; + } + else { + msg = "&6PEExplosionEvent API has been found and registered, but it is " + + "out of date. &cPlease upgrade PrisonEnchants to the lastest release " + + "for best results. &66https://polymart.org/resource/prisonenchants.1434"; + } + + Output.get().logWarn( msg ); + + + if ( getBbPriority() != BlockBreakPriority.DISABLED ) { if ( bbPriority.isComponentCompound() ) { @@ -134,6 +247,71 @@ public void initialize() { } } + /** + *

Checks a Class to see if the given function exists. + * Based upon our own specific needs with this, we are just checking + * setters so no parameters need to be specified. + *

+ * + * @param methodName + * @param klass + * @return + */ + private boolean hasMethod( String methodName, Class klass ) { + boolean results = false; + + try { + Method method = klass.getMethod( methodName, (Class[]) null); + + results = ( method != null ); + } + catch (NoSuchMethodException | SecurityException e) { + // Ignore exceptions... + } + + return results; + } + + private Block getBlock( PEExplosionEvent event ) { + Block results = null; + + if ( getPeApiVersion() == PEExplosionEventVersion.pev1_0_0 ) { + + results = event.getBlockBroken(); + } + else if ( getPeApiVersion() == PEExplosionEventVersion.pev2_0_0 ) { + + results = event.getBlocks().size() > 0 ? + event.getBlocks().get(0) : null; + } + else if ( getPeApiVersion() == PEExplosionEventVersion.pev2_2_1 ) { + + Location bLocation = event.getOrigin(); + results = bLocation.getWorld().getBlockAt(bLocation); + } + + return results; + } + + private List getBlocks( PEExplosionEvent event ) { + List results = new ArrayList<>(); + + if ( getPeApiVersion() == PEExplosionEventVersion.pev1_0_0 ) { + + results.addAll( event.getExplodedBlocks() ); + } + else if ( getPeApiVersion() == PEExplosionEventVersion.pev2_0_0 ) { + + results.addAll( event.getBlocks().subList(1, event.getBlocks().size())); + } + else if ( getPeApiVersion() == PEExplosionEventVersion.pev2_2_1 ) { + + results.addAll( event.getBlocks() ); + } + + return results; + } + private void createListener(BlockBreakPriority bbPriority) { SpigotPrison prison = SpigotPrison.getInstance(); @@ -273,8 +451,12 @@ public void handlePEExplosionEvent( PEExplosionEvent e, BlockBreakPriority bbPri // 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. + + // NOTE: support for v1.0, v2.2, and v2.2.1 has different block structures: + Block bBlock = getBlock( e ); + MinesEventResults eventResults = ignoreMinesBlockBreakEvent( e, - e.getPlayer(), e.getBlockBroken(), + e.getPlayer(), bBlock, bbPriority, true ); if ( eventResults.isIgnoreEvent() ) { @@ -327,12 +509,14 @@ public void handlePEExplosionEvent( PEExplosionEvent e, BlockBreakPriority bbPri return; } - pmEvent.setUnprocessedRawBlocks( e.getExplodedBlocks() ); + List blocks = getBlocks( e ); + + pmEvent.setUnprocessedRawBlocks( blocks ); // 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. + // removed, then it's removed within this function. removeEventTriggerBlocksFromExplosions( pmEvent ); @@ -417,5 +601,13 @@ protected int checkBonusXp( Player player, Block block, ItemStack item ) { return bonusXp; } - + + public PEExplosionEventVersion getPeApiVersion() { + return peApiVersion; + } + public void setPeApiVersion(PEExplosionEventVersion peApiVersion) { + this.peApiVersion = peApiVersion; + } + + } From 044b2525b99572585500376b1d2fbdeaafc791f2 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 18 Aug 2024 04:34:27 -0400 Subject: [PATCH 130/323] Ranks player: Added the capture and storage of the player's rank multiplier and changed the command '/ranks player' display these stored values for the multipliers when the player is offline. --- docs/changelog_v3.3.x.md | 7 ++- .../prison/ranks/data/RankPlayer.java | 59 ++++++++++++++++++- .../prison/ranks/commands/RanksCommands.java | 23 ++++++-- .../prison/ranks/data/RankPlayerFactory.java | 15 +++++ .../prison/spigot/game/SpigotPlayer.java | 26 ++++---- 5 files changed, 111 insertions(+), 19 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 95277b8df..d90ded941 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-beta.18c 2024-08-17 +# 3.3.0-beta.18c 2024-08-18 + + +* **Ranks player: Added the capture and storage of the player's rank multiplier and changed the command '/ranks player' display these stored values for the multipliers when the player is offline.** + + * **PrisonEnchants update: Updated support for Pulsi's PrisonEnchants plugin.** The structure of the API changed with v2.0. Another change happened with v2.2.1. 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 b4735bfdf..7a5b19144 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 @@ -140,6 +140,7 @@ public class RankPlayer private List permsSnapShot; + private double sellallMultiplierValue; private List sellallMultipliers; @@ -158,6 +159,8 @@ public RankPlayer() { this.permsSnapShot = new ArrayList<>(); + + this.sellallMultiplierValue = 1d; this.sellallMultipliers = new ArrayList<>(); @@ -1241,7 +1244,15 @@ public List getPermissions( String prefix ) { * multipliers that exists in the SpigotPlayer object. *

* - *

If the player is offline, then just set to a value of 1.0 so as + *

If the player is offline, then it will try to use the + * getSellallMultiplierValue() which may not be their current + * sellallMulitiplier, but it's the value when they were last + * online and when it was updated and saved within their + * RankPlayer object. + *

+ * + *

Otherwise, if the player is offline, then + * just set to a value of 1.0 so as * not to change any other value that may be used with this function. * If the player is offline, then there will be no inventory that can be * accessed and hence, none to sell, so a value of 1.0 should be fine. @@ -1255,6 +1266,15 @@ public double getSellAllMultiplier() { Player player = getPlatformPlayer(); if ( player != null ) { results = player.getSellAllMultiplier(); + + if ( results != getSellallMultiplierValue() ) { + + setSellallMultiplierValue( results ); + setDirty( true ); + } + } + else { + results = getSellallMultiplierValue(); } // // Optional player = Prison.get().getPlatform().getPlayer( uid ); @@ -2083,12 +2103,26 @@ public void setRankScorePenalty( double rankScorePenalty ) { this.rankScorePenalty = rankScorePenalty; } + /** + *

Returns the player's current sellallMultipliers listing if they are + * online. If they are not online, then this returns their last saved + * listing, which will not be their current listing since they could have + * changed since the player was last online. + *

+ * + */ @Override public List getSellAllMultiplierListings() { Player player = Prison.get().getPlatform().getPlayer(getUUID()).orElse(null); - return player == null ? new ArrayList<>() : player.getSellAllMultiplierListings(); + return player == null ? + + // NOTE: player is offline, so use the saved sellall multiplier list: + getSellallMultipliers() : + + // Online player: The actual live multiplier listings: + player.getSellAllMultiplierListings(); } @@ -2246,6 +2280,27 @@ public void setPermsSnapShot(List permsSnapShot) { this.permsSnapShot = permsSnapShot; } + + /** + * DO NOT USE! + * + * This is just a temporary and unofficial storage of the multiplier. + * This is not the current multiplier. And as such, should never be + * used as the current multiplier. + * + * This could be used in the same way that the + * getSellallMultipliers() listing is used... for references only + * when the player is offline. + * + * @return + */ + public double getSellallMultiplierValue() { + return sellallMultiplierValue; + } + public void setSellallMultiplierValue(double sellallMultiplierValue) { + this.sellallMultiplierValue = sellallMultiplierValue; + } + /** * DO NOT USE! * 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 e8891b651..54e441de5 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 @@ -48,7 +48,6 @@ import tech.mcprison.prison.ranks.data.RankPlayerName; import tech.mcprison.prison.ranks.data.TopNPlayers; import tech.mcprison.prison.ranks.managers.LadderManager; -import tech.mcprison.prison.ranks.managers.PlayerManager; import tech.mcprison.prison.ranks.managers.RankManager; import tech.mcprison.prison.ranks.managers.RankManager.RanksByLadderOptions; import tech.mcprison.prison.ranks.tasks.PlayerNewFileNameCheckAsyncTask; @@ -1632,7 +1631,7 @@ public void rankPlayer(CommandSender sender, SimpleDateFormat sdFmt = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ); - PlayerManager pm = PrisonRanks.getInstance().getPlayerManager(); + //PlayerManager pm = PrisonRanks.getInstance().getPlayerManager(); RankPlayer rankPlayer = player.getRankPlayer(); // RankPlayer rankPlayer = pm.getPlayer(player.getUUID(), player.getName()); @@ -1759,7 +1758,8 @@ public void rankPlayer(CommandSender sender, // sendToPlayerAndConsole( sender, msgOffline ); } - double sellallMultiplier = player.getSellAllMultiplier(); + + double sellallMultiplier = rankPlayer.getSellAllMultiplier(); String messageNotAccurrate = ranksPlayerNotAccurateMsg(); String messageSellallMultiplier = ranksPlayerSellallMultiplierMsg( pFmt.format( sellallMultiplier ), @@ -1767,9 +1767,19 @@ public void rankPlayer(CommandSender sender, msgs.add( messageSellallMultiplier ); // sendToPlayerAndConsole( sender, messageSellallMultiplier ); - List sellallDetails = player.getSellAllMultiplierListings(); + + // Warning, if the player is offline, then the list of multiplier details + // will come from their saved listings from when they were last + // on the server, and they may not be their current listings. + List sellallDetails = + isOnline ? + player.getSellAllMultiplierListings() : + rankPlayer.getSellallMultipliers(); + + for (String sellallDetail : sellallDetails) { - msgs.add( " " + sellallDetail ); + msgs.add( " " + sellallDetail + (!isOnline ? " " + + messageNotAccurrate : "") ); } @@ -1924,7 +1934,8 @@ public void rankPlayer(CommandSender sender, // player.hasPermission( "prison.mines.a" ) ); - List permissionIntegrations = PrisonAPI.getIntegrationManager().getAllForType( IntegrationType.PERMISSION ); + List permissionIntegrations = + PrisonAPI.getIntegrationManager().getAllForType( IntegrationType.PERMISSION ); for ( Integration pIntegration : permissionIntegrations ) { if ( pIntegration instanceof PermissionIntegration ) { diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactory.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactory.java index 8bbec5491..4177dadcc 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactory.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactory.java @@ -157,6 +157,11 @@ public RankPlayer createRankPlayer(Document document) { rankPlayer.setPermsSnapShot( perms ); } + + if ( document.get("sellallMultiplier") != null ) { + double multValue = (Double) document.get("sellallMultiplier"); + rankPlayer.setSellallMultiplierValue( multValue ); + } if ( document.get("sellallMultipliers") != null ) { List mults = (List) document.get("sellallMultipliers"); @@ -262,6 +267,16 @@ public static Document toDocument( RankPlayer rankPlayer ) { } ret.put( "permsSnapShot", perms ); + + double multValue = 1d; + if ( sPlayer != null && sPlayer.isOnline() ) { + multValue = sPlayer.getSellAllMultiplier(); + } + else { + // Otherwise since offline, save the existing list of multipliers: + multValue = rankPlayer.getSellallMultiplierValue(); + } + ret.put( "sellallMultiplier", multValue ); List multipliers = new ArrayList<>(); if ( sPlayer != null && sPlayer.isOnline() ) { 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 b2cb656b8..2f93c1ba0 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 @@ -975,7 +975,7 @@ public boolean isAutoSellEnabled( StringBuilder debugInfo ) { SellAllUtil.get().isAutoSellEnabled ) { if ( SellAllUtil.get().isAutoSellPerUserToggleable ) { - debugInfo.append( "(sellallEnabled:userToggleable)" ); + debugInfo.append( "(&7sellallEnabled:userToggleable&3)" ); // boolean isAutoSellPerUserToggleable = SellAllUtil.get().isAutoSellPerUserToggleable; @@ -983,9 +983,10 @@ public boolean isAutoSellEnabled( StringBuilder debugInfo ) { SellAllUtil.get().isSellallPlayerUserToggleEnabled( getWrapper() ); if ( debugInfo != null ) { - debugInfo.append( "(autosellPlayerToggled: " ) + debugInfo.append( "(&7autosellPlayerToggled&3: " ) .append( Output.get().getColorCodeWarning() ) - .append( isPlayerAutoSellTurnedOn ? "enabled" : "disabled" ) + .append( isPlayerAutoSellTurnedOn ? "enabled" : + Output.get().getColorCodeError() + "disabled:" + Output.get().getColorCodeDebug() ) .append( Output.get().getColorCodeDebug() ) .append( ")"); } @@ -1003,7 +1004,7 @@ public boolean isAutoSellEnabled( StringBuilder debugInfo ) { } else { - debugInfo.append( "(autosell" ) + debugInfo.append( "(autosell " ) .append( Output.get().getColorCodeWarning() ) .append( "Enabled" ) .append( Output.get().getColorCodeDebug() ) @@ -1013,7 +1014,7 @@ public boolean isAutoSellEnabled( StringBuilder debugInfo ) { } else { - debugInfo.append( "(autosell" ) + debugInfo.append( "(autosell " ) .append( Output.get().getColorCodeWarning() ) .append( "Disabled" ) .append( Output.get().getColorCodeDebug() ) @@ -1066,12 +1067,14 @@ private boolean isAutoSellByPermEnabledAutoFeatures( StringBuilder debugInfo ) { if ( !"disable".equalsIgnoreCase( perm ) && !"false".equalsIgnoreCase( perm ) ) { - debugInfo.append( "(autosellAutoFeaturesByPerm: " ) + debugInfo.append( "(&7autosellAutoFeaturesByPerm&3: " ) .append( Output.get().getColorCodeWarning() ) ; if ( isOp() ) { - debugInfo.append( "Op-Disabled" ); + debugInfo.append( + Output.get().getColorCodeError() + "Op-Disabled" + Output.get().getColorCodeDebug() + ); autoSellByPerm = false; } else { @@ -1125,7 +1128,7 @@ public boolean checkAutoSellTogglePerms( StringBuilder debugInfo ) { if ( SellAllUtil.get().isAutoSellPerUserToggleablePermEnabled ) { - debugInfo.append( "(autosellToggleByPerm: " ) + debugInfo.append( "(&7autosellToggleByPerm&3: " ) .append( Output.get().getColorCodeWarning() ) ; @@ -1135,7 +1138,9 @@ public boolean checkAutoSellTogglePerms( StringBuilder debugInfo ) { !"false".equalsIgnoreCase( perm ) ) { if ( isOp() ) { - debugInfo.append( "Op-Disabled" ); + debugInfo.append( + Output.get().getColorCodeError() + "Op-Disabled:" + Output.get().getColorCodeDebug() + ); results = false; } @@ -1143,7 +1148,8 @@ public boolean checkAutoSellTogglePerms( StringBuilder debugInfo ) { results = hasPermission( perm ); - debugInfo.append( results ? "hasPerm" : "noPerm" ); + debugInfo.append( results ? "hasPerm" : + Output.get().getColorCodeError() + "noPerm" + Output.get().getColorCodeDebug() ); } } From 6a7b66ba04ff3c1c93e3ac06cbd8f8913118f95b Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 23 Aug 2024 04:16:30 -0400 Subject: [PATCH 131/323] Sellall multipliers: Fixes some of the problems with sellall multipliers so they can work better when the player is offline. This will now use the snapshot of the player's perms as they were when they were last online. This helps to ensure better accuracy when bukkit will not provide perms when the player is not online. --- docs/changelog_v3.3.x.md | 6 +- .../prison/internal/PlayerPermissions.java | 4 + .../prison/ranks/data/RankPlayer.java | 33 ++- .../java/tech/mcprison/prison/TestPlayer.java | 31 +- .../prison/ranks/commands/RanksCommands.java | 20 +- .../spigot/game/SpigotCommandSender.java | 48 +++- .../spigot/game/SpigotOfflinePlayer.java | 36 ++- .../prison/spigot/sellall/SellAllUtil.java | 272 ++++++++++++++++-- 8 files changed, 404 insertions(+), 46 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index d90ded941..23ed3aeef 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-beta.18c 2024-08-18 +# 3.3.0-beta.18c 2024-08-23 + + +* **Sellall multipliers: Fixes some of the problems with sellall multipliers so they can work better when the player is offline.** +This will now use the snapshot of the player's perms as they were when they were last online. This helps to ensure better accuracy when bukkit will not provide perms when the player is not online. * **Ranks player: Added the capture and storage of the player's rank multiplier and changed the command '/ranks player' display these stored values for the multipliers when the player is offline.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/PlayerPermissions.java b/prison-core/src/main/java/tech/mcprison/prison/internal/PlayerPermissions.java index 21d7566ba..a0aa24a4a 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/PlayerPermissions.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/PlayerPermissions.java @@ -28,9 +28,13 @@ public interface PlayerPermissions { public List getPermissions( String prefix ); + public List getPermissions( String prefix, List perms ); + public double getSellAllMultiplier(); + public double getSellAllMultiplierDebug(); + public List getPermissionsIntegrations( boolean detailed ); 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 7a5b19144..8fad9ad29 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 @@ -1206,6 +1206,13 @@ public Player getPlatformPlayer() { if ( oPlayer.isPresent() ) { player = oPlayer.get(); } + else { + oPlayer = Prison.get().getPlatform().getOfflinePlayer( uid ); + + if ( oPlayer.isPresent() ) { + player = oPlayer.get(); + } + } return player; } @@ -1232,12 +1239,17 @@ public List getPermissions() { @Override public List getPermissions( String prefix ) { - Player player = getPlatformPlayer(); - return (player == null ? new ArrayList<>() : player.getPermissions( prefix ) ); + + return getPermissions( prefix, getPermissions() ); } - - + @Override + public List getPermissions( String prefix, List perms ) { + Player player = getPlatformPlayer(); + return (player == null ? new ArrayList<>() : + player.getPermissions( prefix, perms ) ); + + } /** *

This will called by the placeholders, so need to get the actual @@ -1285,6 +1297,19 @@ public double getSellAllMultiplier() { return results; } + + @Override + public double getSellAllMultiplierDebug() { + double results = 1.0; + + Player player = getPlatformPlayer(); + if ( player != null ) { + results = player.getSellAllMultiplierDebug(); + + } + + return results; + } diff --git a/prison-core/src/test/java/tech/mcprison/prison/TestPlayer.java b/prison-core/src/test/java/tech/mcprison/prison/TestPlayer.java index f70d21b23..aff060886 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/TestPlayer.java +++ b/prison-core/src/test/java/tech/mcprison/prison/TestPlayer.java @@ -187,15 +187,22 @@ public List getPermissions() { return results; } + @Override public List getPermissions( String prefix ) { + + return getPermissions( prefix, getPermissions() ); + } + + @Override + public List getPermissions( String prefix, List perms ) { List results = new ArrayList<>(); - for ( String perm : getPermissions() ) { - if ( perm.startsWith( prefix ) ) { - results.add( perm ); - } - } + for ( String perm : perms ) { + if ( perm.startsWith( prefix ) ) { + results.add( perm ); + } + } return results; } @@ -213,6 +220,16 @@ public double getSellAllMultiplier() { return 1.0; } + @Override + public double getSellAllMultiplierDebug() { + return 1.0; + } + + @Override + public List getSellAllMultiplierListings() { + return new ArrayList<>(); + } + @Override public void setTitle( String title, String subtitle, int fadeIn, int stay, int fadeOut ) { } @@ -254,10 +271,6 @@ public void incrementMinecraftStatsDropCount( Player player, String blockName, i } - @Override - public List getSellAllMultiplierListings() { - return new ArrayList<>(); - } @Override 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 54e441de5..9d8739417 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 @@ -1664,8 +1664,15 @@ public void rankPlayer(CommandSender sender, - String msg2 = String.format( " &7Rank Cost Multiplier: &f", - fFmt.format( rankPlayer.getSellAllMultiplier() )); + String msg2 = String.format( " &7Ranks with (Rank Cost Multiplier):"); +// double rankCostMultiplier = 0d; +// Set rpKeys = rankPlayer.getLadderRanks().keySet(); +// for ( RankLadder rpKey : rpKeys ) { +// PlayerRank pRank = rankPlayer.getLadderRanks().get( rpKey ); +// rankCostMultiplier += pRank.getRankMultiplier(); +// } +// String msg2 = String.format( " &7Rank Cost Multiplier: &f", +// fFmt.format( rankCostMultiplier )); msgs.add( msg2 ); @@ -1706,9 +1713,14 @@ public void rankPlayer(CommandSender sender, // PlayerRank nextPRank = nextRank == null ? null : // new PlayerRank( nextRank, pRank.getRankMultiplier() ); + double rankCostMultiplier = pRank.getRankMultiplier(); + String messageRank = ranksPlayerLadderInfoMsg( rankLadder.getName(), rank.getName() ); + + messageRank += " (" + fFmt.format( rankCostMultiplier ) + ") "; + if ( nextRank == null ) { messageRank += ranksPlayerLadderHighestRankMsg(); @@ -1723,6 +1735,7 @@ public void rankPlayer(CommandSender sender, } } + msgs.add( messageRank ); // sendToPlayerAndConsole( sender, messageRank ); } @@ -1759,7 +1772,8 @@ public void rankPlayer(CommandSender sender, } - double sellallMultiplier = rankPlayer.getSellAllMultiplier(); + double sellallMultiplier = rankPlayer.getSellAllMultiplierDebug(); + String messageNotAccurrate = ranksPlayerNotAccurateMsg(); String messageSellallMultiplier = ranksPlayerSellallMultiplierMsg( pFmt.format( sellallMultiplier ), 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 e26df1fed..275baa560 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 @@ -175,16 +175,35 @@ public List getPermissions() { @Override public List getPermissions( String prefix ) { + + return getPermissions( prefix, getPermissions() ); + } + + @Override + public List getPermissions( String prefix, List perms ) { List results = new ArrayList<>(); - for ( String perm : getPermissions() ) { - if ( perm.startsWith( prefix ) ) { - results.add( perm ); - } - } + for ( String perm : perms ) { + if ( perm.startsWith( prefix ) ) { + results.add( perm ); + } + } return results; } + +// @Override +// public List getPermissions( String prefix ) { +// List results = new ArrayList<>(); +// +// for ( String perm : getPermissions() ) { +// if ( perm.startsWith( prefix ) ) { +// results.add( perm ); +// } +// } +// +// return results; +// } @Override @@ -211,6 +230,25 @@ public double getSellAllMultiplier() { // return results; } + @Override + public double getSellAllMultiplierDebug() { + double results = 1.0; + + if ( isPlayer() ) { + + SellAllUtil sellall = SpigotPrison.getInstance().getSellAllUtil(); + + if ( sellall != null && getWrapper() != null ) { + + Player player = getPlatformPlayer(); + + results = sellall.getPlayerMultiplierDebug( player ); + } + } + + return results; + } + @Override public List getSellAllMultiplierListings() { List results = new ArrayList<>(); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java index cb44115f3..36e28a400 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java @@ -294,13 +294,19 @@ public List getPermissions() { @Override public List getPermissions( String prefix ) { + + return getPermissions( prefix, getPermissions() ); + } + + @Override + public List getPermissions( String prefix, List perms ) { List results = new ArrayList<>(); - for ( String perm : getPermissions() ) { - if ( perm.startsWith( prefix ) ) { - results.add( perm ); - } - } + for ( String perm : perms ) { + if ( perm.startsWith( prefix ) ) { + results.add( perm ); + } + } return results; } @@ -376,6 +382,26 @@ public double getSellAllMultiplier() { return results; } + @Override + public double getSellAllMultiplierDebug() { + double results = 1.0; + + // NOTE: isPlayer() is a check to see if it's tied to the bukkit Player object, of + // which offline player is not. But the sellall multiplier can still be called. +// if ( isPlayer() ) { + + SellAllUtil sellall = SpigotPrison.getInstance().getSellAllUtil(); + + if ( sellall != null && getWrapper() != null ) { + +// SpigotPlayer sPlayer = new SpigotPlayer( getWrapper() ); + + results = sellall.getPlayerMultiplierDebug( this ); + } +// } + + return results; + } public List getSellAllMultiplierListings() { List results = new ArrayList<>(); 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 fe2804723..e96233734 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 @@ -402,20 +402,26 @@ public HashMap getPrestigeMultipliers() { * * @return double. * */ - public double getPlayerMultiplier(Player p){ + public double getPlayerMultiplier(Player p) { + - if (!isSellAllMultiplierEnabled){ + if (!isSellAllMultiplierEnabled) { + return 1d; } - + + // long tPoint1 = System.nanoTime(); SpigotPlayer sPlayer = new SpigotPlayer(p); double multiplier = 0d; + double rankMultiplers = 0; + if ( PrisonRanks.getInstance() != null && PrisonRanks.getInstance().isEnabled() ) { + RankPlayer rPlayer = sPlayer.getRankPlayer(); Set keys = rPlayer.getLadderRanks().keySet(); @@ -424,15 +430,23 @@ public double getPlayerMultiplier(Player p){ String rankName = pRank.getRank().getName(); String multiplierRankString = sellAllConfig.getString("Multiplier." + rankName + ".MULTIPLIER"); + if (multiplierRankString != null && sellAllPrestigeMultipliers.containsKey( rankName )){ - multiplier += sellAllPrestigeMultipliers.get( rankName ); + + double rankMult = sellAllPrestigeMultipliers.get( rankName ); + rankMultiplers += rankMult; + } } } - if ( multiplier == 0 ) { + if ( rankMultiplers == 0 ) { multiplier = defaultMultiplier; } + else { + multiplier = rankMultiplers; + } + @@ -467,22 +481,39 @@ public double getPlayerMultiplier(Player p){ // } // Get Multiplier from multipliers permission's if there's any. - List perms = sPlayer.getPermissions("prison.sellall.multiplier."); + String permPattern = "prison.sellall.multiplier."; + List perms = sPlayer.getPermissions( permPattern ); + double multiplierExtraByPerms = 0; for (String multByPerm : perms) { - double multByPermDouble = Double.parseDouble(multByPerm.substring(26)); + String multStr = multByPerm.replace(permPattern, ""); + if ( multStr.contains( "_" ) ) { + multStr = multStr.substring( 0, multStr.indexOf("_") ); + } + + double multByPermDouble = Double.parseDouble( multStr ); + + boolean highest = multByPermDouble > multiplierExtraByPerms; if ( !isSellAllPermissionMultiplierOnlyHigherEnabled ) { multiplierExtraByPerms += multByPermDouble; + } - else if (multByPermDouble > multiplierExtraByPerms) { - multiplierExtraByPerms = multByPermDouble; + else { + + if ( highest ) { + multiplierExtraByPerms = multByPermDouble; + } } + } + + multiplier += multiplierExtraByPerms; - + + // long tPoint3 = System.nanoTime(); // DecimalFormat dFmt = Prison.get().getDecimalFormat( "0.0000" ); // String debugMsg = "{sellallMult::" + dFmt.format( multiplier ) + ":t1=" + @@ -492,6 +523,208 @@ else if (multByPermDouble > multiplierExtraByPerms) { return multiplier; } + + public double getPlayerMultiplierDebug( tech.mcprison.prison.internal.Player sPlayer ) { + + StringBuilder sb = new StringBuilder(); + + long tPoint1 = System.nanoTime(); + + sb.append( "&dCalculate Sellall Player Multipliers: &6" ) + .append( sPlayer.getName() ); + + if (!isSellAllMultiplierEnabled) { + + sb.append( " &cSellall Multipliers are disabled." ); + if ( Output.get().isDebug() ) { + Output.get().logInfo( sb.toString() ); + } + + return 1d; + } + + + sb.append( " &aEnabled &6DefaultMult: &c" ) + .append( defaultMultiplier ); + + if ( isSellAllPermissionMultiplierOnlyHigherEnabled ) { + sb.append( " &a(Use only the highest perm multiplier) " ); + } + + + + +// SpigotPlayer sPlayer = new SpigotPlayer(p); + + double multiplier = 0d; + double rankMultiplers = 0; + + sb.append( "&6RankMulipliers: &a[ &6" ); + + if ( PrisonRanks.getInstance() != null && PrisonRanks.getInstance().isEnabled() ) { + + + RankPlayer rPlayer = sPlayer.getRankPlayer(); + + Set keys = rPlayer.getLadderRanks().keySet(); + for (RankLadder ladderKey : keys) { + PlayerRank pRank = rPlayer.getLadderRanks().get(ladderKey); + String rankName = pRank.getRank().getName(); + + String multiplierRankString = sellAllConfig.getString("Multiplier." + rankName + ".MULTIPLIER"); + + if (multiplierRankString != null && sellAllPrestigeMultipliers.containsKey( rankName )){ + + double rankMult = sellAllPrestigeMultipliers.get( rankName ); + rankMultiplers += rankMult; + + sb.append( rankMult ).append( " " ); + } + } + } + + if ( rankMultiplers == 0 ) { + multiplier = defaultMultiplier; + sb.append( "&cnone " ); + } + else { + multiplier = rankMultiplers; + } + + sb.append( "&a] " ); + + + sb.append( "&6Base multiplier: &c" ) + .append( multiplier ).append( " " ); + + + + long tPoint2 = System.nanoTime(); + + // Get multiplier depending on Player + Prestige. NOTE that prestige multiplier will replace + // the actual default multiplier. +// if (module != null) { +// PrisonRanks rankPlugin = (PrisonRanks) module; +// if (rankPlugin.getPlayerManager().getPlayer(sPlayer) != null) { +// String playerRankName; +// try { +// +// RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); +// +// RankPlayer rankPlayer = rankPlugin.getPlayerManager().getPlayer(sPlayer); +// PlayerRank pRank = rankPlayer == null ? null : rankPlayerFactory.getRank( rankPlayer, "prestiges"); +// Rank rank = pRank == null ? null : pRank.getRank(); +// +// playerRankName = rank == null ? null : rank.getName(); +// } catch (NullPointerException ex) { +// playerRankName = null; +// } +// if (playerRankName != null) { +// String multiplierRankString = sellAllConfig.getString("Multiplier." + playerRankName + ".MULTIPLIER"); +// if (multiplierRankString != null && sellAllPrestigeMultipliers.containsKey(playerRankName)){ +// multiplier = sellAllPrestigeMultipliers.get(playerRankName); +// } +// } +// } +// } + + // Get Multiplier from multipliers permission's if there's any. + String permPattern = "prison.sellall.multiplier."; + List perms = sPlayer.getPermissions( permPattern ); + List debugRejected = new ArrayList<>(); + String debugHighest = null; + + if ( perms.size() == 0 && sPlayer.getRankPlayer() != null ) { + sb.append( "&cNoBukkkitPerms " ); + + perms.addAll( sPlayer.getPermissions( permPattern, sPlayer.getRankPlayer().getPermsSnapShot() )); + + if ( perms.size() > 0 ) { + + sb.append( "&c(Using &6" ); + sb.append( perms.size() ); + sb.append( " &csnapshotPerms) " ); + } + } + + sb.append( "&6PermissionMulipliers: &a[ &6" ); + + + double multiplierExtraByPerms = 0; + for (String multByPerm : perms) { + + String multStr = multByPerm.replace(permPattern, ""); + if ( multStr.contains( "_" ) ) { + multStr = multStr.substring( 0, multStr.indexOf("_") ); + } + + double multByPermDouble = Double.parseDouble( multStr ); + + boolean highest = multByPermDouble > multiplierExtraByPerms; + + String debugMult = multByPermDouble + ":" + multByPerm + "&r "; + + if ( !isSellAllPermissionMultiplierOnlyHigherEnabled ) { + multiplierExtraByPerms += multByPermDouble; + + sb.append( "&6" ) + .append( debugMult ); + } + else { + + if ( highest ) { + multiplierExtraByPerms = multByPermDouble; + + if ( debugHighest != null ) { + debugRejected.add( debugHighest ); + } + debugHighest = debugMult; + } + else { + debugRejected.add( debugMult ); + } + + } + + } + + if ( debugHighest != null ) { + sb.append( "&6" ) // Green + .append( debugHighest ); + } + + for (String rejected : debugRejected) { + sb.append( "&m&c" ) // Strike through & red + .append( rejected ); + } + + sb.append( " &a] " ); + + + multiplier += multiplierExtraByPerms; + + sb.append( "&6PermissionTotal: &a[ &6" ) + .append( multiplierExtraByPerms ) + .append( " &a] " ); + + sb.append( "&6TotalMultiplier: &a[ &6" ) + .append( multiplier ) + .append( " &a] " ); + + long tPoint3 = System.nanoTime(); + DecimalFormat dFmt = Prison.get().getDecimalFormat( "0.0000" ); + String debugMsg = " :t1=" + + dFmt.format( (tPoint2 - tPoint1)/1000000d ) + + " :t2=" + + dFmt.format( (tPoint3 - tPoint2)/1000000 ) + "}"; + + sb.append( debugMsg ); + + + Output.get().logInfo( sb.toString() ); + + return multiplier; + } public List getPlayerMultiplierList( Player p ) { @@ -679,7 +912,7 @@ else if (multByPermDouble > multiplierExtraByPerms) { public double getPlayerInventoryValue( SpigotPlayer sPlayer ) { double value = 0; - double multiplier = getPlayerMultiplier(sPlayer.getWrapper()); + double multiplier = sPlayer.getSellAllMultiplier(); SpigotPlayerInventory spInventory = sPlayer.getSpigotPlayerInventory(); @@ -693,7 +926,7 @@ public double getPlayerInventoryValue( SpigotPlayer sPlayer ) { public String getPlayerInventoryValueReport( SpigotPlayer sPlayer ) { - double multiplier = getPlayerMultiplier(sPlayer.getWrapper()); + double multiplier = sPlayer.getSellAllMultiplier(); SpigotPlayerInventory spInventory = sPlayer.getSpigotPlayerInventory(); @@ -706,7 +939,8 @@ public String getPlayerInventoryValueReport( SpigotPlayer sPlayer ) { public List getPlayerInventoryValueTransactions( SpigotPlayer sPlayer ) { - double multiplier = getPlayerMultiplier(sPlayer.getWrapper()); + double multiplier = sPlayer.getSellAllMultiplier(); +// double multiplier = getPlayerMultiplier(sPlayer.getWrapper()); SpigotPlayerInventory spInventory = sPlayer.getSpigotPlayerInventory(); @@ -717,9 +951,9 @@ public List getPlayerInventoryValueTransactions( SpigotPlayer sPlay - public double getItemStackValue( SpigotPlayer player, SpigotItemStack itemStack ) { + public double getItemStackValue( SpigotPlayer sPlayer, SpigotItemStack itemStack ) { - double multiplier = getPlayerMultiplier(player.getWrapper()); + double multiplier = sPlayer.getSellAllMultiplier(); SellAllData sad = sellItemStack( itemStack, multiplier ); @@ -728,7 +962,7 @@ public double getItemStackValue( SpigotPlayer player, SpigotItemStack itemStack public String getItemStackValueReport( SpigotPlayer sPlayer, SpigotItemStack itemStack ) { - double multiplier = getPlayerMultiplier(sPlayer.getWrapper()); + double multiplier = sPlayer.getSellAllMultiplier(); List soldItems = new ArrayList<>(); @@ -745,7 +979,7 @@ public String getItemStackValueReport( SpigotPlayer sPlayer, SpigotItemStack ite public List getItemStackValueTransactions( SpigotPlayer sPlayer, SpigotItemStack itemStack ) { - double multiplier = getPlayerMultiplier(sPlayer.getWrapper()); + double multiplier = sPlayer.getSellAllMultiplier(); List soldItems = new ArrayList<>(); @@ -768,10 +1002,10 @@ public List getItemStackValueTransactions( SpigotPlayer sPlayer, Sp */ public List sellPlayerItems(Player p) { - double multiplier = getPlayerMultiplier(p); - SpigotPlayer sPlayer = new SpigotPlayer( p ); + double multiplier = sPlayer.getSellAllMultiplier(); + SpigotPlayerInventory spInventory = sPlayer.getSpigotPlayerInventory(); List soldData = sellInventoryItems( spInventory, multiplier ); From 44765d77b11b76d2cbc4c70da053e7933cb9af92 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 23 Aug 2024 04:18:09 -0400 Subject: [PATCH 132/323] Upgrade XSeries to v11.2.1 from v11.2.0.1. This may help with a few issues with spigot v1.21.1 blocks. --- docs/changelog_v3.3.x.md | 5 +++++ gradle/libs.versions.toml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 23ed3aeef..e10c20c57 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-beta.18c 2024-08-23 +* **Upgrade XSeries to v11.2.1 from v11.2.0.1. ** +This may help with a few issues with spigot v1.21.1 blocks. + + + * **Sellall multipliers: Fixes some of the problems with sellall multipliers so they can work better when the player is offline.** This will now use the snapshot of the player's perms as they were when they were last online. This helps to ensure better accuracy when bukkit will not provide perms when the player is not online. diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1f2602b45..0b8045f7d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -34,7 +34,7 @@ commons-lang3 = "3.12.0" groovy = "3.0.9" gson = "2.10.1" spiget = "1.4.6-SNAPSHOT" -xseries = "11.2.0.1" +xseries = "11.2.1" junit = "4.12" guava = "31.1-jre" spigotApi = "1.13.2-R0.1-SNAPSHOT" From 63f1fe7c52e7573b56c088558f7d11c44d1be590 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 23 Aug 2024 04:22:41 -0400 Subject: [PATCH 133/323] Placeholders: Sellall multiplier: Fixed a few issues related to being offline and even OP'd. When offline, it was not able to get an active player object so it was bypassing the sellall multiplier calculations. Now it can work with bukkit's offline players. And its also able to fallback to using snapshot perms so the sellall calculations at least reflects what it was the last time the player was online. --- docs/changelog_v3.3.x.md | 5 ++++ .../prison/ranks/managers/PlayerManager.java | 29 ++++++++++++++----- .../spigot/game/SpigotOfflinePlayer.java | 23 ++++++++++----- .../prison/spigot/sellall/SellAllUtil.java | 15 ++++++++-- 4 files changed, 55 insertions(+), 17 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index e10c20c57..ed34aeddb 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-beta.18c 2024-08-23 +* **Placeholders: Sellall multiplier: Fixed a few issues related to being offline and even OP'd. +When offline, it was not able to get an active player object so it was bypassing the sellall multiplier calculations.** +Now it can work with bukkit's offline players. And its also able to fallback to using snapshot perms so the sellall calculations at least reflects what it was the last time the player was online. + + * **Upgrade XSeries to v11.2.1 from v11.2.0.1. ** This may help with a few issues with spigot v1.21.1 blocks. diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java index 0850a2589..4b7362261 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java @@ -1525,15 +1525,28 @@ public String getPlayerNextRankTag( RankPlayer rankPlayer, String ladderName ) { private String getPlayerSellallMultiplier( RankPlayer rankPlayer, PlaceholderAttributeNumberFormat attributeNFormat ) { - String results; - double multiplier = rankPlayer.getSellAllMultiplier(); - if ( attributeNFormat != null ) { - - results = attributeNFormat.format( multiplier ); - } - else { - results = Double.toString( multiplier ); + String results = ""; + + UUID pUuid = rankPlayer.getUUID(); + + Player player = + Prison.get().getPlatform().getPlayer( pUuid ).orElse( + Prison.get().getPlatform().getOfflinePlayer( pUuid ).orElse(null) + ); + + if ( player != null ) { + + double multiplier = player.getSellAllMultiplier(); + + if ( attributeNFormat != null ) { + + results = attributeNFormat.format( multiplier ); + } + else { + results = Double.toString( multiplier ); + } } + return results; } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java index 36e28a400..6b6d56cbf 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java @@ -371,13 +371,22 @@ public List getPermissionsIntegrations( boolean detailed ) { public double getSellAllMultiplier() { double results = 1.0; - SpigotPlayer sPlayer = null; - - if ( getWrapper().getPlayer() != null ) { - sPlayer = new SpigotPlayer( getWrapper().getPlayer() ); - - results = sPlayer.getSellAllMultiplier(); - } + SellAllUtil sellall = SpigotPrison.getInstance().getSellAllUtil(); + + if ( sellall != null && getWrapper() != null ) { + +// SpigotPlayer sPlayer = new SpigotPlayer( getWrapper() ); + + results = sellall.getPlayerMultiplier( this ); + } + +// SpigotPlayer sPlayer = null; +// +// if ( getWrapper() != null ) { +// sPlayer = new SpigotPlayer( getWrapper() ); +// +// results = sPlayer.getSellAllMultiplier(); +// } return results; } 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 e96233734..10ceb11e7 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 @@ -402,8 +402,12 @@ public HashMap getPrestigeMultipliers() { * * @return double. * */ - public double getPlayerMultiplier(Player p) { + public double getPlayerMultiplier( Player player ) { + return getPlayerMultiplier( new SpigotPlayer( player )); + } + public double getPlayerMultiplier( tech.mcprison.prison.internal.Player sPlayer ) { + if (!isSellAllMultiplierEnabled) { @@ -413,7 +417,7 @@ public double getPlayerMultiplier(Player p) { // long tPoint1 = System.nanoTime(); - SpigotPlayer sPlayer = new SpigotPlayer(p); +// SpigotPlayer sPlayer = new SpigotPlayer(p); double multiplier = 0d; double rankMultiplers = 0; @@ -484,6 +488,13 @@ public double getPlayerMultiplier(Player p) { String permPattern = "prison.sellall.multiplier."; List perms = sPlayer.getPermissions( permPattern ); + + // If the player is off line, then try to use the snapshot of the last group of perms: + if ( perms.size() == 0 && sPlayer.getRankPlayer() != null ) { + perms.addAll( sPlayer.getPermissions( permPattern, sPlayer.getRankPlayer().getPermsSnapShot() )); + } + + double multiplierExtraByPerms = 0; for (String multByPerm : perms) { From 56d28c721a0c97c3c8e5bbd251d52e32c04b0d41 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 26 Aug 2024 03:05:48 -0400 Subject: [PATCH 134/323] Mine bombs: A lot of various changes and fixes to get them to work better. This new animation and mine bombs code needs more refinement and adjustments, but it's working far better than what it was. --- docs/changelog_v3.3.x.md | 6 +- .../mcprison/prison/bombs/MineBombData.java | 14 +++- .../bombs/MineBombDefaultConfigSettings.java | 1 - .../tech/mcprison/prison/bombs/MineBombs.java | 3 +- .../prison/bombs/MineBombsConfigData.java | 6 +- .../bombs/animations/BombAnimationBounce.java | 17 ++++- .../animations/BombAnimationInfinity.java | 4 +- .../bombs/animations/BombAnimationNone.java | 12 ++- .../animations/BombAnimationOrbital.java | 68 ++++++++--------- .../bombs/animations/BombAnimations.java | 70 +++++++++++------- .../bombs/animations/BombAnimationsTask.java | 37 ++++++++-- .../mcprison/prison/internal/ArmorStand.java | 2 + .../tech/mcprison/prison/internal/World.java | 3 +- .../tech/mcprison/prison/util/Location.java | 8 +- .../java/tech/mcprison/prison/TestWorld.java | 3 +- .../mcprison/prison/internal/WorldTest.java | 3 +- .../mcprison/prison/spigot/SpigotUtil.java | 24 +++--- .../prison/spigot/game/SpigotWorld.java | 73 ++++++++++++------- .../spigot/game/entity/SpigotArmorStand.java | 32 +++++--- .../spigot/utils/PrisonBombListener.java | 37 +++++++++- .../utils/PrisonUtilsMineBombsTasks.java | 10 +-- 21 files changed, 288 insertions(+), 145 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index ed34aeddb..e2988ea78 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-beta.18c 2024-08-23 +# 3.3.0-beta.18c 2024-08-26 + + +* **Mine bombs: A lot of various changes and fixes to get them to work better.** +This new animation and mine bombs code needs more refinement and adjustments, but it's working far better than what it was. * **Placeholders: Sellall multiplier: Fixed a few issues related to being offline and even OP'd. 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 e49bb1a5c..d3b4d1e3a 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 @@ -333,10 +333,12 @@ public MineBombData( String name, String itemType, String explosionShape, this.animationPattern = AnimationPattern.infinity; // setAnimationPattern( AnimationPattern.infinity ); - + this.throwVelocityLow = 1.5; this.throwVelocityHigh = 3; + this.animationSpeed = 10.0; + this.glowing = false; this.gravity = true; @@ -777,6 +779,9 @@ public void setSmall(boolean small) { } public boolean addSoundEffects( MineBombEffectsData effect ) { + return addSoundEffects( effect, true ); + } + public boolean addSoundEffects( MineBombEffectsData effect, boolean showWarnings ) { boolean results = false; effect.setEffectType( EffectType.sounds ); @@ -786,7 +791,7 @@ public boolean addSoundEffects( MineBombEffectsData effect ) { if ( effect.isValid() ) { getSoundEffects().add(effect); } - else { + else if ( showWarnings ) { String msg = String.format( "MineBombData.addSoundEffects: Invalid effect. " + "This effect is not valid for the version of Spigot that you're " @@ -808,6 +813,9 @@ public void setSoundEffects( TreeSet soundEffects ) { } public boolean addVisualEffects( MineBombEffectsData effect ) { + return addVisualEffects( effect, true ); + } + public boolean addVisualEffects( MineBombEffectsData effect, boolean showWarnings ) { boolean results = false; effect.setEffectType( EffectType.visuals ); @@ -817,7 +825,7 @@ public boolean addVisualEffects( MineBombEffectsData effect ) { if ( effect.isValid() ) { getVisualEffects().add(effect); } - else { + else if ( showWarnings ) { String msg = String.format( "MineBombData.addVisualEffects: Invalid effect. " + "This effect is not valid for the version of Spigot that you're " 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 b016bf8ef..fce927b8d 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 @@ -8,7 +8,6 @@ public class MineBombDefaultConfigSettings { - @SuppressWarnings( "unused" ) public void setupDefaultMineBombData(MineBombs mineBombs) { if ( mineBombs.getConfigData().getBombs().size() == 0 ) { 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 c220fd7ad..2b07bfae6 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 @@ -347,6 +347,7 @@ public void loadConfigJson() { getConfigData().getBombs().clear(); MineBombDefaultConfigSettings defaultConfigs = new MineBombDefaultConfigSettings(); + defaultConfigs.setupDefaultMineBombData( this ); @@ -359,7 +360,7 @@ public void loadConfigJson() { if ( configs != null ) { - boolean dirty = configs.validateMineBombEffects(); + boolean dirty = configs.validateMineBombEffects( true ); setConfigData( configs ); 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 6aa1e85a2..27dfe96bb 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 @@ -43,7 +43,7 @@ public void setDataFormatVersion( int dataFormatVersion ) { this.dataFormatVersion = dataFormatVersion; } - public boolean validateMineBombEffects() { + protected boolean validateMineBombEffects( boolean showWarnings ) { boolean results = false; Set keys = getBombs().keySet(); @@ -53,7 +53,7 @@ public boolean validateMineBombEffects() { TreeSet sounds = new TreeSet<>( bomb.getSoundEffects() ); bomb.getSoundEffects().clear(); for ( MineBombEffectsData sound : sounds ) { - if ( bomb.addSoundEffects( sound ) && !results ) { + if ( bomb.addSoundEffects( sound, showWarnings ) && !results ) { results = true; } } @@ -61,7 +61,7 @@ public boolean validateMineBombEffects() { TreeSet visuals = new TreeSet<>( bomb.getVisualEffects() ); bomb.getVisualEffects().clear(); for ( MineBombEffectsData visual : visuals ) { - if ( bomb.addVisualEffects( visual ) && !results ) { + if ( bomb.addVisualEffects( visual, showWarnings ) && !results ) { results = true; } } diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationBounce.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationBounce.java index 52c571326..425f3f988 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationBounce.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationBounce.java @@ -11,10 +11,12 @@ public class BombAnimationBounce private double yOriginal = 0; private double counter = 0; - public BombAnimationBounce(MineBombData bomb, PrisonBlock sBombBlock, + public BombAnimationBounce(MineBombData bomb, + Location location, + PrisonBlock sBombBlock, ItemStack item, BombAnimationsTask task, float entityYaw, float entityPitch) { - super(bomb, sBombBlock, item, task, entityYaw, entityPitch); + super(bomb, location, sBombBlock, item, task, entityYaw, entityPitch); this.yOriginal = getArmorStand().getLocation().getY(); } @@ -32,11 +34,20 @@ public void stepAnimation() { double bounce = 1.25 * Math.sin( counter ); - Location loc = new Location( getArmorStand().getLocation() ); + Location loc = new Location( getOriginalLocation() ); + + // NOTICE!!! Have to subtract 1 from the original location so the armorstand is + // always TP'd to the same y value. Otherwise it will bounce when it + // hits the ground. This probably only affects spigot 1.8.x. + // This has something to do with the fact that the armorstand is being + // teleported. + loc.setY( loc.getY() - 1 ); + loc.setY( yOriginal + bounce ); getArmorStand().teleport( loc ); + // getArmorStand().getLocation().setY( yOriginal + bounce ); } diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationInfinity.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationInfinity.java index cae7bc9b0..4e042a71c 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationInfinity.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationInfinity.java @@ -4,15 +4,17 @@ import tech.mcprison.prison.internal.EulerAngle; import tech.mcprison.prison.internal.ItemStack; import tech.mcprison.prison.internal.block.PrisonBlock; +import tech.mcprison.prison.util.Location; public class BombAnimationInfinity extends BombAnimations { public BombAnimationInfinity( MineBombData bomb, + Location location, PrisonBlock sBombBlock, ItemStack item, BombAnimationsTask task, float entityYaw, float entityPitch ) { - super( bomb, sBombBlock, item, task, entityYaw, entityPitch ); + super( bomb, location, sBombBlock, item, task, entityYaw, entityPitch ); } diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationNone.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationNone.java index 130aa07e2..407b5f6f1 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationNone.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationNone.java @@ -3,6 +3,7 @@ import tech.mcprison.prison.bombs.MineBombData; import tech.mcprison.prison.internal.ItemStack; import tech.mcprison.prison.internal.block.PrisonBlock; +import tech.mcprison.prison.util.Location; public class BombAnimationNone extends BombAnimations { @@ -16,22 +17,29 @@ public class BombAnimationNone * @param task */ public BombAnimationNone( MineBombData bomb, + Location location, PrisonBlock sBombBlock, BombAnimationsTask task ) { - super( bomb, sBombBlock, task ); + super( bomb, location, sBombBlock, task ); } public BombAnimationNone( MineBombData bomb, + Location location, PrisonBlock sBombBlock, ItemStack item, BombAnimationsTask task, float entityYaw, float entityPitch ) { - super( bomb, sBombBlock, item, task, entityYaw, entityPitch ); + super( bomb, location, sBombBlock, item, task, entityYaw, entityPitch ); } + /** + * Since this animation is "none", there is no movement to this one. + * + * This should be used for displaying the custom name. + */ @Override public void stepAnimation() { diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationOrbital.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationOrbital.java index ba871f358..60abeb09a 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationOrbital.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationOrbital.java @@ -15,13 +15,15 @@ public class BombAnimationOrbital extends BombAnimations { private double angle = 0.0; private double radius = 1.0; + private double radiusDelta = 0; private boolean alternateDirections = false; - public BombAnimationOrbital(MineBombData bomb, PrisonBlock sBombBlock, + public BombAnimationOrbital(MineBombData bomb, Location location, + PrisonBlock sBombBlock, ItemStack item, BombAnimationsTask task, float entityYaw, float entityPitch) { - super(bomb, sBombBlock, item, task, entityYaw, entityPitch); + super(bomb, location, sBombBlock, item, task, entityYaw, entityPitch); this.angle = entityYaw; @@ -30,11 +32,6 @@ public BombAnimationOrbital(MineBombData bomb, PrisonBlock sBombBlock, bomb.getAnimationOffset(), 0d, bomb.getAnimationOffset()); getOriginalLocation().add( vec ); -// getOriginalLocation().setX( -// getOriginalLocation().getX() + bomb.getAnimationOffset()); -// getOriginalLocation().setZ( -// getOriginalLocation().getZ() + bomb.getAnimationOffset()); - } @Override @@ -61,41 +58,33 @@ else if ( angle < -360 ) { angle += 360; } - Vector vector = GeometricShapes.getPointsOnCircleXZ( angle, radius ); + double radi = radius + + (radiusDelta == 0 ? 0 : + radiusDelta * Math.sin( angle / 2d )); - // Location.add() creates a new instance of a Location and does not change - // the original value: - Location newLoc = getOriginalLocation().add(vector); - getArmorStand().teleport( newLoc ); + double spinVal = angle * -7d; +// Vector spin = new Vector( spinVal, 0, 0 ); -// DecimalFormat dFmt = new DecimalFormat( "#,##0.0000" ); -// Output.get().logInfo( -// String.format( -// "Orbital direction: angle: %8s x: %8s y: %8s z: %8s", -// dFmt.format(angle), -// dFmt.format( vector.getX() ), -// dFmt.format( vector.getY() ), -// dFmt.format( vector.getY() ) -// ) -// ); -// + Vector vector = GeometricShapes.getPointsOnCircleXZ( angle, radi ); +// Vector vector = GeometricShapes.getPointsOnCircleXZ( angle, radius ); + // Location.add() creates a new instance of a Location and does not change + // the original value: + Location newLoc = getOriginalLocation().add(vector); + // NOTICE!!! Have to subtract 1 from the original location so the armorstand is + // always TP'd to the same y value. Otherwise it will bounce when it + // hits the ground. This probably only affects spigot 1.8.x. + // This has something to do with the fact that the armorstand is being + // teleported. + newLoc.setY( newLoc.getY() - 1 ); -// double angle = 0.05; -// Vector direction = getArmorStand().getLocation().getDirection(); -// -// setEulerAngleX( direction.getX() + angle); -// -// direction.setX( getEulerAngleX() ); -// -// getArmorStand().getLocation().setDirection(direction); -// -// -// Output.get().logInfo( "Orbital direction: x: " + getEulerAngleX() + -// " y: " + getEulerAngleY() + -// " z: " + getEulerAngleZ() ); + // Spin the held item? + newLoc.setYaw( (float) spinVal ); +// newLoc.setDirection( spin ); + + getArmorStand().teleport( newLoc ); } @@ -114,6 +103,13 @@ public void setRadius(double radius) { this.radius = radius; } + public double getRadiusDelta() { + return radiusDelta; + } + public void setRadiusDelta(double radiusDelta) { + this.radiusDelta = radiusDelta; + } + public boolean isAlternateDirections() { return alternateDirections; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java index 96d685242..576890fc1 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java @@ -9,7 +9,6 @@ import tech.mcprison.prison.internal.EulerAngle; import tech.mcprison.prison.internal.ItemStack; import tech.mcprison.prison.internal.block.PrisonBlock; -import tech.mcprison.prison.output.Output; import tech.mcprison.prison.util.BluesSemanticVersionComparator; import tech.mcprison.prison.util.Location; import tech.mcprison.prison.util.Text; @@ -53,12 +52,14 @@ public abstract class BombAnimations { * holographic display of the name. */ public BombAnimations( MineBombData bomb, + Location location, PrisonBlock sBombBlock, BombAnimationsTask task ) { - this( bomb, sBombBlock, null, task, 0f, 0f ); + this( bomb, location, sBombBlock, null, task, 0f, 0f ); } public BombAnimations( MineBombData bomb, + Location location, PrisonBlock sBombBlock, ItemStack item, BombAnimationsTask task, @@ -75,12 +76,11 @@ public BombAnimations( MineBombData bomb, this.sBlock = sBombBlock; this.item = item; - - Location location = - getBomb().getPlacedBombLocation() != null ? - getBomb().getPlacedBombLocation() : - getsBlock().getLocation(); - location.setY( location.getY() + 2.5 ); +// Location location = +// getBomb().getPlacedBombLocation() != null ? +// getBomb().getPlacedBombLocation() : +// getsBlock().getLocation(); +// location.setY( location.getY() + 2.5 ); // NOTE: The direction the entity is facing is based upon yaw. // When using org.bukkit.Location.setDirection() it's using a vector @@ -167,10 +167,11 @@ public void initialize() { // If item is null, then armorstand will not spawn with an item // and no arms. armorStand = getOriginalLocation().spawnArmorStand( - (getItem() == null ? null : getBomb().getItemType()), - (getId() == 0 ? getBomb().getName() : null) ); + (getItem() == null ? null : getBomb().getItemType()) ); +// armorStand = getOriginalLocation().spawnArmorStand( +// null, +// (getId() == 0 ? getBomb().getName() : null) ); -// MineBombs.MINE_BOMBS_NBT_KEY, getBomb().getName() ); // armorStand = location.spawnArmorStand(); @@ -192,8 +193,21 @@ public void initialize() { // armorStand.setupArmorStand( getBomb().getItemType() ); // armorStand.setupArmorStand( getItem() ); +// if ( getItem() != null ) { +// armorStand.setVisible( true ); +// +// armorStand.setArms( true ); +// +// armorStand.setItemInHand( getItem() ); +// } + + + + // Sets up the custom name on the armorstand and also configures the + // processing if it's a dynamic name: armorStand.setCustomNameVisible( getId() == 0 && initializeCustomName() ); + armorStand.setNbtString( MineBombs.MINE_BOMBS_NBT_KEY, getBomb().getName() ); // armorStand.setNbtString( MineBombs.MINE_BOMBS_NBT_THROWER_UUID, @@ -231,27 +245,33 @@ public void initialize() { if ( new BluesSemanticVersionComparator().compareMCVersionTo( "1.9.0" ) >= 0 ) { + armorStand.setInvulnerable( true ); + armorStand.setGlowing( getBomb().isGlowing() ); // setGravity is invalid for spigot 1.8.8: armorStand.setGravity( getBomb().isGravity() ); + + armorStand.setInvulnerable( true ); } } - if ( Output.get().isDebug() ) { - String msg = String.format( - "### BombAnimation.initializeArmorStand : id: %s %s %s %s%s", - Integer.toString(getId()), - bomb.getAnimationPattern().name(), - armorStand.getLocation().toString(), - (getArmorStand().isCustomNameVisible() ? " CustomName" : ""), - (getArmorStand().hasArms() ? " hasArms" : "" ), - (getArmorStand().getItemInHand() != null ? - " " + getArmorStand().getItemInHand().getName() : "" ) - ); - - Output.get().logInfo( msg ); - } +// if ( Output.get().isDebug() ) { +// String msg = String.format( +// "### BombAnimation.initializeArmorStand : id: %s %s %s %s%s%s%s", +// Integer.toString(getId()), +// bomb.getAnimationPattern().name(), +// armorStand.getLocation().toWorldCoordinates(), +// +// (getArmorStand().isCustomNameVisible() ? " CustomName" : " -noName- "), +// (getArmorStand().hasArms() ? " hasArms" : " -noArms- " ), +// (getArmorStand().getItemInHand() != null ? +// " " + getArmorStand().getItemInHand().getName() : " -noItemInHand- " ), +// (getArmorStand().isVisible() ? " visible " : " notVisible ") +// ); +// +// Output.get().logInfo( msg ); +// } } diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationsTask.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationsTask.java index cefe623dc..18dbf21b7 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationsTask.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationsTask.java @@ -11,6 +11,7 @@ import tech.mcprison.prison.output.Output; import tech.mcprison.prison.tasks.PrisonRunnable; import tech.mcprison.prison.tasks.PrisonTaskSubmitter; +import tech.mcprison.prison.util.Location; public class BombAnimationsTask implements PrisonRunnable { @@ -45,6 +46,22 @@ public void animatorFactory( AnimationPattern animation = bomb.getAnimationPattern(); + Location location = + bomb.getPlacedBombLocation() != null ? + bomb.getPlacedBombLocation() : + pBlock.getLocation(); + + // The current y adjustment is +2.5 blocks. Still using this so + // existing bomb configs are not messed up. + location.setY( Math.floor( location.getY() + 2 ) ); + + // The bomb y adjustments should have been made in this function: + // tech.mcprison.prison.spigot.utils.PrisonUtilsMineBombs.setBombInHand() +// if ( bomb.getPlacementAdjustmentY() != 0 ) { +// +// location.setY( location.getY() + bomb.getPlacementAdjustmentY() ); +// } + if ( Output.get().isDebug() ) { String msg = String.format( @@ -61,13 +78,14 @@ public void animatorFactory( case bounce: { // Add BombAnimationNone for a stationary name: - BombAnimationNone baHolo = new BombAnimationNone( bomb, pBlock, this ); + BombAnimationNone baHolo = new BombAnimationNone( bomb, location, pBlock, this ); getAnimators().add( baHolo ); float yaw = 0; float pitch = 0; BombAnimationBounce ba = new BombAnimationBounce( bomb, + location, pBlock, item, this, yaw, pitch ); @@ -80,13 +98,14 @@ public void animatorFactory( case orbital: { // Add BombAnimationNone for a stationary name: - BombAnimationNone baHolo = new BombAnimationNone( bomb, pBlock, this ); + BombAnimationNone baHolo = new BombAnimationNone( bomb, location, pBlock, this ); getAnimators().add( baHolo ); float yaw = 0; float pitch = 0; BombAnimationOrbital ba = new BombAnimationOrbital( bomb, + location, pBlock, item, this, yaw, pitch ); @@ -99,7 +118,7 @@ public void animatorFactory( case orbitalEight: { // Add BombAnimationNone for a stationary name: - BombAnimationNone baHolo = new BombAnimationNone( bomb, pBlock, this ); + BombAnimationNone baHolo = new BombAnimationNone( bomb, location, pBlock, this ); getAnimators().add( baHolo ); float yaw = 0; @@ -108,6 +127,7 @@ public void animatorFactory( for ( int i = 0; i < 8; i++ ) { BombAnimationOrbital ba = new BombAnimationOrbital( bomb, + location, pBlock, item, this, yaw, pitch ); @@ -123,7 +143,7 @@ public void animatorFactory( case starburst: { // Add BombAnimationNone for a stationary name: - BombAnimationNone baHolo = new BombAnimationNone( bomb, pBlock, this ); + BombAnimationNone baHolo = new BombAnimationNone( bomb, location, pBlock, this ); getAnimators().add( baHolo ); float yaw = 0; @@ -132,10 +152,12 @@ public void animatorFactory( for ( int i = 0; i < 16; i++ ) { BombAnimationOrbital ba = new BombAnimationOrbital( bomb, + location, pBlock, item, this, yaw, pitch ); ba.setAlternateDirections( true ); + ba.setRadiusDelta( 1.0 ); getAnimators().add( ba ); @@ -152,6 +174,7 @@ public void animatorFactory( float pitch = 0; BombAnimationInfinity ba = new BombAnimationInfinity( bomb, + location, pBlock, item, this, yaw, pitch ); @@ -164,7 +187,7 @@ public void animatorFactory( case infinityEight: { // Add BombAnimationNone for a stationary name: - BombAnimationNone baHolo = new BombAnimationNone( bomb, pBlock, this ); + BombAnimationNone baHolo = new BombAnimationNone( bomb, location, pBlock, this ); getAnimators().add( baHolo ); float yaw = 0; @@ -172,7 +195,7 @@ public void animatorFactory( float yawStep = 360f / 8f; for ( int i = 0; i < 8; i++ ) { - BombAnimationInfinity ba = new BombAnimationInfinity( bomb, + BombAnimationInfinity ba = new BombAnimationInfinity( bomb, location, pBlock, item, this, yaw, pitch ); @@ -192,7 +215,7 @@ public void animatorFactory( float yaw = 0; float pitch = 0; - BombAnimationNone ba = new BombAnimationNone( bomb, + BombAnimationNone ba = new BombAnimationNone( bomb, location, pBlock, item, this, yaw, pitch ); diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/ArmorStand.java b/prison-core/src/main/java/tech/mcprison/prison/internal/ArmorStand.java index dd0bd3d6d..bbada6baf 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/ArmorStand.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/ArmorStand.java @@ -38,5 +38,7 @@ public interface ArmorStand public boolean isSmall(); public void setSmall(boolean small); + + public void setInvulnerable(boolean b); } diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/World.java b/prison-core/src/main/java/tech/mcprison/prison/internal/World.java index 3ec2e1250..d49e60e98 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/World.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/World.java @@ -89,8 +89,7 @@ public void setBlocksSynchronously( List tBlocks, public ArmorStand spawnArmorStand( Location location ); - public ArmorStand spawnArmorStand(Location location, String itemType, - String customName ); + public ArmorStand spawnArmorStand(Location location, String itemType ); public int getMaxHeight(); 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 663564fbf..59ada78fa 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 @@ -74,6 +74,10 @@ public Location(Location clone) { public Location() { } + public Location clone() { + return new Location( this ); + } + public World getWorld() { return world; } @@ -336,9 +340,9 @@ public ArmorStand spawnArmorStand() { return getWorld().spawnArmorStand( this ); } - public ArmorStand spawnArmorStand( String itemName, String name ) { + public ArmorStand spawnArmorStand( String itemName ) { - return getWorld().spawnArmorStand( this, itemName, name ); + return getWorld().spawnArmorStand( this, itemName ); } diff --git a/prison-core/src/test/java/tech/mcprison/prison/TestWorld.java b/prison-core/src/test/java/tech/mcprison/prison/TestWorld.java index 2f6fd4dcc..942522818 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/TestWorld.java +++ b/prison-core/src/test/java/tech/mcprison/prison/TestWorld.java @@ -101,8 +101,7 @@ public int getMaxHeight() { } @Override - public ArmorStand spawnArmorStand(Location location, String itemType, - String customName ) { + public ArmorStand spawnArmorStand(Location location, String itemType ) { return null; } diff --git a/prison-core/src/test/java/tech/mcprison/prison/internal/WorldTest.java b/prison-core/src/test/java/tech/mcprison/prison/internal/WorldTest.java index b00142e08..783c71f42 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/internal/WorldTest.java +++ b/prison-core/src/test/java/tech/mcprison/prison/internal/WorldTest.java @@ -61,8 +61,7 @@ public ArmorStand spawnArmorStand(Location location) { } @Override - public ArmorStand spawnArmorStand(Location location, String itemType, - String customName ) { + public ArmorStand spawnArmorStand(Location location, String itemType ) { return null; } 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 75a8ba2bf..25081584f 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 @@ -55,7 +55,6 @@ import tech.mcprison.prison.spigot.integrations.IntegrationMinepacksPlugin; import tech.mcprison.prison.util.Location; import tech.mcprison.prison.util.Text; -import tech.mcprison.prison.util.Vector; /** * Utilities for converting Prison-Core types to Spigot types. @@ -1050,13 +1049,18 @@ private static void logTestBlocks( StringBuilder sb, String message ) { */ public static Location bukkitLocationToPrison(org.bukkit.Location bukkitLocation) { - org.bukkit.util.Vector v = bukkitLocation.getDirection(); - Vector direction = new Vector( v.getX(), v.getY(), v.getZ() ); - return new Location(new SpigotWorld(bukkitLocation.getWorld()), bukkitLocation.getX(), - bukkitLocation.getY(), bukkitLocation.getZ(), bukkitLocation.getPitch(), - bukkitLocation.getYaw(), - direction ); + return new Location(new SpigotWorld(bukkitLocation.getWorld()), bukkitLocation.getX(), + bukkitLocation.getY(), bukkitLocation.getZ(), bukkitLocation.getPitch(), + bukkitLocation.getYaw() ); + +// org.bukkit.util.Vector v = bukkitLocation.getDirection(); +// Vector direction = new Vector( v.getX(), v.getY(), v.getZ() ); +// +// return new Location(new SpigotWorld(bukkitLocation.getWorld()), bukkitLocation.getX(), +// bukkitLocation.getY(), bukkitLocation.getZ(), bukkitLocation.getPitch(), +// bukkitLocation.getYaw(), +// direction ); } public static org.bukkit.Location prisonLocationToBukkit(Location prisonLocation) { @@ -1065,9 +1069,9 @@ public static org.bukkit.Location prisonLocationToBukkit(Location prisonLocation prisonLocation.getX(), prisonLocation.getY(), prisonLocation.getZ(), prisonLocation.getYaw(), prisonLocation.getPitch() ); - Vector v = prisonLocation.getDirection(); - org.bukkit.util.Vector vec = new org.bukkit.util.Vector( v.getX(), v.getY(), v.getZ() ); - loc.setDirection( vec ); +// Vector v = prisonLocation.getDirection(); +// org.bukkit.util.Vector vec = new org.bukkit.util.Vector( v.getX(), v.getY(), v.getZ() ); +// loc.setDirection( vec ); return loc; } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotWorld.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotWorld.java index d52e168e7..36a5113b4 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotWorld.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotWorld.java @@ -48,7 +48,6 @@ import tech.mcprison.prison.spigot.game.entity.SpigotArmorStand; import tech.mcprison.prison.spigot.game.entity.SpigotEntity; import tech.mcprison.prison.spigot.game.entity.SpigotEntityType; -import tech.mcprison.prison.spigot.nbt.PrisonNBTUtil; import tech.mcprison.prison.util.Location; /** @@ -328,62 +327,84 @@ public org.bukkit.entity.ArmorStand spawnBukkitArmorStand( Location location ) { @Override - public ArmorStand spawnArmorStand( Location location, String itemType, - String customName -// , -// String nbtKey, String nbtValue - ) { + public ArmorStand spawnArmorStand( Location location, String itemType ) { - int maxHight = location.getWorld().getMaxHeight(); - Location spawnPoint = new Location( location ); - spawnPoint.setY(maxHight); + // NOTE: Once spawned, the armor stand is not being teleported back to the + // intended location. It was being spawned at a different location + // because it was "flashing" as visible. +// int maxHight = location.getWorld().getMaxHeight(); + +// Location spawnPoint = new Location( location ); +// spawnPoint.setY(maxHight); + + + + org.bukkit.inventory.ItemStack bItemStack = null; // Location spawnPoint = new Location( location ); // spawnPoint.setX( spawnPoint.getX() + 2 ); // spawnPoint.setZ( spawnPoint.getZ() + 2 ); - org.bukkit.entity.Entity bEntity = spawnBukkitEntity( spawnPoint, SpigotEntityType.ENTITY_TYPE_ARMOR_STAND ); + org.bukkit.entity.Entity bEntity = spawnBukkitEntity( location, SpigotEntityType.ENTITY_TYPE_ARMOR_STAND ); org.bukkit.entity.ArmorStand as = (org.bukkit.entity.ArmorStand) bEntity; as.setVisible( false ); - as.setCustomNameVisible( true ); - as.setArms( true ); as.setBasePlate( false ); - - if ( customName != null ) { - as.setCustomName( customName ); - } + as.setCanPickupItems( false ); +// as.setInvulnerable( true ); +// as.setGravity( false ); -// if ( nbtKey != null && nbtValue != null ) { -// -// PrisonNBTUtil.setNBTString( as, nbtKey, nbtValue ); +// if ( customName == null ) { +// as.setCustomNameVisible( false ); // } +// else { +// as.setCustomNameVisible( true ); +// as.setCustomName( customName ); +// } + - - if ( itemType != null && itemType.trim().length() > 0 ) { + if ( itemType == null || itemType.trim().length() == 0 ) { + as.setArms( false ); + + } + else { + as.setArms( true ); + +// XMaterial.ARMOR_STAND. XMaterial xMat = XMaterial.matchXMaterial( itemType ).orElse( null ); - org.bukkit.inventory.ItemStack bItemStack = xMat == null ? null : xMat.parseItem(); + bItemStack = xMat == null ? null : xMat.parseItem(); if ( bItemStack == null ) { bItemStack = XMaterial.COBBLESTONE.parseItem(); } + as.setItemInHand(bItemStack); +// as.setItem( EquipmentSlot.HAND, bItemStack); + } +// String msg = "SpigotWorld.spawnArmorStand: itemInHand: " + +// ( as.getItemInHand() == null ? "null" : as.getItemInHand().toString()) + +// " hasArmms: " + as.hasArms() + +// " itemStack( " + +// (bItemStack == null ? "null" : +// bItemStack.toString() + " " + bItemStack.getAmount()) + ") " + +// " name: " + (customName == null ? "noCustomName" : customName); +// +// Output.get().logInfo( msg ); - as.teleport( SpigotLocation.getBukkitLocation(location) ); +// as.teleport( SpigotLocation.getBukkitLocation(location) ); - // as.setSmall( true ); - + // wrap in a SpigotArmorStand: SpigotArmorStand sas = new SpigotArmorStand( as ); -// sas.teleport( location ); + //sas.teleport( location ); return sas; } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotArmorStand.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotArmorStand.java index 34052464b..a7424c907 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotArmorStand.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotArmorStand.java @@ -132,16 +132,23 @@ public ItemStack getItemInHand() { @Override public void setItemInHand(ItemStack item) { - SpigotItemStack sItemStack = - ( item instanceof SpigotItemStack ? - (SpigotItemStack) item : - new SpigotItemStack( item ) ); - - this.sItemStack = sItemStack; - - org.bukkit.inventory.ItemStack bas = sItemStack.getBukkitStack(); - - bArmorStand.setItemInHand( bas ); + if ( item == null ) { + bArmorStand.setItemInHand( null ); + bArmorStand.setArms( false ); + } + else { + SpigotItemStack sItemStack = + ( item instanceof SpigotItemStack ? + (SpigotItemStack) item : + new SpigotItemStack( item ) ); + + this.sItemStack = sItemStack; + + org.bukkit.inventory.ItemStack bas = sItemStack.getBukkitStack(); + + bArmorStand.setArms( true ); + bArmorStand.setItemInHand( bas ); + } } @Override @@ -209,5 +216,10 @@ public boolean isSmall() { public void setSmall(boolean small) { bArmorStand.setSmall(small); } + + @Override + public void setInvulnerable(boolean invulnerable) { + bArmorStand.setInvulnerable(invulnerable); + } } 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 7794068f8..e228e0882 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 @@ -95,6 +95,13 @@ public void mineBombPlacementEvent( BlockPlaceEvent event ) { Block targetBlock = event.getBlockAgainst(); + SpigotBlock lsBlock = sPlayer.getLineOfSightBlock(); + + Output.get().logInfo( + "### Place mine bomb: mineBombPlacementEvent: block: %s sight: %s", + targetBlock.getLocation().toString(), + lsBlock.getLocation().toString() ); + EquipmentSlot hand = SpigotCompatibility.getInstance().getHand(event); boolean canceled = processBombTriggerEvent( player, mineBomb, @@ -220,6 +227,8 @@ public void run() { locs.get(2).equals(locs.get(3)) ) { + // Set the mine bomb's location where the item has landed: + mineBomb.setPlacedBombLocation( loc ); // Cancel this task: SpigotPrison.getInstance().getScheduler().cancelTask( mineBomb.getTask() ); @@ -232,7 +241,7 @@ public void run() { aStnd.remove(); // Start mine bomb animation: - loc.setY( loc.getY() - 1); +// loc.setY( loc.getY() ); SpigotBlock targetBlock = (SpigotBlock) loc.getBlockAt(); Mine mine = getMine(sPlayer, mineBomb, targetBlock ); @@ -337,6 +346,29 @@ public void bombPlacementEvent( PlayerInteractEvent event ) { Block targetBlock = event.getClickedBlock(); + + SpigotBlock lsBlock = sPlayer.getLineOfSightBlock(); + + Location losLoc = sPlayer.getLineOfSightExactLocation(); + + // The placedBombLocation will be used as the center point of the animation: + mineBomb.setPlacedBombLocation( losLoc ); + + Output.get().logInfo( + "### Place mine bomb: bombPlacementEvent: block: %s " + + "sight: %s LineOfSight: %s ", + new SpigotLocation( targetBlock.getLocation()).toString(), + lsBlock.getLocation().toString(), + (losLoc == null ? "null" : losLoc.toString()) ); + + if ( losLoc != null ) { + lsBlock = (SpigotBlock) losLoc.getBlockAt(); + + targetBlock = lsBlock.getWrapper(); + } + + + EquipmentSlot hand = SpigotCompatibility.getInstance().getHand(event); processBombTriggerEvent( player, mineBomb, targetBlock, hand ); @@ -419,7 +451,8 @@ private boolean processBombTriggerEvent( Player player, private boolean processBombTriggerEvent( SpigotPlayer sPlayer, Mine mine, MineBombData mineBomb, - SpigotBlock sBlock, EquipmentSlot hand ) { + SpigotBlock sBlock, + EquipmentSlot hand ) { boolean canceled = false; diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTasks.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTasks.java index 82ce8a139..e036b3fc0 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTasks.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTasks.java @@ -169,13 +169,12 @@ public void run() { xSound.play( bLocation, effect.getVolumne(), effect.getPitch() ); } } - catch ( IllegalArgumentException | - NullPointerException e ) { + catch ( Exception e ) { Output.get().logWarn( String.format( "Invalid Sound Effect value in bomb %s: Error: [%s] [\\Q%s\\E] ", bomb.getName(), - e.getMessage(), + ( e == null ? "-noErrorMessage-" : e.getMessage()), effect.toString()) ); } @@ -214,13 +213,12 @@ public void run() { } } } - catch ( IllegalArgumentException | - NullPointerException e ) { + catch ( Exception e ) { Output.get().logWarn( String.format( "Invalid Visual Effect value in bomb %s: Error: [%s] [\\Q%s\\E] ", bomb.getName(), - e.getMessage(), + ( e == null ? "-noErrorMessage-" : e.getMessage()), effect.toString()) ); } From 5d9e74183f35a571e186b526a6f992ac87c4ab51 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 26 Aug 2024 15:02:36 -0400 Subject: [PATCH 135/323] New Feature: Support for Bukkit's EntityExplodeEvent which is what the ExcellentEnchantments plugin uses. --- docs/changelog_v3.3.x.md | 4 + .../autofeatures/AutoFeaturesFileConfig.java | 3 + .../prison/spigot/SpigotPlatform.java | 7 + .../AutoManagerEntityExplodeEvents.java | 450 ++++++++++++++++++ .../block/OnBlockBreakEventListener.java | 11 +- 5 files changed, 474 insertions(+), 1 deletion(-) create mode 100644 prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerEntityExplodeEvents.java diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index e2988ea78..2eca77c45 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-beta.18c 2024-08-26 + +* **New Feature: Support for Bukkit's EntityExplodeEvent which is what the ExcellentEnchantments plugin uses.** + + * **Mine bombs: A lot of various changes and fixes to get them to work better.** This new animation and mine bombs code needs more refinement and adjustments, but it's working far better than what it was. 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 408039a9c..bbd5c22e5 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 @@ -109,6 +109,9 @@ public enum AutoFeatures { blockBreakEventPriority(blockBreakEvents, "LOW"), + entityExplodeEventPriority(blockBreakEvents, "DISABLED"), + + ProcessPrisons_ExplosiveBlockBreakEventsPriority(blockBreakEvents, "LOW"), 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 07d956db7..360cc67c2 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 @@ -117,6 +117,7 @@ import tech.mcprison.prison.ranks.managers.RankManager; import tech.mcprison.prison.spigot.autofeatures.events.AutoManagerBlockBreakEvents; import tech.mcprison.prison.spigot.autofeatures.events.AutoManagerCrazyEnchants; +import tech.mcprison.prison.spigot.autofeatures.events.AutoManagerEntityExplodeEvents; import tech.mcprison.prison.spigot.autofeatures.events.AutoManagerPrisonEnchants; import tech.mcprison.prison.spigot.autofeatures.events.AutoManagerPrisonsExplosiveBlockBreakEvents; import tech.mcprison.prison.spigot.autofeatures.events.AutoManagerRevEnchantsExplosiveEvent; @@ -2847,6 +2848,12 @@ public String dumpEventListenersBlockBreakEvents() { AutoManagerPrisonsExplosiveBlockBreakEvents prisonExplosiveEnchants = new AutoManagerPrisonsExplosiveBlockBreakEvents(); prisonExplosiveEnchants.dumpEventListeners( sb ); + + // Bukkit's EntityExplodeEvent... used by creepers and enchantment plugins like ExcellentEnchants. + AutoManagerEntityExplodeEvents bukkitEntityExplodeEvent = new AutoManagerEntityExplodeEvents(); + bukkitEntityExplodeEvent.dumpEventListeners( sb ); + + AutoManagerCrazyEnchants crazyEnchants = new AutoManagerCrazyEnchants(); crazyEnchants.dumpEventListeners( sb ); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerEntityExplodeEvents.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerEntityExplodeEvents.java new file mode 100644 index 000000000..b5fdfd91b --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerEntityExplodeEvents.java @@ -0,0 +1,450 @@ +package tech.mcprison.prison.spigot.autofeatures.events; + +import org.bukkit.Bukkit; +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; +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.event.entity.EntityExplodeEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.EventExecutor; +import org.bukkit.plugin.PluginManager; + +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 AutoManagerEntityExplodeEvents + extends AutoManagerFeatures + implements PrisonEventManager +{ + private BlockBreakPriority bbPriority; + + private Boolean entityExplodeEventEnabled; + + public AutoManagerEntityExplodeEvents() { + super(); + + this.entityExplodeEventEnabled = null; + } + + + public AutoManagerEntityExplodeEvents( BlockBreakPriority bbPriority ) { + super(); + + this.entityExplodeEventEnabled = null; + + 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 AutoManagerEntityExplodeEventListener + extends AutoManagerEntityExplodeEvents + implements Listener { + + public AutoManagerEntityExplodeEventListener( BlockBreakPriority bbPriority ) { + super( bbPriority ); + } + + @EventHandler(priority=EventPriority.NORMAL) + public void onBukkitEntityExplode( EntityExplodeEvent e, BlockBreakPriority bbPriority) { + + if ( isDisabled( e.getEntity().getLocation().getWorld().getName() ) || + bbPriority.isDisabled() ) { + return; + } + + handleEntityExplodeEvent( e, bbPriority ); + } + } + + + @Override + public void initialize() { + + String eP = getMessage( AutoFeatures.CrazyEnchantsBlastUseEventPriority ); + + BlockBreakPriority bbPriority = BlockBreakPriority.fromString( eP ); + setBbPriority( bbPriority ); + +// boolean isEventEnabled = eP != null && !"DISABLED".equalsIgnoreCase( eP ); + + if ( bbPriority == BlockBreakPriority.DISABLED ) { + return; + } + + // Check to see if the class BlastUseEvent even exists: + try { + Output.get().logInfo( "AutoManager: checking if loaded: CrazyEnchants" ); + + Class.forName( "me.badbones69.crazyenchantments.api.events.BlastUseEvent", false, + this.getClass().getClassLoader() ); + + Output.get().logInfo( "AutoManager: Trying to register CrazyEnchants" ); + + + 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: CrazyEnchants is not loaded" ); + } + catch ( Exception e ) { + Output.get().logInfo( "AutoManager: CrazyEnchants failed to load. [%s]", e.getMessage() ); + } + } + + + private void createListener(BlockBreakPriority bbPriority) { + + SpigotPrison prison = SpigotPrison.getInstance(); + PluginManager pm = Bukkit.getServer().getPluginManager(); + EventPriority ePriority = bbPriority.getBukkitEventPriority(); + + + AutoManagerEntityExplodeEventListener autoManagerListener = + new AutoManagerEntityExplodeEventListener( bbPriority ); + + pm.registerEvent(EntityExplodeEvent.class, autoManagerListener, ePriority, + new EventExecutor() { + public void execute(Listener l, Event e) { + + EntityExplodeEvent eeEvent = (EntityExplodeEvent) e; + + ((AutoManagerEntityExplodeEventListener)l) + .onBukkitEntityExplode( eeEvent, getBbPriority() ); + } + }, + 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.entityExplodeEventPriority ); + boolean isEventEnabled = eP != null && !"DISABLED".equalsIgnoreCase( eP ); + + if ( !isEventEnabled ) { + return; + } + + // Check to see if the class BlastUseEvent even exists: + try { + + Class.forName( "org.bukkit.event.entity.EntityExplodeEvent", false, + this.getClass().getClassLoader() ); + + + HandlerList handlers = EntityExplodeEvent.getHandlerList(); + +// String eP = getMessage( AutoFeatures.blockBreakEventPriority ); + BlockBreakPriority bbPriority = BlockBreakPriority.fromString( eP ); + + dumpEventListenersCore( "EntityExplodeEvent", handlers, bbPriority, sb ); + + +// BlockBreakPriority bbPriority = BlockBreakPriority.fromString( eP ); +// +// +// String title = String.format( +// "BlastUseEvent (%s)", +// ( bbPriority == null ? "--none--" : bbPriority.name()) ); +// +// ChatDisplay eventDisplay = Prison.get().getPlatform().dumpEventListenersChatDisplay( +// title, +// new SpigotHandlerList( BlastUseEvent.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 ) { + // EntityExplodeEvent is not loaded... so ignore. + } + catch ( Exception e ) { + Output.get().logInfo( "AutoManager: EntityExplodeEvent failed to load. [%s]", e.getMessage() ); + } + } + + /** + *

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 handleEntityExplodeEvent( EntityExplodeEvent 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. + Entity bEntity = e.getEntity(); + Player bPlayer = bEntity instanceof Player ? (Player) bEntity : null; + + if ( bPlayer == null ) { + return; // Ignore the event... it's not a player. + } + + MinesEventResults eventResults = ignoreMinesBlockBreakEvent( e, + bPlayer, e.blockList().get( 0 ), + bbPriority, true ); + + if ( eventResults.isIgnoreEvent() ) { + return; + } + + StringBuilder debugInfo = new StringBuilder(); + + debugInfo.append( String.format( "### ** handleBlastUseEvent ** ### " + + "(event: BlastUseEvent, 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.blockList().size() > 0 ) { + + +// Block bukkitBlock = e.getBlockList().get( 0 ); + + BlockEventType eventType = BlockEventType.CEXplosion; + 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.blockList().size(); i++ ) { + pmEvent.getUnprocessedRawBlocks().add( e.blockList().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 function. + removeEventTriggerBlocksFromExplosions( pmEvent ); + + + + 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. + } + + + // now process all blocks (non-monitor): + else { + + // This is where the processing actually happens: + +// if ( e instanceof BlockBreakEvent ) { +// processPMBBExternalEvents( pmEvent, debugInfo, e ); +// } + + + + EventListenerCancelBy cancelBy = EventListenerCancelBy.none; + + cancelBy = processPMBBEvent( pmEvent ); + + + // NOTE: you cannot cancel a crazy enchant's drops, so this will + // always cancel the event. + 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; + + // NOTE: This does not exist for EntityExplodeEvent. See AutoManagerCrazyEnchants for it's source code. + + return bonusXp; + } + + + public Boolean isEntityExplodeEventEnabled() { + return entityExplodeEventEnabled; + } + public void setEntityExplodeEventEnabled(Boolean entityExplodeEventEnabled) { + this.entityExplodeEventEnabled = entityExplodeEventEnabled; + } + +} 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 f693a3c41..89b12686b 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 @@ -12,6 +12,7 @@ import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.autofeatures.events.AutoManagerBlockBreakEvents; import tech.mcprison.prison.spigot.autofeatures.events.AutoManagerCrazyEnchants; +import tech.mcprison.prison.spigot.autofeatures.events.AutoManagerEntityExplodeEvents; import tech.mcprison.prison.spigot.autofeatures.events.AutoManagerPrisonEnchants; import tech.mcprison.prison.spigot.autofeatures.events.AutoManagerPrisonsExplosiveBlockBreakEvents; import tech.mcprison.prison.spigot.autofeatures.events.AutoManagerRevEnchantsExplosiveEvent; @@ -105,6 +106,8 @@ public class OnBlockBreakEventListener private AutoManagerBlockBreakEvents bbEvents; private AutoManagerPrisonsExplosiveBlockBreakEvents pebbEvents; + private AutoManagerEntityExplodeEvents eeEvents; + private AutoManagerCrazyEnchants ceEvents; private AutoManagerPrisonEnchants peEvents; @@ -221,7 +224,8 @@ private void registerEvents() { // Prison's own internal event and listener: pebbEvents = new AutoManagerPrisonsExplosiveBlockBreakEvents(); - ceEvents = new AutoManagerCrazyEnchants(); + eeEvents = new AutoManagerEntityExplodeEvents(); + ceEvents = new AutoManagerCrazyEnchants(); @@ -252,6 +256,11 @@ private void registerEvents() { // Prison's own internal event and listener: pebbEvents.registerEvents(); + + // Bukkit's EntityExplodeEvent: + eeEvents.registerEvents(); + + ceEvents.registerEvents(); peEvents.registerEvents(); From da660153bd49000c28c21be7b601fdc254a3f926 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 27 Aug 2024 04:57:07 -0400 Subject: [PATCH 136/323] Fixed a potential problem with null ranks being loaded within the ladder loaders.. I cannot find a reason why this was happening, or what data was triggering it, but this fixed the issue by skipping null ranks. --- .../prison/ranks/data/RankLadderFactory.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankLadderFactory.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankLadderFactory.java index adbe19228..296dc04a4 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankLadderFactory.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankLadderFactory.java @@ -4,6 +4,7 @@ import com.google.gson.internal.LinkedTreeMap; +import tech.mcprison.prison.output.Output; import tech.mcprison.prison.ranks.PrisonRanks; import tech.mcprison.prison.ranks.managers.RankManager; import tech.mcprison.prison.store.Document; @@ -55,6 +56,19 @@ public RankLadder createRankLadder(Document document, RankManager rankManager) { // rankLadder.ranks = new ArrayList<>(); // already initialized for (LinkedTreeMap rank : ranksLocal) { + if ( rank == null ) { + + // Force a resave to "fix" the problem? + isDirty = true; + + Output.get().logInfo( "RankLadderFactory.createRankLadder: " + + "A loaded rank was null, and is skipping it. Since it" + + "was null, there is no way to identify what it was. " + + "This notice is to inform you and to prevent Prison from " + + "failing to load."); + + continue; + } // The only real field that is important here is rankId to tie the // rank back to this ladder. Name helps clarify the contents of the From e8606c80915eae8df6b4e058e00d3f1b21f5b1d0 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 27 Aug 2024 05:07:27 -0400 Subject: [PATCH 137/323] Bug fixes: With spigot/paper 1.21.1 and the NBT lib that we are using, there were issue that were suddenly occurring that worked fine before. Basically, eliminated a lot of generation of stack traces, especially when dealing with NBTs. Upgraded NBT-lib to v2.13.2 from v2.13.1. When formatting the rank list, the defaults were set to a value of zero. But if there are no tags on any ranks within a ladder, then the width was being used with a value of zero. This was causing a failure since it cannot left-position anything with a zero width. It was trying to format '%-0s'. With a default of 1, it would always use 1 as the minimum value, which works perfectly fine. --- docs/changelog_v3.3.x.md | 13 +- gradle/libs.versions.toml | 2 +- .../tech/mcprison/prison/output/Output.java | 19 ++- .../prison/ranks/commands/RanksCommands.java | 8 +- .../prison/spigot/nbt/PrisonNBTUtil.java | 128 ++++++++++++------ 5 files changed, 118 insertions(+), 52 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 2eca77c45..e741aa374 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,12 +14,21 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-beta.18c 2024-08-26 +# 3.3.0-beta.18c 2024-08-27 +* **Bug fixes: With spigot/paper 1.21.1 and the NBT lib that we are using, there were issue that were suddenly occurring that worked fine before.** +Basically, eliminated a lot of generation of stack traces, especially when dealing with NBTs. +Upgraded NBT-lib to v2.13.2 from v2.13.1. +When formatting the rank list, the defaults were set to a value of zero. But if there are no tags on any ranks within a ladder, then the width was being used with a value of zero. This was causing a failure since it cannot left-position anything with a zero width. It was trying to format '%-0s'. With a default of 1, it would always use 1 as the minimum value, which works perfectly fine. -* **New Feature: Support for Bukkit's EntityExplodeEvent which is what the ExcellentEnchantments plugin uses.** +* **Fixed a potential problem with null ranks being loaded within the ladder loaders.** +I cannot find a reason why this was happening, or what data was triggering it, but this fixed the issue by skipping null ranks. + + +* **New Feature: Support for Bukkit's EntityExplodeEvent which is what the ExcellentEnchantments plugin uses.** +owo * **Mine bombs: A lot of various changes and fixes to get them to work better.** This new animation and mine bombs code needs more refinement and adjustments, but it's working far better than what it was. diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0b8045f7d..49bb2cdda 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -39,7 +39,7 @@ junit = "4.12" guava = "31.1-jre" spigotApi = "1.13.2-R0.1-SNAPSHOT" -nbtApi = "2.13.1" +nbtApi = "2.13.2" papi = "2.11.6" vault = "1.7.1" 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 f89c3a5c6..04887921f 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 @@ -350,6 +350,7 @@ else if ( Prison.get() == null || Prison.get().getPlatform() == null ) { * @param message The informational message. May include color codes, but the default is white. */ public void logInfo(String message, Object... args) { + log(message, LogLevel.INFO, args); } @@ -361,8 +362,15 @@ public void logInfo(String message, Object... args) { * @param throwable The exceptions thrown, if any. */ public void logWarn(String message, Throwable... throwable) { - log(message, LogLevel.WARNING); + try { + log(message, LogLevel.WARNING); + } + catch (Exception e) { + log( "Failure: Output.logWarn: failed to log an error message. Retrying without formatting.", LogLevel.ERROR ); + logRaw( message ); + } + if (throwable.length > 0) { Arrays.stream(throwable).forEach(Throwable::printStackTrace); } @@ -376,7 +384,14 @@ public void logWarn(String message, Throwable... throwable) { * @param throwable The exceptions thrown, if any. */ public void logError(String message, Throwable... throwable) { - log(message, LogLevel.ERROR); + + try { + log(message, LogLevel.ERROR); + } + catch (Exception e) { + log( "Failure: Output.logError: failed to log an error message. Retrying without formatting.", LogLevel.ERROR ); + logRaw( message ); + } if (throwable.length > 0) { Arrays.stream(throwable).forEach(Throwable::printStackTrace); 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 9d8739417..f7949cf19 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 @@ -972,9 +972,11 @@ private ChatDisplay listRanksOnLadder( RankLadder ladder, boolean hasPerm, RankP // 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; + // Note: Use a value of 1 as a default since '%-0s' would be a failure. This could happen + // if not tags are defined for any ranks. + int maxRankNameSize = 1; + int maxRankTagNoColorSize = 1; + int maxRankCostSize = 1; for (Rank rank : ladder.getRanks()) { String nameNoColor = Text.stripColor( rank.getName() ); 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 7a2a19ca3..097d23303 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 @@ -49,7 +49,17 @@ public static String getNBTString( ItemStack bukkitStack, String key ) { try { Function gsFnc = nbt -> { - String value = (String) nbt.getString(key); + String value = null; + + try { + Object vObj = nbt.getString(key); + + if ( vObj != null ) { + value = (String) vObj; + } + } + catch (Exception e) { + } // if ( Output.get().isDebug() ) { // Output.get().logInfo( "PrisonNBTUtil.getNBTString():ItemStack: %s", nbt.toString() ); @@ -61,11 +71,13 @@ public static String getNBTString( ItemStack bukkitStack, String key ) { // results = NBT.get(bukkitStack, nbt -> nbt.getString(key)); } catch (Exception e) { - Output.get().logInfo( - "PrisonNBTUtil.getNBTString(): Failure trying to use NBTs. " - + "Contact prison support. The NBT library may need to be updated. [%s]", - e.getMessage() - ); + // ignore exception... these are very common if there are no NBTs on the ItemStack + +// Output.get().logInfo( +// "PrisonNBTUtil.getNBTString(): Failure trying to use NBTs. " +// + "Contact prison support. The NBT library may need to be updated. [%s]", +// e.getMessage() +// ); } return results; @@ -77,16 +89,24 @@ public static String getNBTString( Block bukkitBlock, String key ) { try { Function gsFnc = nbt -> (String) nbt.getString(key); - BlockState blockState = bukkitBlock.getState(); + BlockState blockState = null; + + try { + blockState = bukkitBlock.getState(); + } + catch (Exception e) { + } results = NBT.get(blockState, gsFnc ); } catch (Exception e) { - Output.get().logInfo( - "PrisonNBTUtil.getNBTString(block): Failure trying to use NBTs. " - + "Contact prison support. The NBT library may need to be updated. [%s]", - e.getMessage() - ); + // ignore exception... these are very common if there are no NBTs on the ItemStack + +// Output.get().logInfo( +// "PrisonNBTUtil.getNBTString(block): Failure trying to use NBTs. " +// + "Contact prison support. The NBT library may need to be updated. [%s]", +// e.getMessage() +// ); } return results; @@ -104,11 +124,11 @@ public static void setNBTString( ItemStack bukkitStack, String key, String value // } } catch (Exception e) { - Output.get().logInfo( - "PrisonNBTUtil.setNBTString(): Failure trying to use NBTs. " - + "Contact prison support. The NBT library may need to be updated. [%s]", - e.getMessage() - ); +// Output.get().logInfo( +// "PrisonNBTUtil.setNBTString(): Failure trying to use NBTs. " +// + "Contact prison support. The NBT library may need to be updated. [%s]", +// e.getMessage() +// ); } } @@ -122,11 +142,13 @@ public static boolean getNBTBoolean( ItemStack bukkitStack, String key ) { // results = NBT.get(bukkitStack, nbt -> nbt.getBoolean(key)); } catch (Exception e) { - Output.get().logInfo( - "PrisonNBTUtil.getNBTBoolean(): Failure trying to use NBTs. " - + "Contact prison support. The NBT library may need to be updated. [%s]", - e.getMessage() - ); + // ignore exception... these are very common if there are no NBTs on the ItemStack + +// Output.get().logInfo( +// "PrisonNBTUtil.getNBTBoolean(): Failure trying to use NBTs. " +// + "Contact prison support. The NBT library may need to be updated. [%s]", +// e.getMessage() +// ); } return results; @@ -144,11 +166,11 @@ public static void setNBTBoolean( ItemStack bukkitStack, String key, boolean val // } } catch (Exception e) { - Output.get().logInfo( - "PrisonNBTUtil.setNBTBoolean(): Failure trying to use NBTs. " - + "Contact prison support. The NBT library may need to be updated. [%s]", - e.getMessage() - ); +// Output.get().logInfo( +// "PrisonNBTUtil.setNBTBoolean(): Failure trying to use NBTs. " +// + "Contact prison support. The NBT library may need to be updated. [%s]", +// e.getMessage() +// ); } } @@ -167,7 +189,13 @@ public static int getNBTInt( ItemStack bukkitStack, String key ) { try { Function gsFnc = nbt -> { - Integer value = nbt.getInteger(key); + Integer value = null; + + try { + value = nbt.getInteger(key); + } + catch (Exception e) { + } // if ( Output.get().isDebug() ) { // Output.get().logInfo( "PrisonNBTUtil.getNBTString():ItemStack: %s", nbt.toString() ); @@ -178,11 +206,13 @@ public static int getNBTInt( ItemStack bukkitStack, String key ) { results = NBT.get(bukkitStack, gsFnc ); } catch (Exception e) { - Output.get().logInfo( - "PrisonNBTUtil.getNBTInt(): Failure trying to use NBTs. " - + "Contact prison support. The NBT library may need to be updated. [%s]", - e.getMessage() - ); + // ignore exception... these are very common if there are no NBTs on the ItemStack + +// Output.get().logInfo( +// "PrisonNBTUtil.getNBTInt(): Failure trying to use NBTs. " +// + "Contact prison support. The NBT library may need to be updated. [%s]", +// e.getMessage() +// ); } return results; @@ -201,7 +231,15 @@ public static String getNBTString( Entity entity, String key ) { try { results = NBT.get(entity, nbt -> { - String value = (String) nbt.getString(key); + String value = null; + + try { + Object vObj = nbt.getString(key); + value = (String) vObj; + } + catch (Exception e) { + } + return value; }); @@ -211,11 +249,13 @@ public static String getNBTString( Entity entity, String key ) { // results = NBT.get(bukkitStack, nbt -> nbt.getString(key)); } catch (Exception e) { - Output.get().logInfo( - "PrisonNBTUtil.getNBTString(): Failure trying to use NBTs. " - + "Contact prison support. The NBT library may need to be updated. [%s]", - e.getMessage() - ); + // ignore exception... these are very common if there are no NBTs on the ItemStack + +// Output.get().logInfo( +// "PrisonNBTUtil.getNBTString(): Failure trying to use NBTs. " +// + "Contact prison support. The NBT library may need to be updated. [%s]", +// e.getMessage() +// ); } return results; @@ -232,11 +272,11 @@ public static void setNBTString( Entity entity, String key, String value ) { } } catch (Exception e) { - Output.get().logInfo( - "PrisonNBTUtil.setNBTString(): Failure trying to use NBTs. " - + "Contact prison support. The NBT library may need to be updated. [%s]", - e.getMessage() - ); +// Output.get().logInfo( +// "PrisonNBTUtil.setNBTString(): Failure trying to use NBTs. " +// + "Contact prison support. The NBT library may need to be updated. [%s]", +// e.getMessage() +// ); } } From a21981678971824cd5e65496d7a27188848f4392 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 27 Aug 2024 05:11:14 -0400 Subject: [PATCH 138/323] Material validations: The validation process was generating a ton of warnings for all items and blocks that exist in minecraft, but yet cannot exist in an item stack. Such as wall hangings, water, etc... since they are fixed in the world, and when in itemstacks, they are represented by something else, such as an ItemFrame or a Bucket of Water. I eliminated most errors, but reduced it down to a list of items. Also starting to suppress items that are known not to be ItemStack-able so the list is greatly reduced. Still need to work on suppressing others too. --- docs/changelog_v3.3.x.md | 5 ++ .../mcprison/prison/spigot/SpigotUtil.java | 65 ++++++++++++++++--- 2 files changed, 60 insertions(+), 10 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index e741aa374..1494ae7b0 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-beta.18c 2024-08-27 +* **Material validations: The validation process was generating a ton of warnings for all items and blocks that exist in minecraft, but yet cannot exist in an item stack.** Such as wall hangings, water, etc... since they are fixed in the world, and when in itemstacks, they are represented by something else, such as an ItemFrame or a Bucket of Water. +I eliminated most errors, but reduced it down to a list of items. Also starting to suppress items that are known not to be ItemStack-able so the list is greatly reduced. Still need to work on suppressing others too. + + + * **Bug fixes: With spigot/paper 1.21.1 and the NBT lib that we are using, there were issue that were suddenly occurring that worked fine before.** Basically, eliminated a lot of generation of stack traces, especially when dealing with NBTs. Upgraded NBT-lib to v2.13.2 from v2.13.1. 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 25081584f..eaea2814e 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 @@ -674,21 +674,20 @@ public static HashMap playerInventoryRemoveItem( Player play public static List getAllPlatformBlockTypes() { List blockTypes = new ArrayList<>(); + StringBuilder sb = new StringBuilder(); + for ( XMaterial xMat : XMaterial.values() ) { if ( xMat.isSupported() ) { ItemStack itemStack = null; + + boolean itemStackFailed = false; try { itemStack = xMat.parseItem(); } catch (Exception e) { - Output.get().logInfo( - "Notice: invalid XMaterial type encountered when trying to use 'parseItem()'. %s " + - "Contact prison support. XSeries may need to be updated to support " + - "the current version of spigot. ", - xMat.name() - ); + itemStackFailed = true; } if ( xMat.name().toLowerCase().contains( "_wood" ) ) { @@ -731,17 +730,63 @@ public static List getAllPlatformBlockTypes() { // } // } else { - Output.get().logWarn( "### SpigotUtil.testAllPrisonBlockTypes: " + - "Possible XMaterial FAIL: XMaterial " + xMat.name() + - " is supported for this version, but the XMaterial cannot " + - "be mapped to an actual Material."); + + // NOTE: Wall hangings, water, and potted plants can be placed as blocks, but cannot + // created as ItemStacks: + if ( canItemStackMaterial( xMat ) ) { + + sb.append( xMat.name() ).append( " " ); + } + + +// Output.get().logInfo( +// "Notice: invalid XMaterial type encountered when trying to use 'parseItem()'. %s " + +// "Contact prison support. XSeries may need to be updated to support " + +// "the current version of spigot. ", +// xMat.name() +// ); + } } } + if ( sb.length() > 0 ) { + + Output.get().logInfo( "### SpigotUtil.testAllPrisonBlockTypes: " + + "The following XMaterial items could not generate an ItemStack. " + + "This is not an error. This list could be beneficial if there are any " + + "issues with XMaterial and new versions of Spigot/Paper. " + + "Igoring '*water*', '*wall*', and '*potted*' [%s] ", + sb.toString() ); + } + return blockTypes; } + + public static boolean canItemStackMaterial( Material max ) { + return canItemStackMaterial( max.name() ); + } + + public static boolean canItemStackMaterial( XMaterial max ) { + return canItemStackMaterial( max.name() ); + } + + public static boolean canItemStackMaterial( String name ) { + boolean results = true; + + name = name.toLowerCase(); + + if ( name.contains( "wall") || name.contains( "potted" ) || name.contains( "water" ) || + name.contains("") ) { + + results = false; + } + + return results; + } + + public static List getAllCustomBlockTypes() { List blockTypes = new ArrayList<>(); From f77666082a3daf420dbc73c468a77efed7931775 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 27 Aug 2024 05:12:03 -0400 Subject: [PATCH 139/323] Material validations: The validation process was generating a ton of warnings for all items and blocks that exist in minecraft, but yet cannot exist in an item stack. Such as wall hangings, water, etc... since they are fixed in the world, and when in itemstacks, they are represented by something else, such as an ItemFrame or a Bucket of Water. I eliminated most errors, but reduced it down to a list of items. Also starting to suppress items that are known not to be ItemStack-able so the list is greatly reduced. Still need to work on suppressing others too. --- .../spigot/compat/Spigot_1_13_Blocks.java | 44 +++++++++++++++---- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_13_Blocks.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_13_Blocks.java index f0d86452b..d47d1c1ee 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_13_Blocks.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_13_Blocks.java @@ -15,6 +15,7 @@ import tech.mcprison.prison.internal.block.PrisonBlock; import tech.mcprison.prison.internal.block.PrisonBlockTypes.InternalBlockTypes; import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.spigot.SpigotUtil; import tech.mcprison.prison.spigot.block.SpigotBlock; import tech.mcprison.prison.spigot.block.SpigotItemStack; import tech.mcprison.prison.util.Location; @@ -341,23 +342,50 @@ public BlockTestStats testCountAllBlockTypes() { stats.setMaterialSize( Material.values().length ); + StringBuilder sb = new StringBuilder(); + // go through all available materials: for ( Material mat : Material.values() ) { - // Must create an item stack: - ItemStack iStack = new ItemStack( mat, 1 ); - - if ( iStack != null ) { + try { + // Must create an item stack: + ItemStack iStack = new ItemStack( mat, 1 ); - if ( mat.isBlock() ) { - stats.addCountBlocks(); + if ( iStack != null ) { + + if ( mat.isBlock() ) { + stats.addCountBlocks(); + } + else if ( mat.isItem() ) { + stats.addCountItems(); + } } - else if ( mat.isItem() ) { - stats.addCountItems(); + } + catch (Exception e) { + + // NOTE: Wall hangings, water, and potted plants can be placed as blocks, but cannot + // created as ItemStacks: + if ( SpigotUtil.canItemStackMaterial( mat ) ) { + + sb.append( mat.name() ).append( " " ); } + +// Output.get().logInfo( +// "Notice: The org.bukkit.Material %s could not create an ItemStack. This is not an error, just a notice.", +// mat.name() +// ); } } + if ( sb.length() > 0 ) { + + Output.get().logInfo( "### Spigot_1_13_Blocks.testCountAllBlockTypes: " + + "The following XMaterial items could not generate an ItemStack. " + + "This is not an error. " + + "Igoring '*water*', '*wall*', and '*potted*' [%s] ", + sb.toString() ); + } + return stats; } From a8b55097a253e42d7029e98597633b032fa12cfb Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 27 Aug 2024 19:23:06 -0400 Subject: [PATCH 140/323] Mine bombs: Minor adjustments. There still are changes that are needed, but I'm needing to post a new alpha release before I proceed to wrap up the mine bombs. They are getting very close to working as intended, and I'm wanting to add more features to the bombs, along with changing a few other things too. But for now, a new alpha needs to be pushed out because other issues have been addressed and fixed. --- docs/changelog_v3.3.x.md | 7 ++++ .../bombs/animations/BombAnimationsTask.java | 2 +- .../spigot/api/ExplosiveBlockBreakEvent.java | 2 ++ .../spigot/utils/PrisonBombListener.java | 33 +++++++++++-------- 4 files changed, 30 insertions(+), 14 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 1494ae7b0..5b5b44a53 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-beta.18c 2024-08-27 +* **Mine bombs: Minor adjustments.** +There still are changes that are needed, but I'm needing to post a new alpha release before I proceed to wrap up the mine bombs. +They are getting very close to working as intended, and I'm wanting to add more features to the bombs, along with changing a few other things too. +But for now, a new alpha needs to be pushed out because other issues have been addressed and fixed. + + + * **Material validations: The validation process was generating a ton of warnings for all items and blocks that exist in minecraft, but yet cannot exist in an item stack.** Such as wall hangings, water, etc... since they are fixed in the world, and when in itemstacks, they are represented by something else, such as an ItemFrame or a Bucket of Water. I eliminated most errors, but reduced it down to a list of items. Also starting to suppress items that are known not to be ItemStack-able so the list is greatly reduced. Still need to work on suppressing others too. diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationsTask.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationsTask.java index 18dbf21b7..b20a2be79 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationsTask.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationsTask.java @@ -157,7 +157,7 @@ public void animatorFactory( yaw, pitch ); ba.setAlternateDirections( true ); - ba.setRadiusDelta( 1.0 ); + ba.setRadiusDelta( 2.0 ); getAnimators().add( ba ); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/ExplosiveBlockBreakEvent.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/ExplosiveBlockBreakEvent.java index 6147bebaa..864fd9b41 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/ExplosiveBlockBreakEvent.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/ExplosiveBlockBreakEvent.java @@ -76,6 +76,8 @@ public ExplosiveBlockBreakEvent( Block theBlock, Player player, this.explodedBlocks = explodedBlocks; this.triggeredBy = triggeredBy; + + this.setCancelled( false ); } public ExplosiveBlockBreakEvent( Block theBlock, Player player, List explodedBlocks ) { 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 e228e0882..8ed01ef22 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 @@ -390,22 +390,29 @@ private String checkMineBombItemStack( ItemStack iStack ) { // NOTE: Because we're just checking, do not auto update the itemstack. // NBTItem nbtItem = new NBTItem( event.getItem() ); - String bombName = PrisonNBTUtil.getNBTString( iStack, MineBombs.MINE_BOMBS_NBT_KEY ); -// String ownerUUID = PrisonNBTUtil.getNBTString( iStack, MineBombs.MINE_BOMBS_NBT_OWNER_UUID ); + String bombName = null; - if ( bombName != null && bombName.trim().length() == 0 ) { - bombName = null; - } - else if ( bombName != null ){ + try { + bombName = PrisonNBTUtil.getNBTString( iStack, MineBombs.MINE_BOMBS_NBT_KEY ); +// String ownerUUID = PrisonNBTUtil.getNBTString( iStack, MineBombs.MINE_BOMBS_NBT_OWNER_UUID ); -// if ( Output.get().isDebug() ) { -// Output.get().logInfo( "PrisonBombListener.onInteract (item) " -// + "bombName: &7%s&r &3:: nbt: &r\\Q%s\\E", -// bombName, -// PrisonNBTUtil.nbtDebugString( iStack ).replace("%", "_") -//// (nbtItem == null ? "&a-no-nbt-" : nbtItem.toString()) -// ); + if ( bombName != null && bombName.trim().length() == 0 ) { + bombName = null; + } +// else if ( bombName != null ) { +// +// // if ( Output.get().isDebug() ) { +// // Output.get().logInfo( "PrisonBombListener.onInteract (item) " +// // + "bombName: &7%s&r &3:: nbt: &r\\Q%s\\E", +// // bombName, +// // PrisonNBTUtil.nbtDebugString( iStack ).replace("%", "_") +// //// (nbtItem == null ? "&a-no-nbt-" : nbtItem.toString()) +// // ); +// // } // } + } + catch (Exception e) { + // Ignore... not a mine bomb. } From 380fb7719fad72ea7a75613fdc0e3a0345ccf813 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 27 Aug 2024 23:21:08 -0400 Subject: [PATCH 141/323] ExcellentEnchants: Added support for org.bukkit.event.entity.EntityExplodeEvent. This fixes some issues where the initial changes were not fully finished. --- docs/changelog_v3.3.x.md | 8 +++++- .../prison/mines/features/MineBlockEvent.java | 7 +++++ .../AutoManagerEntityExplodeEvents.java | 26 +++++++++---------- prison-spigot/src/main/resources/plugin.yml | 2 ++ 4 files changed, 29 insertions(+), 14 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 5b5b44a53..605cb1179 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-beta.18c 2024-08-27 + +* **ExcellentEnchants: Added support for org.bukkit.event.entity.EntityExplodeEvent.** +This fixes some issues where the initial changes were not fully finished. + + + * **Mine bombs: Minor adjustments.** There still are changes that are needed, but I'm needing to post a new alpha release before I proceed to wrap up the mine bombs. They are getting very close to working as intended, and I'm wanting to add more features to the bombs, along with changing a few other things too. @@ -46,7 +52,7 @@ owo This new animation and mine bombs code needs more refinement and adjustments, but it's working far better than what it was. -* **Placeholders: Sellall multiplier: Fixed a few issues related to being offline and even OP'd. +* **Placeholders: Sellall multiplier: Fixed a few issues related to being offline and even OP'd.** When offline, it was not able to get an active player object so it was bypassing the sellall multiplier calculations.** Now it can work with bukkit's offline players. And its also able to fallback to using snapshot perms so the sellall calculations at least reflects what it was the last time the player was online. 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 c34a3d527..1bce10fc5 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 @@ -33,6 +33,13 @@ public enum BlockEventType { all, blockBreak, + + /** + * The EntityExplodeEvent is a bukkit event, but other plugins, such as ExcellentEnchants + * will use it too. + */ + EntityExplodeEvent, + TEXplosion, CEXplosion, PEExplosive, // PrisonEnchant: Pulsi_'s plugin diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerEntityExplodeEvents.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerEntityExplodeEvents.java index b5fdfd91b..b7d32e484 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerEntityExplodeEvents.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerEntityExplodeEvents.java @@ -88,7 +88,7 @@ public void onBukkitEntityExplode( EntityExplodeEvent e, BlockBreakPriority bbPr @Override public void initialize() { - String eP = getMessage( AutoFeatures.CrazyEnchantsBlastUseEventPriority ); + String eP = getMessage( AutoFeatures.entityExplodeEventPriority ); BlockBreakPriority bbPriority = BlockBreakPriority.fromString( eP ); setBbPriority( bbPriority ); @@ -99,17 +99,17 @@ public void initialize() { return; } - // Check to see if the class BlastUseEvent even exists: try { - Output.get().logInfo( "AutoManager: checking if loaded: CrazyEnchants" ); + Output.get().logInfo( "AutoManager: checking if loaded: EntityExplodeEvents (ExcellentEnchants, and others)" ); - Class.forName( "me.badbones69.crazyenchantments.api.events.BlastUseEvent", false, - this.getClass().getClassLoader() ); + // This class should always exist, since it's part of core bukkit: + Class.forName( "org.bukkit.event.entity.EntityExplodeEvent", false, + this.getClass().getClassLoader() ); - Output.get().logInfo( "AutoManager: Trying to register CrazyEnchants" ); + Output.get().logInfo( "AutoManager: Trying to register EntityExplodeEvents (ExcellentEnchants, and others)" ); - if ( getBbPriority() != BlockBreakPriority.DISABLED ) { + if ( bbPriority != BlockBreakPriority.DISABLED ) { if ( bbPriority.isComponentCompound() ) { for (BlockBreakPriority subBBPriority : bbPriority.getComponentPriorities()) { @@ -127,11 +127,11 @@ public void initialize() { } catch ( ClassNotFoundException e ) { - // CrazyEnchants is not loaded... so ignore. - Output.get().logInfo( "AutoManager: CrazyEnchants is not loaded" ); + // EntityExplodeEvents (ExcellentEnchants, and others) is not loaded... so ignore. + Output.get().logInfo( "AutoManager: EntityExplodeEvents (ExcellentEnchants, and others) is not loaded" ); } catch ( Exception e ) { - Output.get().logInfo( "AutoManager: CrazyEnchants failed to load. [%s]", e.getMessage() ); + Output.get().logInfo( "AutoManager: EntityExplodeEvents (ExcellentEnchants, and others) failed to load. [%s]", e.getMessage() ); } } @@ -294,8 +294,8 @@ public void handleEntityExplodeEvent( EntityExplodeEvent e, BlockBreakPriority b StringBuilder debugInfo = new StringBuilder(); - debugInfo.append( String.format( "### ** handleBlastUseEvent ** ### " + - "(event: BlastUseEvent, config: %s, priority: %s, canceled: %s) ", + debugInfo.append( String.format( "### ** handleEntityExplodeEvent ** ### " + + "(event: EntityExplodeEvent, config: %s, priority: %s, canceled: %s) ", bbPriority.name(), bbPriority.getBukkitEventPriority().name(), (e.isCancelled() ? "TRUE " : "FALSE") @@ -315,7 +315,7 @@ public void handleEntityExplodeEvent( EntityExplodeEvent e, BlockBreakPriority b // Block bukkitBlock = e.getBlockList().get( 0 ); - BlockEventType eventType = BlockEventType.CEXplosion; + BlockEventType eventType = BlockEventType.EntityExplodeEvent; String triggered = null; diff --git a/prison-spigot/src/main/resources/plugin.yml b/prison-spigot/src/main/resources/plugin.yml index afd56092b..6e6e5fefb 100644 --- a/prison-spigot/src/main/resources/plugin.yml +++ b/prison-spigot/src/main/resources/plugin.yml @@ -56,3 +56,5 @@ softdepend: - CoinsEngineEconomy - SaneEconomy - EdPrison + - ExcellentEnchants + From da03b20fcd0f90d1c9b87ddd21019aaab12837be Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 27 Aug 2024 23:23:55 -0400 Subject: [PATCH 142/323] Release v3.3.0-alpha.18d 2024-08-27 --- 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 605cb1179..51f051a62 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-beta.18c 2024-08-27 +# 3.3.0-alpha.18d 2024-08-27 + + +* **3.3.0-alpha.18d 2024-08-27** diff --git a/gradle.properties b/gradle.properties index ef6eae228..ecb7e4c09 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-beta.18c +version=3.3.0-alpha.18d From c5a5bdfca00fc3c2c236200a6e73534e78ee475d Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 28 Aug 2024 17:02:53 -0400 Subject: [PATCH 143/323] Sellall: Changed '/sellall items inspect' to print everything to the console, and to decode the lore so it shows all of the color codes. This is critical for understanding how lore is setup so you can use the auto features lore settings. --- docs/changelog_v3.3.x.md | 6 +++++- .../spigot/commands/PrisonSpigotSellAllCommands.java | 11 ++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 51f051a62..3e9c2cf47 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.18d 2024-08-27 +# 3.3.0-alpha.18d 2024-08-28 + + +* **Sellall: Changed '/sellall items inspect' to print everything to the console, and to decode the lore so it shows all of the color codes.** +This is critical for understanding how lore is setup so you can use the auto features lore settings. * **3.3.0-alpha.18d 2024-08-27** 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 e4954cfac..697ee1af9 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 @@ -1,6 +1,5 @@ package tech.mcprison.prison.spigot.commands; -import java.lang.reflect.Method; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; @@ -37,6 +36,7 @@ import tech.mcprison.prison.spigot.sellall.SellAllBlockData; import tech.mcprison.prison.spigot.sellall.SellAllUtil; import tech.mcprison.prison.spigot.utils.tasks.PlayerAutoRankupTask; +import tech.mcprison.prison.util.Text; /** * @author GABRYCA @@ -998,7 +998,9 @@ private void sellAllItemInspectCommand(CommandSender sender) { chatDisplay.addText( "Lore:" ); for (String l : lore) { - chatDisplay.addText( " %s", l ); + String loreEscaped = l.replace(Text.COLOR_CHAR, '&'); + + chatDisplay.addText( " %s :: [\\Q%s\\E]", l, loreEscaped ); } } @@ -1068,7 +1070,10 @@ else if ( ench.getClass().getMethod( "getName" ) != null ) { } // chatDisplay.addText( " ", ); - chatDisplay.send( sender );; + chatDisplay.send( sender ); + + // Send to the console too: + chatDisplay.sendtoOutputLogInfo(); } } From 626df4fac96ef27348805cdcbabed5b7d454353d Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 28 Aug 2024 17:13:44 -0400 Subject: [PATCH 144/323] New feature: Mines: Prevent a block from dropping drops! This can be used to setup something like lucky blocks, of which the player does not get paid for this block, nor do they get the block or whatever bukkit would normally drop. The new command is: `/mines block preventDrops help`. This saves the new feature with the mine data, and works with normal pickaxes, explosions, and also with silktouch to prevent the drops. The debug information for block breaks has been updated to properly report on how this is working within handling the events. --- docs/changelog_v3.3.x.md | 7 ++ .../internal/block/PrisonBlockStatusData.java | 31 ++++++- .../mines/commands/MinesBlockCommands.java | 87 ++++++++++++++++++- .../prison/mines/commands/MinesCommands.java | 20 ++++- .../api/PrisonMinesBlockBreakEvent.java | 13 +++ .../autofeatures/AutoManagerFeatures.java | 33 ++++++- .../spigot/block/OnBlockBreakEventCore.java | 40 +++++++-- 7 files changed, 217 insertions(+), 14 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 3e9c2cf47..82c2bb18f 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.18d 2024-08-28 +* **New feature: Mines: Prevent a block from dropping drops!** +This can be used to setup something like lucky blocks, of which the player does not get paid for this block, nor do they get the block or whatever bukkit would normally drop. +The new command is: `/mines block preventDrops help`. +This saves the new feature with the mine data, and works with normal pickaxes, explosions, and also with silktouch to prevent the drops. +The debug information for block breaks has been updated to properly report on how this is working within handling the events. + + * **Sellall: Changed '/sellall items inspect' to print everything to the console, and to decode the lore so it shows all of the color codes.** This is critical for understanding how lore is setup so you can use the auto features lore settings. diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/block/PrisonBlockStatusData.java b/prison-core/src/main/java/tech/mcprison/prison/internal/block/PrisonBlockStatusData.java index 0dab4b8d0..83f3e2040 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/block/PrisonBlockStatusData.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/block/PrisonBlockStatusData.java @@ -42,6 +42,10 @@ public abstract class PrisonBlockStatusData { private boolean gravity = false; + + private boolean preventDrops = false; + + // private transient boolean includeInLayerCalculations; @@ -90,6 +94,9 @@ public PrisonBlockStatusData( this.gravity = checkGravityAffects( blockName ); + this.preventDrops = false; + + // this.includeInLayerCalculations = true; } @@ -144,9 +151,14 @@ public void incrementMiningBlockCount() { } public String toSaveFileFormat() { - return getBlockName() + "-" + getChance() + "-" + getBlockCountTotal() + "-" + - getConstraintMin() + "-" + getConstraintMax() + "-" + - getConstraintExcludeTopLayers() + "-" + getConstraintExcludeBottomLayers(); + return getBlockName() + "-" + + getChance() + "-" + + getBlockCountTotal() + "-" + + getConstraintMin() + "-" + + getConstraintMax() + "-" + + getConstraintExcludeTopLayers() + "-" + + getConstraintExcludeBottomLayers() + "-" + + Boolean.toString( isPreventDrops() ); } @@ -201,6 +213,7 @@ public void parseFromSaveFileFormatStats( String blockString ) { int constraintMax = split.length > 4 ? Integer.parseInt(split[4]) : 0; int constraintExcludeTopLayers = split.length > 5 ? Integer.parseInt(split[5]) : 0; int constraintExcludeBottomLayers = split.length > 6 ? Integer.parseInt(split[6]) : 0; + boolean preventDrops = split.length > 7 ? Boolean.parseBoolean(split[7]) : false; setChance( chance ); setBlockCountTotal( blockCount ); @@ -208,6 +221,7 @@ public void parseFromSaveFileFormatStats( String blockString ) { setConstraintMax( constraintMax ); setConstraintExcludeTopLayers( constraintExcludeTopLayers ); setConstraintExcludeBottomLayers( constraintExcludeBottomLayers ); + setPreventDrops(preventDrops); // if ( blockTypeName.equalsIgnoreCase( "gold_ore" ) ) { // Output.get().logInfo( "### parseFromSaveFile: [" + @@ -257,6 +271,10 @@ public String toPlaceholderString() { .append( " T: " ) .append( total ) ; + if ( isPreventDrops() ) { + sb.append( " NoDrops!" ); + } + return sb.toString(); } @@ -554,6 +572,13 @@ public void setGravity( boolean gravity ) { this.gravity = gravity; } + public boolean isPreventDrops() { + return preventDrops; + } + public void setPreventDrops(boolean preventDrops) { + this.preventDrops = preventDrops; + } + // public boolean isIncludeInLayerCalculations() { 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 304a5a21e..2da38fe43 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 @@ -266,6 +266,13 @@ private void addBlockStats( Mine mine, PrisonBlockStatusData block, PlaceholdersUtil.formattedKmbtSISize( 1.0d * block.getBlockCountTotal(), dFmt, "" ) ) ) .tooltip( "&3T&7otal blocks of this type that have been mined." ); row.addFancy( msg3 ); + + + if ( block.isPreventDrops() ) { + FancyMessage msg4 = new FancyMessage( " &dNoDrops!" ) + .tooltip( "&9This block will not drop anything. &3BlockEvents can be used to reward player."); + row.addFancy( msg4 ); + } // FancyMessage msg4 = new FancyMessage( String.format( (totals ? "&b%-9s" : " &3S: &7%-9s"), // PlaceholdersUtil.formattedKmbtSISize( 1.0d * block.getBlockCountTotal(), dFmt, "" ) ) ) @@ -853,6 +860,81 @@ public void constraintsBlockCommand(CommandSender sender, } + + + + public void preventDropsBlockCommand(CommandSender sender, String mineName, String blockName, + String preventDrops) { + + + setLastMineReferenced(mineName); + + PrisonMines pMines = PrisonMines.getInstance(); + Mine m = pMines.getMine(mineName); + + boolean isPreventDrops = false; + + if ( m == null ) { + sender.sendMessage( + String.format( "&7The specified mine named &3%s &7 does not exist. " + + "Please try again.", + (mineName == null ? "null" : mineName) )); + return; + } + + if ( blockName == null || !m.hasBlock( blockName ) ) { + sender.sendMessage( + String.format( "&7The block name &3%s &7 does not exist in the specified mine. " + + "Please try again.", + (blockName == null ? "null" : blockName) )); + listBlockCommand(sender, m.getTag() ); + return; + } + + if ( preventDrops == null || + !preventDrops.equalsIgnoreCase("true") && !preventDrops.equalsIgnoreCase("false") ) { + sender.sendMessage( + String.format( "&7The parameter 'preventDrops' must be boolean: 'true' or 'false'. " + + "Found: [%s]", + (preventDrops == null ? "null" : preventDrops) )); + listBlockCommand(sender, m.getTag() ); + return; + } + + + isPreventDrops = Boolean.parseBoolean( preventDrops ); + + + PrisonBlockStatusData block = null; + + block = m.getPrisonBlock( blockName ); + + + if ( block.isPreventDrops() == isPreventDrops ) { + sender.sendMessage( + String.format( "&7The specified value prevent drops has not changed. " + + "Please try again." + )); + listBlockCommand(sender, m.getTag() ); + return; + } + + block.setPreventDrops( isPreventDrops ); + + + + pMines.getMineManager().saveMine( m ); + + + String message = String.format( "&7Mine &3%s&7's setting for prevent drops for block &3%s &7has been " + + "set to &3%s.", + m.getTag(), block.getBlockName(), + Boolean.toString(isPreventDrops) ); + + + sender.sendMessage( message ); + + } public void listBlockLayerStatsCommand( CommandSender sender, String mineName ) { @@ -865,12 +947,13 @@ public void listBlockLayerStatsCommand( CommandSender sender, String mineName ) Output.get().logInfo( "Mine %s Block Layer Stats:", m.getName() ); - List layers = m.getTargetBlockStatsPerLevel(); - for ( String layer : layers ) { + List layers = m.getTargetBlockStatsPerLevel(); for ( String layer : layers ) { Output.get().logInfo( " " + layer ); } } } + + } 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 5fe5cb89a..4d4bd25a5 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 @@ -255,7 +255,7 @@ public void listBlockCommand(CommandSender sender, + "read as 'excludeBottom from layers 15 and lower'.") public void constraintsBlockCommand(CommandSender sender, @Arg(name = "mineName", description = "The name of the mine to view.") String mineName, - @Arg(name = "blockNme", description = "The block's name") String blockName, + @Arg(name = "blockName", description = "The block's name") String blockName, @Arg(name = "contraint", description = "Constraint to apply " + "[min max excludeTop excludeBottom]", def = "max") String constraint, @@ -267,6 +267,24 @@ public void constraintsBlockCommand(CommandSender sender, + @Override + @Command(identifier = "mines block preventDrops", permissions = "mines.block", + description = "The specified block will not drop anything. It can be mined, but it will " + + "not result in giving the player anything for mining it. Not even money. " + + "This can be used in combination with block commands to create effects " + + "such as Lucky Blocks.") + public void preventDropsBlockCommand(CommandSender sender, + @Arg(name = "mineName", description = "The name of the mine to view.") String mineName, + @Arg(name = "blockName", description = "The block's name") String blockName, + @Arg(name = "preventDrops", description = "Prevent the block from dropping anything " + + "[true false]", + def = "false") String preventDrops ) { + + super.preventDropsBlockCommand( sender, mineName, blockName, preventDrops ); + } + + + @Command(identifier = "mines create", description = "Creates a new mine, or even a virtual mine. " + 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 415085e15..c1f6d6a40 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 @@ -137,6 +137,8 @@ public class PrisonMinesBlockBreakEvent private List bukkitDrops; + private int preventedDrops; + private List unprocessedRawBlocks; @@ -191,6 +193,8 @@ public PrisonMinesBlockBreakEvent( this.bukkitDrops = new ArrayList<>(); + this.preventedDrops = 0; + this.debugInfo = new StringBuilder(); setDebugColorCodeDebug(); this.debugInfo.append( debugInfo ); @@ -227,6 +231,8 @@ public PrisonMinesBlockBreakEvent( Block theBlock, Player player, this.bukkitDrops = new ArrayList<>(); + this.preventedDrops = 0; + this.debugInfo = debugInfo; this.applyToPlayersBlockCount = true; @@ -430,6 +436,13 @@ public void setBukkitDrops( List drops ) { this.bukkitDrops = drops; } + public int getPreventedDrops() { + return preventedDrops; + } + public void setPreventedDrops(int preventedDrops) { + this.preventedDrops = preventedDrops; + } + public BlockEventType getBlockEventType() { return blockEventType; } 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 5fb9b6e0d..43b7aa2b2 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 @@ -3456,25 +3456,52 @@ private void calculateSilkTouch( PrisonMinesBlockBreakEvent pmEvent ) { List stacks = new ArrayList<>(); + Mine mine = pmEvent.getMine(); + + int preventedDrops = 0; + SpigotBlock sBlock = pmEvent.getSpigotBlock(); + PrisonBlockStatusData statsBlock = mine.getBlockStats(sBlock); String lore = null; - stacks.add( new SpigotItemStack( 1, sBlock, lore) ); + + if ( statsBlock == null || !statsBlock.isPreventDrops() ) { + + stacks.add( new SpigotItemStack( 1, sBlock, lore) ); + } + else { + preventedDrops++; + } for ( SpigotBlock spBlock : pmEvent.getExplodedBlocks() ) { - stacks.add( new SpigotItemStack( 1, spBlock, lore) ); + PrisonBlockStatusData exStatsBlock = mine.getBlockStats(sBlock); + if ( exStatsBlock == null || !exStatsBlock.isPreventDrops() ) { + + stacks.add( new SpigotItemStack( 1, spBlock, lore) ); + } + else { + preventedDrops++; + } } // Merge all of the single quantity item stacks together, then // set as the new drops: pmEvent.setBukkitDrops( mergeDrops( stacks ) ); + if ( preventedDrops > 0 ) { + + pmEvent.setPreventedDrops( pmEvent.getPreventedDrops() + preventedDrops ); + } + int count = 0; for ( SpigotItemStack sItemStack : pmEvent.getBukkitDrops() ) { count += sItemStack.getAmount(); } - String msg = String.format( "(SilkDrops: %d) " , count ); + String msg = String.format( "(SilkDrops: %d%s) " , + count, + (preventedDrops == 0 ? "" : " preventedSilkDrops: " + preventedDrops) + ); pmEvent.getDebugInfo().append( msg ); } 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 30d12655c..114e7998a 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 @@ -491,9 +491,19 @@ protected boolean validateEvent( PrisonMinesBlockBreakEvent pmEvent ) if ( pbBlockHit != null && (matchedBlocks || !matchedBlocks && bypassMatchedBlocks )) { - - // Confirmed the block is correct... so get the drops... - collectBukkitDrops( pmEvent.getBukkitDrops(), targetBlock, pmEvent.getItemInHand(), sBlockHit, pmEvent.getSpigotPlayer() ); + + if ( pbTargetBlock != null && pbTargetBlock.isPreventDrops() ) { + + debugInfo.append( " &dPreventDrops:&b" ) + .append( pbTargetBlock.getBlockName() ) + .append( " " ); + preventedDrops++; + } + else { + + // Confirmed the block is correct... so get the drops... + collectBukkitDrops( pmEvent.getBukkitDrops(), targetBlock, pmEvent.getItemInHand(), sBlockHit, pmEvent.getSpigotPlayer() ); + } // If a chain reaction on explosions, this will prevent the same block from // being processed more than once: @@ -652,8 +662,19 @@ else if ( targetExplodedBlock.isMined() ) { ( matchedExplodedBlocks || !matchedExplodedBlocks && bypassMatchedBlocks ) ) { - // Confirmed the block is correct... so get the drops... - collectBukkitDrops( pmEvent.getBukkitDrops(), targetExplodedBlock, pmEvent.getItemInHand(), sBlockMined, pmEvent.getSpigotPlayer() ); + if ( pBlockMined != null && pBlockMined.isPreventDrops() ) { + + debugInfo.append( " &dPreventDrops:&b" ) + .append( pBlockMined.getBlockName() ) + .append( " " ); + preventedDrops++; + } + else { + + // Confirmed the block is correct... so get the drops... + collectBukkitDrops( pmEvent.getBukkitDrops(), targetExplodedBlock, pmEvent.getItemInHand(), sBlockMined, pmEvent.getSpigotPlayer() ); + } + // If a chain reaction on explosions, this will prevent the same block from // being processed more than once: @@ -748,6 +769,15 @@ else if ( targetExplodedBlock.isMined() ) { pmEvent.setDebugColorCodeDebug(); } + if ( preventedDrops > 0 ) { + + // The prevented drops will be added to total drops later in the processing to + // confirm if the whole event was successful or not. + pmEvent.setPreventedDrops( preventedDrops ); + + debugInfo.append( "TOTAL_PreventedDrops (" + preventedDrops + " ) " ); + } + // Need to compress the drops to eliminate duplicates: pmEvent.setBukkitDrops( mergeDrops( pmEvent.getBukkitDrops() ) ); From a6762d0e6e064ec0c819cd15ca346c3413140324 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 28 Aug 2024 17:20:06 -0400 Subject: [PATCH 145/323] AutoFeatures: Changed the debug logging on block break events and explosions, to better encode them with color so important items stand out better. Plus added logging on features that were not covered before: If a mine reset was triggered, how many block events were submitted. If the blockbreak task is submitted with how many blocks it's changing. If minesweeper was submitted. --- docs/changelog_v3.3.x.md | 6 ++ .../prison/mines/commands/MinesCommands.java | 6 +- .../prison/mines/data/MineScheduler.java | 21 ++++-- .../autofeatures/AutoManagerFeatures.java | 27 ++++---- .../events/AutoManagerBlockBreakEvents.java | 4 +- .../events/AutoManagerCrazyEnchants.java | 4 +- .../AutoManagerEntityExplodeEvents.java | 4 +- .../events/AutoManagerPrisonEnchants.java | 4 +- ...nagerPrisonsExplosiveBlockBreakEvents.java | 4 +- .../AutoManagerRevEnchantsExplosiveEvent.java | 4 +- ...AutoManagerRevEnchantsJackHammerEvent.java | 4 +- .../events/AutoManagerTokenEnchant.java | 4 +- ...toManagerXPrisonExplosionTriggerEvent.java | 4 +- .../AutoManagerXPrisonLayerTriggerEvent.java | 4 +- .../AutoManagerXPrisonNukeTriggerEvent.java | 4 +- .../events/AutoManagerZenchantments.java | 4 +- .../spigot/block/OnBlockBreakEventCore.java | 64 +++++++++++++++---- .../spigot/block/OnBlockBreakMines.java | 60 ++++++++--------- 18 files changed, 145 insertions(+), 87 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 82c2bb18f..1ac6a8c1a 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.18d 2024-08-28 +* **AutoFeatures: Changed the debug logging on block break events and explosions, to better encode them with color so important items stand out better.** +Plus added logging on features that were not covered before: If a mine reset was triggered, how many block events were submitted. +If the blockbreak task is submitted with how many blocks it's changing. +If minesweeper was submitted. + + * **New feature: Mines: Prevent a block from dropping drops!** This can be used to setup something like lucky blocks, of which the player does not get paid for this block, nor do they get the block or whatever bukkit would normally drop. The new command is: `/mines block preventDrops help`. 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 4d4bd25a5..26c36669b 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 @@ -971,7 +971,7 @@ private ChatDisplay mineInfoDetails( CommandSender sender, boolean isMineStats, DecimalFormat dFmt = Prison.get().getDecimalFormatInt(); DecimalFormat fFmt = Prison.get().getDecimalFormat("#,##0.00"); - ChatDisplay chatDisplay = new ChatDisplay("&bMine: &3" + m.getName()); + ChatDisplay chatDisplay = new ChatDisplay("&bMine: &3" + m.getTag()); chatDisplay.addSupportHyperLinkData( "Mine %s", m.getName() ); @@ -1379,7 +1379,7 @@ else if ( cmdPageData.isShowAll() ) { // Include all the blockEvent commands: - ChatDisplay blockEventDisplay = new ChatDisplay("BlockEvent Commands for " + m.getTag()); + ChatDisplay blockEventDisplay = new ChatDisplay("BlockEvent Commands for Mine " + m.getTag()); blockEventDisplay.addText("&8Hover over values for more information and clickable actions."); generateBlockEventListing( m, blockEventDisplay, false ); @@ -5155,7 +5155,7 @@ public void commandList(CommandSender sender, private ChatDisplay minesCommandList( Mine m ) { - ChatDisplay display = new ChatDisplay("ResetCommand for " + m.getName()); + ChatDisplay display = new ChatDisplay("Mine Reset Commands for Mine " + m.getTag()); display.addText("&8Click a command to remove it."); BulletedListComponent.BulletedListBuilder builder = new BulletedListComponent.BulletedListBuilder(); diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineScheduler.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineScheduler.java index 82bbc534e..2e1cc07ec 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineScheduler.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineScheduler.java @@ -555,10 +555,11 @@ private void submitNextAction(double offsetSeconds) { * @param blockCount * @param player */ - public void processBlockBreakEventCommands( PrisonBlock prisonBlock, + public int processBlockBreakEventCommands( PrisonBlock prisonBlock, MineTargetPrisonBlock targetBlock, Player player, BlockEventType eventType, String triggered ) { + int blockEventsRan = 0; // Only one block is processed here: if ( getBlockEvents().size() > 0 ) { @@ -571,14 +572,17 @@ public void processBlockBreakEventCommands( PrisonBlock prisonBlock, for ( MineBlockEvent blockEvent : getBlockEvents() ) { double chance = random.nextDouble() * 100; - processBlockEventDetails( player, prisonBlock, - targetBlock, eventType, chance, blockEvent, triggered, - cmdTasks, ++row ); + blockEventsRan += + processBlockEventDetails( player, prisonBlock, + targetBlock, eventType, chance, blockEvent, triggered, + cmdTasks, ++row ); } PrisonCommandTasks.submitTasks( player, cmdTasks ); } + + return blockEventsRan; } @@ -610,13 +614,14 @@ public void processBlockBreakEventCommands( PrisonBlock prisonBlock, // } // } - private void processBlockEventDetails( Player player, PrisonBlock prisonBlock, + private int processBlockEventDetails( Player player, PrisonBlock prisonBlock, MineTargetPrisonBlock targetBlock, BlockEventType eventType, double chance, MineBlockEvent blockEvent, String triggered, List cmdTasks, int row ) { - + int blockEventsRan = 0; + boolean fireEvent = blockEvent.isFireEvent( chance, eventType, targetBlock, triggered ); @@ -629,6 +634,8 @@ private void processBlockEventDetails( Player player, PrisonBlock prisonBlock, perms == null || perms.trim().length() == 0 ) { + + blockEventsRan++; DecimalFormat dFmt = Prison.get().getDecimalFormat( "#,##0.0000" ); @@ -743,6 +750,8 @@ private void processBlockEventDetails( Player player, PrisonBlock prisonBlock, // } } } + + return blockEventsRan; } @Override 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 43b7aa2b2..faab4d126 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 @@ -36,6 +36,7 @@ import tech.mcprison.prison.cache.PlayerCache; import tech.mcprison.prison.internal.block.PrisonBlock; import tech.mcprison.prison.internal.block.PrisonBlock.PrisonBlockType; +import tech.mcprison.prison.internal.block.PrisonBlockStatusData; import tech.mcprison.prison.mines.data.Mine; import tech.mcprison.prison.output.ChatDisplay; import tech.mcprison.prison.output.Output; @@ -160,7 +161,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}|| &6### ** End Event Debug Info ** ###&3 [" ) .append( (stop - start) / 1000000d ) .append( " ms]" ); @@ -255,7 +256,7 @@ protected EventListenerCancelBy processPMBBEvent(PrisonMinesBlockBreakEvent pmEv if ( pmEvent.getMine() != null || pmEvent.getMine() == null && !isBoolean( AutoFeatures.pickupLimitToMines ) ) { - pmEvent.getDebugInfo().append( "(Fire pmEvent) " ); + pmEvent.getDebugInfo().append( "&2(Fire pmEvent &6*start*&2) &b" ); // 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. @@ -278,7 +279,7 @@ protected EventListenerCancelBy processPMBBEvent(PrisonMinesBlockBreakEvent pmEv pmEvent.setDebugColorCodeWarning(); pmEvent.getDebugInfo().append( - "(Fire pmEvent: PrisonMinesBlockBreakEvent was canceled by another plugin!) " ); + "&2(Fire pmEvent: &dPrisonMinesBlockBreakEvent was canceled by another plugin!&2)&b " ); pmEvent.setDebugColorCodeDebug(); } else { @@ -310,18 +311,18 @@ protected EventListenerCancelBy processPMBBEvent(PrisonMinesBlockBreakEvent pmEv else { pmEvent.setDebugColorCodeWarning(); - pmEvent.getDebugInfo().append( "(fire pmEvent:doAction failed without details) " ); + pmEvent.getDebugInfo().append( "&2(fire pmEvent: &7doAction failed without details&2) &b" ); pmEvent.setDebugColorCodeDebug(); } } - pmEvent.getDebugInfo().append( "(Fire pmEvent completed) " ); + pmEvent.getDebugInfo().append( "&2(Fire pmEvent &6*completed*&2) &b" ); } else { - pmEvent.getDebugInfo().append( "(Fire pmEvent bypassed) " ); + pmEvent.getDebugInfo().append( "&2(Fire pmEvent &6*bypassed*&2) &b" ); } return cancelBy; } @@ -638,7 +639,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 ) { @@ -707,7 +708,7 @@ private int applyAutoEventsDetails( PrisonMinesBlockBreakEvent pmEvent ) { if ( configNormalDrop ) { pmEvent.getDebugInfo() -// .append( "{br}||") +// .append( "{br}|| ") .append( "(&7NormalDrop handling enabled&3: " ) .append( "&7normalDropSmelt&3[" ) .append( configNormalDropSmelt ? "enabled" : @@ -1125,7 +1126,7 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, double amount = SellAllUtil.get().getItemStackValue( pmEvent.getSpigotPlayer(), itemStack ); autosellTotal += amount; -// debugInfo.append( "{br}|| " ); +// debugInfo.append( "{br}|| " ); debugInfo.append( " (&7WARNING: autosell leftovers&3: " + itemStack.getName() + " qty: " + itemStack.getAmount() + " value: " + dFmt.format( amount ) + " - " + @@ -1176,7 +1177,7 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, if ( count > 0 || autosellTotal > 0 ) { -// debugInfo.append( "{br}|| " ); +// debugInfo.append( "{br}|| " ); debugInfo.append( " [&7autoPickupDrops total&3: qty: " + count + " value: " + dFmt.format( autosellTotal ) + " unsellableCount: " + autosellUnsellableCount ); @@ -1260,7 +1261,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. @@ -1317,7 +1318,7 @@ public int calculateNormalDrop( PrisonMinesBlockBreakEvent pmEvent ) { // } -// pmEvent.getDebugInfo().append( "{br}|| " ); +// pmEvent.getDebugInfo().append( "{br}|| " ); double autosellTotal = 0; @@ -1370,7 +1371,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/autofeatures/events/AutoManagerBlockBreakEvents.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java index 79de1dcb8..b3032b796 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,8 +287,8 @@ private void handleBlockBreakEvent( BlockBreakEvent e, BlockBreakPriority bbPrio StringBuilder debugInfo = new StringBuilder(); - debugInfo.append( String.format( "### ** handleBlockBreakEvent ** ### " + - "(event: BlockBreakEvent, config: %s, priority: %s, canceled: %s) ", + debugInfo.append( String.format( "&6### ** handleBlockBreakEvent ** ###&3 " + + "(event: &6BlockBreakEvent&3, config: %s, priority: %s, canceled: %s) ", bbPriority.name(), bbPriority.getBukkitEventPriority().name(), (e.isCancelled() ? "TRUE " : "FALSE") 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 2a0c9ff00..0c6e58232 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 @@ -287,8 +287,8 @@ public void handleBlastUseEvent( BlastUseEvent e, BlockBreakPriority bbPriority StringBuilder debugInfo = new StringBuilder(); - debugInfo.append( String.format( "### ** handleBlastUseEvent ** ### " + - "(event: BlastUseEvent, config: %s, priority: %s, canceled: %s) ", + debugInfo.append( String.format( "&6### ** handleBlastUseEvent ** ###&3 " + + "(event: &6BlastUseEvent&3, config: %s, priority: %s, canceled: %s) ", bbPriority.name(), bbPriority.getBukkitEventPriority().name(), (e.isCancelled() ? "TRUE " : "FALSE") diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerEntityExplodeEvents.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerEntityExplodeEvents.java index b7d32e484..4a1d2eb81 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerEntityExplodeEvents.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerEntityExplodeEvents.java @@ -294,8 +294,8 @@ public void handleEntityExplodeEvent( EntityExplodeEvent e, BlockBreakPriority b StringBuilder debugInfo = new StringBuilder(); - debugInfo.append( String.format( "### ** handleEntityExplodeEvent ** ### " + - "(event: EntityExplodeEvent, config: %s, priority: %s, canceled: %s) ", + debugInfo.append( String.format( "&6### ** handleEntityExplodeEvent ** ###&3 " + + "(event: &3EntityExplodeEvent&3, config: %s, priority: %s, canceled: %s) ", bbPriority.name(), bbPriority.getBukkitEventPriority().name(), (e.isCancelled() ? "TRUE " : "FALSE") 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 4e72d924d..a246d6bf4 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 @@ -466,8 +466,8 @@ public void handlePEExplosionEvent( PEExplosionEvent e, BlockBreakPriority bbPri StringBuilder debugInfo = new StringBuilder(); - debugInfo.append( String.format( "### ** handlePEEExplosionEvent (Pulsi) ** ### " + - "(event: PEExplosionEvent, config: %s, priority: %s, canceled: %s) ", + debugInfo.append( String.format( "&6### ** handlePEEExplosionEvent (Pulsi) ** ###&3 " + + "(event: &6PEExplosionEvent&3, config: %s, priority: %s, canceled: %s) ", bbPriority.name(), bbPriority.getBukkitEventPriority().name(), (e.isCancelled() ? "TRUE " : "FALSE") 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 befc5b33f..15a4b4c1c 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 @@ -254,8 +254,8 @@ protected void handleExplosiveBlockBreakEvent( ExplosiveBlockBreakEvent e, StringBuilder debugInfo = new StringBuilder(); - debugInfo.append( String.format( "### ** handleExplosiveBlockBreakEvent (Prisons's bombs) ** ### " + - "(event: ExplosiveBlockBreakEvent, config: %s, priority: %s, canceled: %s) ", + debugInfo.append( String.format( "&6### ** handleExplosiveBlockBreakEvent (Prisons's bombs) ** ###&3 " + + "(event: &6ExplosiveBlockBreakEvent&3, config: %s, priority: %s, canceled: %s) ", bbPriority.name(), bbPriority.getBukkitEventPriority().name(), (e.isCancelled() ? "TRUE " : "FALSE") 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 2231fb2b0..a6f51cc82 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 @@ -289,8 +289,8 @@ public void handleRevEnchantsExplosiveEvent( ExplosiveEvent e, BlockBreakPriorit StringBuilder debugInfo = new StringBuilder(); - debugInfo.append( String.format( "### ** handleRevEnchantsExplosiveEvent ** ### " + - "(event: ExplosiveEvent, config: %s, priority: %s, canceled: %s) ", + debugInfo.append( String.format( "&6### ** handleRevEnchantsExplosiveEvent ** ###&3 " + + "(event: &6ExplosiveEvent&3, config: %s, priority: %s, canceled: %s) ", bbPriority.name(), bbPriority.getBukkitEventPriority().name(), (e.isCancelled() ? "TRUE " : "FALSE") 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 cadc4736f..f3691b344 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 @@ -297,8 +297,8 @@ public void handleRevEnchantsJackHammerEvent( JackHammerEvent e, BlockBreakPrior StringBuilder debugInfo = new StringBuilder(); - debugInfo.append( String.format( "### ** handleRevEnchantsJackHammerEvent ** ### " + - "(event: JackHammerEvent, config: %s, priority: %s, canceled: %s) ", + debugInfo.append( String.format( "&6### ** handleRevEnchantsJackHammerEvent ** ###&3 " + + "(event: &6JackHammerEvent&3, config: %s, priority: %s, canceled: %s) ", bbPriority.name(), bbPriority.getBukkitEventPriority().name(), (e.isCancelled() ? "TRUE " : "FALSE") 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 5ea2ff076..7d04ea09f 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 @@ -343,8 +343,8 @@ public void handleTEBlockExplodeEvent( TEBlockExplodeEvent e, BlockBreakPriority StringBuilder debugInfo = new StringBuilder(); - debugInfo.append( String.format( "### ** genericBlockExplodeEvent ** ### " + - "(event: TEBlockExplodeEvent, config: %s, priority: %s, canceled: %s) ", + debugInfo.append( String.format( "&6### ** genericBlockExplodeEvent ** ###&3 " + + "(event: &6TEBlockExplodeEvent&3, config: %s, priority: %s, canceled: %s) ", bbPriority.name(), bbPriority.getBukkitEventPriority().name(), (e.isCancelled() ? "TRUE " : "FALSE") 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 758d082b0..f0a329f34 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 @@ -295,8 +295,8 @@ public void handleXPrisonExplosionTriggerEvent( ExplosionTriggerEvent e, BlockBr StringBuilder debugInfo = new StringBuilder(); - debugInfo.append( String.format( "### ** handleXPrisonExplosionTriggerEvent ** ### " + - "(event: ExplosionTriggerEvent, config: %s, priority: %s, canceled: %s) ", + debugInfo.append( String.format( "&6### ** handleXPrisonExplosionTriggerEvent ** ###&3 " + + "(event: &6ExplosionTriggerEvent&3, config: %s, priority: %s, canceled: %s) ", bbPriority.name(), bbPriority.getBukkitEventPriority().name(), (e.isCancelled() ? "TRUE " : "FALSE") 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 6043f5a2b..79fc8844a 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 @@ -295,8 +295,8 @@ public void handleXPrisonLayerTriggerEvent( LayerTriggerEvent e, BlockBreakPrior StringBuilder debugInfo = new StringBuilder(); - debugInfo.append( String.format( "### ** handleXPrisonLayerTriggerEvent ** ### " + - "(event: LayerTriggerEvent, config: %s, priority: %s, canceled: %s) ", + debugInfo.append( String.format( "&6### ** handleXPrisonLayerTriggerEvent ** ###&3 " + + "(event: &6LayerTriggerEvent&3, config: %s, priority: %s, canceled: %s) ", bbPriority.name(), bbPriority.getBukkitEventPriority().name(), (e.isCancelled() ? "TRUE " : "FALSE") 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 2185fc3d5..c6237d13f 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 @@ -295,8 +295,8 @@ public void handleXPrisonNukeTriggerEvent( NukeTriggerEvent e, BlockBreakPriorit StringBuilder debugInfo = new StringBuilder(); - debugInfo.append( String.format( "### ** handleXPrisonNukeTriggerEvent ** ### " + - "(event: NukeTriggerEvent, config: %s, priority: %s, canceled: %s) ", + debugInfo.append( String.format( "&6### ** handleXPrisonNukeTriggerEvent ** ###&3 " + + "(event: &6NukeTriggerEvent&3, config: %s, priority: %s, canceled: %s) ", bbPriority.name(), bbPriority.getBukkitEventPriority().name(), (e.isCancelled() ? "TRUE " : "FALSE") 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 23bfb8643..d2f6c028e 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 @@ -284,8 +284,8 @@ private void handleZenchantmentsBlockBreakEvent( BlockBreakEvent e, BlockBreakPr StringBuilder debugInfo = new StringBuilder(); - debugInfo.append( String.format( "### ** handleZenchantmentsBlockBreakEvent ** ### " + - "(event: BlockBreakEvent, config: %s, priority: %s, canceled: %s) ", + debugInfo.append( String.format( "&6### ** handleZenchantmentsBlockBreakEvent ** ###&3 " + + "(event: &6BlockBreakEvent&3, config: %s, priority: %s, canceled: %s) ", bbPriority.name(), bbPriority.getBukkitEventPriority().name(), (e.isCancelled() ? "TRUE " : "FALSE") 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 114e7998a..3512f8023 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 @@ -237,11 +237,14 @@ protected void doBlockEvents( PrisonMinesBlockBreakEvent pmEvent ) if ( pmEvent.getMine() != null ) { + int blockEventsRan = 0; + // Count the blocks that were mined: countBlocksMined( pmEvent, pmEvent.getTargetBlock() ); // process the prison blockEvents commands: - processPrisonBlockEventCommands( pmEvent, pmEvent.getTargetBlock() ); + blockEventsRan += + processPrisonBlockEventCommands( pmEvent, pmEvent.getTargetBlock() ); for ( MineTargetPrisonBlock teBlock : pmEvent.getTargetExplodedBlocks() ) { @@ -250,13 +253,27 @@ protected void doBlockEvents( PrisonMinesBlockBreakEvent pmEvent ) countBlocksMined( pmEvent, teBlock ); // process the prison blockEvents commands: - processPrisonBlockEventCommands( pmEvent, teBlock ); + blockEventsRan += + processPrisonBlockEventCommands( pmEvent, teBlock ); + } + + if ( blockEventsRan > 0 ) { + pmEvent.getDebugInfo().append( " (&bBlockEvents&3:" ) + .append( blockEventsRan ) + .append( ")" ); } - checkZeroBlockReset( pmEvent.getMine() ); + + if ( pmEvent.getMine().checkZeroBlockReset() ) { + + pmEvent.getDebugInfo().append( " (&dMine Reset was triggered&3)"); + } // Check Mine Sweeper: - checkMineSweeper( pmEvent.getMine() ); + if ( pmEvent.getMine().submitMineSweeperTask() ) { + + pmEvent.getDebugInfo().append( " (&dMineSweeper was submitted&3)"); + } } } @@ -267,6 +284,10 @@ protected void finalizeBreakTheBlocks( PrisonMinesBlockBreakEvent pmEvent ) if ( isBoolean( AutoFeatures.applyBlockBreaksThroughSyncTask ) ) { AutoManagerBreakBlockTask.submitTask( blocks, pmEvent.getMine() ); + + pmEvent.getDebugInfo().append( " (&bbreakBlocks&3:submitTask:" ) + .append( blocks.size() ) + .append( ")" ); } else { @@ -283,6 +304,9 @@ protected void finalizeBreakTheBlocks( PrisonMinesBlockBreakEvent pmEvent ) spigotBlock.setPrisonBlock( PrisonBlock.AIR ); } + pmEvent.getDebugInfo().append( " (&bbreakBlocks&3:" ) + .append( count ) + .append( ":finished)" ); } } @@ -371,7 +395,7 @@ protected boolean validateEvent( PrisonMinesBlockBreakEvent pmEvent ) StringBuilder debugInfo = pmEvent.getDebugInfo(); - debugInfo.append( "{br}|| validateEvent:: " ); + debugInfo.append( "{br}|| validateEvent:: " ); SpigotBlock sBlockHit = pmEvent.getSpigotBlock(); @@ -399,7 +423,10 @@ protected boolean validateEvent( PrisonMinesBlockBreakEvent pmEvent ) boolean hasOriginalBLockIncluded = pmEvent.getBlockEventType() == BlockEventType.CEXplosion || pmEvent.getBlockEventType() == BlockEventType.RevEnExplosion || - pmEvent.getBlockEventType() == BlockEventType.RevEnJackHammer; + pmEvent.getBlockEventType() == BlockEventType.RevEnJackHammer || + pmEvent.getBlockEventType() == BlockEventType.EntityExplodeEvent || + pmEvent.getBlockEventType() == BlockEventType.PEExplosive + ; boolean isExplosionEvent = pmEvent.getUnprocessedRawBlocks().size() > (hasOriginalBLockIncluded ? 0 : 1); @@ -411,6 +438,7 @@ protected boolean validateEvent( PrisonMinesBlockBreakEvent pmEvent ) int monitorNotAir = 0; int noTargetBlock = 0; int blockTypeNotExpected = 0; + int preventedDrops = 0; boolean targetBlockAlreadyMined = false; @@ -1073,7 +1101,7 @@ else if ( results && pmEvent.getBbPriority().isMonitor() && mine != null ) { } -// debugInfo.append( "{br}|| " ); +// debugInfo.append( "{br}|| " ); return results; } @@ -1216,21 +1244,30 @@ private void processPrisonBlockEventCommands( if ( pmEvent.getMine() != null && spigotBlock != null ) { + int blockEventsRan = 0; + Mine mine = pmEvent.getMine(); MineTargetPrisonBlock targetBlock = mine.getTargetPrisonBlock( spigotBlock ); if ( targetBlock != null ) { - processPrisonBlockEventCommands( pmEvent, targetBlock ); + blockEventsRan += + processPrisonBlockEventCommands( pmEvent, targetBlock ); } + + pmEvent.getDebugInfo().append( " (blockEventsRan:" ) + .append( blockEventsRan ) + .append( ")" ); } } - private void processPrisonBlockEventCommands( PrisonMinesBlockBreakEvent pmEvent, + private int processPrisonBlockEventCommands( PrisonMinesBlockBreakEvent pmEvent, MineTargetPrisonBlock targetBlock ) { + int blockEventsRan = 0; + // Do not allow MONITOR or ACCESSMONITOR to process the block events: if ( targetBlock != null && pmEvent.getMine() != null && pmEvent.getBbPriority() != BlockBreakPriority.MONITOR && @@ -1241,7 +1278,7 @@ private void processPrisonBlockEventCommands( PrisonMinesBlockBreakEvent pmEvent SpigotBlock sBlock = (SpigotBlock) targetBlock.getMinedBlock(); PrisonBlock pBlock = sBlock == null ? null : sBlock.getPrisonBlock(); - mine.processBlockBreakEventCommands( pBlock, + blockEventsRan = mine.processBlockBreakEventCommands( pBlock, targetBlock, pmEvent.getSpigotPlayer(), pmEvent.getBlockEventType(), @@ -1249,6 +1286,7 @@ private void processPrisonBlockEventCommands( PrisonMinesBlockBreakEvent pmEvent } + return blockEventsRan; } @@ -1335,7 +1373,11 @@ public boolean applyDropsBlockBreakage( PrisonMinesBlockBreakEvent pmEvent, int // checkZeroBlockReset( pmEvent.getMine() ); // } - if ( totalDrops > 0 ) { + + // NOTE: totalDrops must be greater than zero to have been a success. + // But if there were prevented drops, then they should be included + // in the count since the player was successful in breaking that block. + if ( (totalDrops + pmEvent.getPreventedDrops()) > 0 ) { success = true; } else { 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 f37715d60..378683f87 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 @@ -121,7 +121,7 @@ public String getDebugInfo() { getSpigotBlock().getLocation().toWorldCoordinates(); return String.format( - "{br}|| EventInfo: %s %s Mine: %s %s %s ", + " EventInfo: %s %s Mine: %s %s %s ", getResultsReason().name(), // getBbPriority().name(), getSpigotPlayer().getName(), @@ -520,37 +520,37 @@ else if ( !ignoreBlockReuse && targetBlock.isCounted() ) { // return processEvent; // } - /** - *

If mine is not null, then it will check for a zero-block reset (reset-threshold). - *

- * - * @param mine - */ - public void checkZeroBlockReset( Mine mine ) { - if ( mine != null ) { - - // Checks to see if the mine ran out of blocks, and if it did, then - // it will reset the mine: - mine.checkZeroBlockReset(); - } - } +// /** +// *

If mine is not null, then it will check for a zero-block reset (reset-threshold). +// *

+// * +// * @param mine +// */ +// public void checkZeroBlockReset( Mine mine ) { +// if ( mine != null ) { +// +// // Checks to see if the mine ran out of blocks, and if it did, then +// // it will reset the mine: +// mine.checkZeroBlockReset(); +// } +// } - /** - *

If mine is not null, then it will perform a mine sweeper - * for the mine, if it is enabled. - *

- * - * @param mine - */ - public void checkMineSweeper( Mine mine ) { - if ( mine != null ) { - - // submit a mine sweeper task. It will only run if it is enabled and another - // mine sweeper task has not been submitted. - mine.submitMineSweeperTask(); - } - } +// /** +// *

If mine is not null, then it will perform a mine sweeper +// * for the mine, if it is enabled. +// *

+// * +// * @param mine +// */ +// public void checkMineSweeper( Mine mine ) { +// if ( mine != null ) { +// +// // submit a mine sweeper task. It will only run if it is enabled and another +// // mine sweeper task has not been submitted. +// mine.submitMineSweeperTask(); +// } +// } From 6a918fc63fe34ba6c02248f643439b3a54b88912 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 28 Aug 2024 17:22:26 -0400 Subject: [PATCH 146/323] AutoFeatures: EntityExplodeEvent: Fixed a few issues with how it was setup. Apparently the event can be fired with zero blocks! This now handles that situation and will bypass handling of that event, but it will log a warning in the console. --- docs/changelog_v3.3.x.md | 4 ++++ .../events/AutoManagerEntityExplodeEvents.java | 16 ++++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 1ac6a8c1a..577c73e63 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.18d 2024-08-28 +* **AutoFeatures: EntityExplodeEvent: Fixed a few issues with how it was setup. ** +Apparently the event can be fired with zero blocks! This now handles that situation and will bypass handling of that event, but it will log a warning in the console. + + * **AutoFeatures: Changed the debug logging on block break events and explosions, to better encode them with color so important items stand out better.** Plus added logging on features that were not covered before: If a mine reset was triggered, how many block events were submitted. If the blockbreak task is submitted with how many blocks it's changing. diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerEntityExplodeEvents.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerEntityExplodeEvents.java index 4a1d2eb81..376d431a5 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerEntityExplodeEvents.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerEntityExplodeEvents.java @@ -280,12 +280,24 @@ public void handleEntityExplodeEvent( EntityExplodeEvent e, BlockBreakPriority b Entity bEntity = e.getEntity(); Player bPlayer = bEntity instanceof Player ? (Player) bEntity : null; - if ( bPlayer == null ) { + Block eBlock = e.blockList() != null && e.blockList().size() > 0 ? + e.blockList().get(0) : null; + + if ( bPlayer == null || eBlock == null ) { + + if ( bPlayer != null ) { + String msg = String.format( + "&dEntityExplodeEvent: player [&b%s&d] or eventBlock [&b%s&d] is null. " + + "&2Cannot process event without a player or at least one block. ", + ( bPlayer == null ? "&cnull" : bPlayer.getName() ), + ( eBlock == null ? "&cnull" : eBlock.getType().name() ) ); + Output.get().logInfo( msg ); + } return; // Ignore the event... it's not a player. } MinesEventResults eventResults = ignoreMinesBlockBreakEvent( e, - bPlayer, e.blockList().get( 0 ), + bPlayer, eBlock, bbPriority, true ); if ( eventResults.isIgnoreEvent() ) { From 2851b3477e1d2ea1abc10b12ea12840a044096a8 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 28 Aug 2024 17:27:15 -0400 Subject: [PATCH 147/323] Blocks: Update the list of blocks that can be effected by gravity (fall when disturbed). Added falling_sand, falling_block, suspicious_sand, suspecicious_gravel --- docs/changelog_v3.3.x.md | 4 ++++ .../prison/internal/block/PrisonBlockStatusData.java | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 577c73e63..38d4d64ee 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.18d 2024-08-28 +* **Blocks: Update the list of blocks that can be effected by gravity (fall when disturbed).** +Added falling_sand, falling_block, suspicious_sand, suspecicious_gravel + + * **AutoFeatures: EntityExplodeEvent: Fixed a few issues with how it was setup. ** Apparently the event can be fired with zero blocks! This now handles that situation and will bypass handling of that event, but it will log a warning in the console. diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/block/PrisonBlockStatusData.java b/prison-core/src/main/java/tech/mcprison/prison/internal/block/PrisonBlockStatusData.java index 83f3e2040..1b5a7ed23 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/block/PrisonBlockStatusData.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/block/PrisonBlockStatusData.java @@ -405,6 +405,11 @@ private boolean checkGravityAffects( String blockName ) { case "sand": case "red_sand": + case "falling_sand": + case "falling_block": + case "suspicious_sand": + case "suspicious_gravel": + case "gravel": case "white_concrete_powder": From ce461c8f46b5a48bbcbab33c8470affad7ab70fa Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 29 Aug 2024 04:08:05 -0400 Subject: [PATCH 148/323] Bug fix: If someone deletes the playerCache folder, it was causing failures in trying to create new player cache files. Fixed by using '.mkDirs()' to ensure the path fully exists before creating the temp files. Also eliminated the stack trace and replaced it with a one line entry in the console. --- docs/changelog_v3.3.x.md | 7 +- .../mcprison/prison/cache/CoreCacheFiles.java | 71 ++++++++++++------- 2 files changed, 51 insertions(+), 27 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 38d4d64ee..0ed8c190a 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.18d 2024-08-28 +# 3.3.0-alpha.18d 2024-08-29 + + +* **Bug fix: If someone deletes the playerCache folder, it was causing failures in trying to create new player cache files.** +Fixed by using '.mkDirs()' to ensure the path fully exists before creating the temp files. +Also eliminated the stack trace and replaced it with a one line entry in the console. * **Blocks: Update the list of blocks that can be effected by gravity (fall when disturbed).** diff --git a/prison-core/src/main/java/tech/mcprison/prison/cache/CoreCacheFiles.java b/prison-core/src/main/java/tech/mcprison/prison/cache/CoreCacheFiles.java index 434de38da..39bb18b8e 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/cache/CoreCacheFiles.java +++ b/prison-core/src/main/java/tech/mcprison/prison/cache/CoreCacheFiles.java @@ -228,6 +228,11 @@ public void toJsonFile(CoreCacheData cacheData) { // getPlayerFiles().put( playerFile.getName(), playerFile ); // } + if ( outTemp.mkdirs() ) { + Output.get().logInfo( "CoreCacheFiles.toJsonFile(): Created missing directories: %s", + outTemp.getParentFile().getAbsolutePath() ); + } + boolean success = false; try ( @@ -238,39 +243,53 @@ public void toJsonFile(CoreCacheData cacheData) { success = true; } catch ( JsonIOException | IOException e ) { - e.printStackTrace(); + + String msg = String.format( + "&3CoreCacheFiles.toJsonFile: &6Failure to write to temp file. &3This is probably an " + + "issue with the underlying OS and file system. Did you run out of file storage space? " + + "Please confirm. Tempfile: &6%s&3 OriginalFile: %s Error message: [&6%s&3]", + outTemp.getAbsolutePath(), + playerFile.getAbsolutePath(), + e.getMessage() + ); + + Output.get().logInfo( msg ); } - // If there is a significant change in file size, or the new file is smaller than the - // old, then rename it to a backup and keep it. If it is smaller, then something went wrong - // because player cache data should always increase, with the only exception being - // the player cache. - if ( playerFile.exists() ) { - long pfSize = playerFile.length(); - long tmpSize = outTemp.length(); + if ( success ) { - if ( tmpSize < pfSize ) { - - renamePlayerFileToBU( playerFile ); + // If there is a significant change in file size, or the new file is smaller than the + // old, then rename it to a backup and keep it. If it is smaller, then something went wrong + // because player cache data should always increase, with the only exception being + // the player cache. + if ( playerFile.exists() ) { + long pfSize = playerFile.length(); + long tmpSize = outTemp.length(); + + if ( tmpSize < pfSize ) { + + renamePlayerFileToBU( playerFile ); + } } - } - - if ( success && ( !playerFile.exists() || playerFile.delete()) ) { - outTemp.renameTo( playerFile ); - } - else { - boolean removed = false; - if ( outTemp.exists() ) { - removed = outTemp.delete(); + if ( success && ( !playerFile.exists() || playerFile.delete()) ) { + outTemp.renameTo( playerFile ); + } + else { + + boolean removed = false; + if ( outTemp.exists() ) { + removed = outTemp.delete(); + } + + String message = String.format( + "Unable to rename PlayerCache temp file. It was %sremoved: %s", + (removed ? "" : "not "), outTemp.getAbsolutePath() ); + + Output.get().logWarn( message ); } - - String message = String.format( - "Unable to rename PlayerCache temp file. It was %sremoved: %s", - (removed ? "" : "not "), outTemp.getAbsolutePath() ); - - Output.get().logWarn( message ); } + } } From bfebe85d1af71781fc1a45cce11932f865b0ea6a Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 29 Aug 2024 04:14:26 -0400 Subject: [PATCH 149/323] Added a new feature to the prison versions information: Directory path checks. If a specified directory is missing, it will be created to prevent possible errors in other parts of prison. See last commit. This reports the path, number of directories and files, with the file's total size in that directory. --- docs/changelog_v3.3.x.md | 5 ++ .../prison/spigot/SpigotPlatform.java | 90 ++++++++++++++++++- 2 files changed, 93 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 0ed8c190a..b21a4a528 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.18d 2024-08-29 +* **Added a new feature to the prison versions information: Directory path checks.** +If a specified directory is missing, it will be created to prevent possible errors in other parts of prison. See last commit. +This reports the path, number of directories and files, with the file's total size in that directory. + + * **Bug fix: If someone deletes the playerCache folder, it was causing failures in trying to create new player cache files.** Fixed by using '.mkDirs()' to ensure the path fully exists before creating the temp files. Also eliminated the stack trace and replaced it with a one line entry in the console. 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 360cc67c2..4bc089a62 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 @@ -2609,8 +2609,7 @@ private String formatAFEvent(String description, AutoFeatures autoFeature ) { public void prisonVersionFeatures( ChatDisplay display, boolean isBasic, boolean showLaddersAndRanks ) { - - + List features = getActiveFeatures( showLaddersAndRanks ); if ( features.size() > 0 ) { @@ -2792,9 +2791,96 @@ 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(); + + + // check directory structures: + checkDirectoryStructures( display ); + + } + private void checkDirectoryStructures(ChatDisplay display) { + + + display.addText("."); + display.addText("&7Prison File System Check:"); + + display.addText( checkDirectory( "/" ) ); + display.addText( checkDirectory( "backpacks" ) ); + display.addText( checkDirectory( "backups" ) ); + display.addText( checkDirectory( "data_storage" ) ); + display.addText( checkDirectory( "data_storage/mines" ) ); + display.addText( checkDirectory( "data_storage/playerCache" ) ); + display.addText( checkDirectory( "data_storage/ranksDb" ) ); + display.addText( checkDirectory( "data_storage/ranksDb/ladders" ) ); + display.addText( checkDirectory( "data_storage/ranksDb/players" ) ); + display.addText( checkDirectory( "data_storage/ranksDb/ranks" ) ); + display.addText( checkDirectory( "module_conf" ) ); + + } + + private String checkDirectory( String dirPath ) { + + String pathMask = Prison.get().getDataFolder().getParentFile().getAbsolutePath(); + + File path = new File( Prison.get().getDataFolder(), dirPath ); + boolean pathCreated = path.mkdirs(); + + int countDirs = 0; + int countFiles = 0; + double fileSize = 0; + String fileSizeUnit = ""; + + File[] files = path.listFiles(); + for (File f : files) { + + if ( f.isDirectory() ) { + countDirs++; + } + else if ( f.isFile() ) { + countFiles++; + fileSize += f.length(); + } + } + + if ( fileSize > 0 ) { + fileSizeUnit = "bytes"; + + if ( fileSize >= 1024 ) { + fileSize /= 1024.0; + fileSizeUnit = "KB"; + + if ( fileSize >= 1024 ) { + fileSize /= 1024.0; + fileSizeUnit = "MB"; + + if ( fileSize >= 1024 ) { + fileSize /= 1024.0; + fileSizeUnit = "GB"; + + } + } + } + } + + + + DecimalFormat iFmt = Prison.getDecimalFormatStaticInt(); + DecimalFormat dFmt = Prison.getDecimalFormatStaticDouble(); + String msg = String.format( + " plugins&b%-40s &2dirs: &b%3s &2files: &b%3s &2totalFileSize: &b%7s &3%s %s", + path.getAbsolutePath().replace(pathMask, ""), + iFmt.format( countDirs ), + iFmt.format( countFiles ), + dFmt.format( fileSize ), + fileSizeUnit, + ( pathCreated ? " &6DirCreated!" : "" ) + ); + + return msg; + } + @Override public PlayerUtil getPlayerUtil( UUID playerUuid ) { return new SpigotPlayerUtil( playerUuid ); From 4fba3e6c840586e1351735393ff00ea8630e0cf2 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 29 Aug 2024 04:18:57 -0400 Subject: [PATCH 150/323] Mine bomb: Added more features for control of the animations: radius, radiusDelta, alterateDirections, animation speed, and spin speed, and armorstand item location. This is working pretty good overall, but still needs to do some work on the related spin. --- docs/changelog_v3.3.x.md | 6 ++ .../mcprison/prison/bombs/MineBombData.java | 63 +++++++++++++++++++ .../bombs/MineBombDefaultConfigSettings.java | 11 +++- .../tech/mcprison/prison/bombs/MineBombs.java | 23 +++++++ .../animations/BombAnimationOrbital.java | 22 ++++++- .../bombs/animations/BombAnimations.java | 3 +- .../mcprison/prison/internal/ArmorStand.java | 4 ++ .../tech/mcprison/prison/internal/World.java | 4 +- .../tech/mcprison/prison/util/Location.java | 5 +- .../java/tech/mcprison/prison/TestWorld.java | 6 +- .../mcprison/prison/internal/WorldTest.java | 3 +- .../prison/spigot/game/SpigotWorld.java | 26 +++++--- .../spigot/game/entity/SpigotArmorStand.java | 36 ++++++++++- 13 files changed, 191 insertions(+), 21 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index b21a4a528..417890cef 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.18d 2024-08-29 +* **Mine bomb: Added more features for control of the animations: ** +radius, radiusDelta, alterateDirections, animation speed, and spin speed, and armorstand item location. +This is working pretty good overall, but still needs to do some work on the related spin. + + + * **Added a new feature to the prison versions information: Directory path checks.** If a specified directory is missing, it will be created to prevent possible errors in other parts of prison. See last commit. This reports the path, number of directories and files, with the file's total size in that directory. 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 d3b4d1e3a..c534a8777 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 @@ -6,6 +6,7 @@ import tech.mcprison.prison.Prison; import tech.mcprison.prison.bombs.MineBombEffectsData.EffectType; +import tech.mcprison.prison.bombs.MineBombs.AnimationArmorStandItemLocation; import tech.mcprison.prison.bombs.MineBombs.AnimationPattern; import tech.mcprison.prison.internal.block.Block; import tech.mcprison.prison.internal.block.PrisonBlock; @@ -170,6 +171,13 @@ public class MineBombData private double animationSpeed = 5; + private double animationRadius = 1.0; + private double animationRadiusDelta = 0.0; + private boolean animationAlternateDirections = false; + private float animationSpinSpeed = -35; + + private AnimationArmorStandItemLocation animationArmorStandItemLocation; + private double throwVelocityLow = 1.5; private double throwVelocityHigh = 3; @@ -333,6 +341,17 @@ public MineBombData( String name, String itemType, String explosionShape, this.animationPattern = AnimationPattern.infinity; // setAnimationPattern( AnimationPattern.infinity ); + this.animationSpeed = 5.0; + + this.animationOffset = 0.0; + + this.animationRadius = 1.0; + this.animationRadiusDelta = 0.0; + this.animationAlternateDirections = false; + this.animationSpinSpeed = -35; + + this.animationArmorStandItemLocation = AnimationArmorStandItemLocation.hand; + this.throwVelocityLow = 1.5; this.throwVelocityHigh = 3; @@ -389,6 +408,11 @@ public MineBombData clone() { cloned.setAnimationPattern( getAnimationPattern() ); cloned.setAnimationOffset( getAnimationOffset() ); cloned.setAnimationSpeed( getAnimationSpeed() ); + cloned.setAnimationRadius( getAnimationRadius() ); + cloned.setAnimationRadiusDelta( getAnimationRadiusDelta() ); + cloned.setAnimationAlternateDirections( isAnimationAlternateDirections() ); + cloned.setAnimationSpinSpeed( getAnimationSpinSpeed() ); + cloned.setAnimationArmorStandItemLocation( getAnimationArmorStandItemLocation() ); cloned.setThrowVelocityLow( getThrowVelocityLow() ); @@ -710,6 +734,45 @@ public double getAnimationSpeed() { public void setAnimationSpeed(double animationSpeed) { this.animationSpeed = animationSpeed; } + + public double getAnimationRadius() { + return animationRadius; + } + public void setAnimationRadius(double animationRadius) { + this.animationRadius = animationRadius; + } + + public double getAnimationRadiusDelta() { + return animationRadiusDelta; + } + public void setAnimationRadiusDelta(double animationRadiusDelta) { + this.animationRadiusDelta = animationRadiusDelta; + } + + public boolean isAnimationAlternateDirections() { + return animationAlternateDirections; + } + public void setAnimationAlternateDirections(boolean animationAlternateDirections) { + this.animationAlternateDirections = animationAlternateDirections; + } + + public float getAnimationSpinSpeed() { + return animationSpinSpeed; + } + public void setAnimationSpinSpeed(float animationSpinSpeed) { + this.animationSpinSpeed = animationSpinSpeed; + } + + public AnimationArmorStandItemLocation getAnimationArmorStandItemLocation() { + if ( animationArmorStandItemLocation == null ) { + animationArmorStandItemLocation = AnimationArmorStandItemLocation.hand; + } + return animationArmorStandItemLocation; + } + public void setAnimationArmorStandItemLocation(AnimationArmorStandItemLocation animationItemLocation) { + this.animationArmorStandItemLocation = animationItemLocation == null ? + AnimationArmorStandItemLocation.hand : animationItemLocation; + } public int getTaskId() { return taskId; 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 fce927b8d..774f0faf7 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 @@ -1,6 +1,7 @@ package tech.mcprison.prison.bombs; import tech.mcprison.prison.bombs.MineBombEffectsData.EffectState; +import tech.mcprison.prison.bombs.MineBombs.AnimationArmorStandItemLocation; import tech.mcprison.prison.bombs.MineBombs.AnimationPattern; import tech.mcprison.prison.bombs.MineBombs.ExplosionShape; import tech.mcprison.prison.output.Output; @@ -293,6 +294,7 @@ public void setupDefaultMineBombData(MineBombs mineBombs) mbd.setFuseDelayTicks( 15 * 20 ); // 15 seconds mbd.setAnimationPattern( AnimationPattern.orbital ); + mbd.setAnimationArmorStandItemLocation( AnimationArmorStandItemLocation.head ); mineBombs.getConfigData().getBombs().put( mbd.getName().toLowerCase(), mbd ); } @@ -395,6 +397,7 @@ public void setupDefaultMineBombData(MineBombs mineBombs) mbd.setAnimationPattern( AnimationPattern.orbital ); + mbd.setAnimationArmorStandItemLocation( AnimationArmorStandItemLocation.head ); mineBombs.getConfigData().getBombs().put( mbd.getName().toLowerCase(), mbd ); } @@ -432,6 +435,7 @@ public void setupDefaultMineBombData(MineBombs mineBombs) mbd.setAnimationPattern( AnimationPattern.orbitalEight ); + mbd.setAnimationArmorStandItemLocation( AnimationArmorStandItemLocation.head ); mineBombs.getConfigData().getBombs().put( mbd.getName().toLowerCase(), mbd ); } @@ -442,7 +446,7 @@ public void setupDefaultMineBombData(MineBombs mineBombs) MineBombData mbd = new MineBombData( "starburstBomb", "WHEAT", ExplosionShape.sphere.name(), 2, "This is a bomb?&r" ); - mbd.setDescription("This old bomb is a dud.&r"); + mbd.setDescription("This old bomb is a star!r"); mbd.setNameTag( "&a-=- &4{countdown} &5-=- &7{name} &5-=- &4{countdown} &a-=-&r" ); mbd.setItemName( MineBombData.MINE_BOMB_DEFAULT_ITEM_NAME ); @@ -469,6 +473,11 @@ public void setupDefaultMineBombData(MineBombs mineBombs) mbd.setAnimationPattern( AnimationPattern.starburst ); + mbd.setAnimationRadius( 1.5 ); + mbd.setAnimationRadiusDelta( .75 ); + mbd.setAnimationAlternateDirections( true ); + mbd.setAnimationSpeed( 9.0 ); + mineBombs.getConfigData().getBombs().put( mbd.getName().toLowerCase(), mbd ); } 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 2b07bfae6..508c7950e 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 @@ -141,6 +141,29 @@ public static List asList() } } + public enum AnimationArmorStandItemLocation { + hand, + head; + + public static final AnimationArmorStandItemLocation fromString( String animationItemLocation ) { + AnimationArmorStandItemLocation results = AnimationArmorStandItemLocation.hand; + + if ( animationItemLocation != null ) { + + for (AnimationArmorStandItemLocation ail : values() ) { + if ( ail.name().equalsIgnoreCase( animationItemLocation) ) { + results = ail; + break; + } + } + } + + return results; + } + + } + + /** * DO NOT USE! * This has been set to protected only to be used by diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationOrbital.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationOrbital.java index 60abeb09a..0d5e2cf06 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationOrbital.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationOrbital.java @@ -16,6 +16,7 @@ public class BombAnimationOrbital extends BombAnimations { private double angle = 0.0; private double radius = 1.0; private double radiusDelta = 0; + private float spinValue = 0; private boolean alternateDirections = false; @@ -27,6 +28,10 @@ public BombAnimationOrbital(MineBombData bomb, Location location, this.angle = entityYaw; + this.radius = bomb.getAnimationRadius(); + this.radiusDelta = bomb.getAnimationRadiusDelta(); + + this.alternateDirections = bomb.isAnimationAlternateDirections(); Vector vec = new Vector( bomb.getAnimationOffset(), 0d, bomb.getAnimationOffset()); @@ -62,8 +67,19 @@ else if ( angle < -360 ) { (radiusDelta == 0 ? 0 : radiusDelta * Math.sin( angle / 2d )); - double spinVal = angle * -7d; -// Vector spin = new Vector( spinVal, 0, 0 ); + + spinValue += getBomb().getAnimationSpinSpeed(); + if ( spinValue > 360 ) { + spinValue -= 360; + } + else if ( spinValue < -360 ) { + spinValue += 360; + } + + + +// getArmorStand().get + Vector vector = GeometricShapes.getPointsOnCircleXZ( angle, radi ); @@ -81,7 +97,7 @@ else if ( angle < -360 ) { newLoc.setY( newLoc.getY() - 1 ); // Spin the held item? - newLoc.setYaw( (float) spinVal ); + newLoc.setYaw( (float) spinValue ); // newLoc.setDirection( spin ); getArmorStand().teleport( newLoc ); diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java index 576890fc1..c67ac8c4a 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimations.java @@ -167,7 +167,8 @@ public void initialize() { // If item is null, then armorstand will not spawn with an item // and no arms. armorStand = getOriginalLocation().spawnArmorStand( - (getItem() == null ? null : getBomb().getItemType()) ); + (getItem() == null ? null : getBomb().getItemType()), + getBomb().getAnimationArmorStandItemLocation() ); // armorStand = getOriginalLocation().spawnArmorStand( // null, // (getId() == 0 ? getBomb().getName() : null) ); diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/ArmorStand.java b/prison-core/src/main/java/tech/mcprison/prison/internal/ArmorStand.java index bbada6baf..ec741f0ed 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/ArmorStand.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/ArmorStand.java @@ -19,6 +19,10 @@ public interface ArmorStand public void setItemInHand( ItemStack itemm ); + public ItemStack getHelmet(); + public void setHelmet( ItemStack item ); + + public void setRightArmPose( EulerAngle arm ); public boolean isGlowing(); diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/World.java b/prison-core/src/main/java/tech/mcprison/prison/internal/World.java index d49e60e98..8bcfc85ad 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/World.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/World.java @@ -20,6 +20,7 @@ import java.util.List; +import tech.mcprison.prison.bombs.MineBombs.AnimationArmorStandItemLocation; import tech.mcprison.prison.internal.block.Block; import tech.mcprison.prison.internal.block.MineResetType; import tech.mcprison.prison.internal.block.MineTargetPrisonBlock; @@ -89,7 +90,8 @@ public void setBlocksSynchronously( List tBlocks, public ArmorStand spawnArmorStand( Location location ); - public ArmorStand spawnArmorStand(Location location, String itemType ); + public ArmorStand spawnArmorStand(Location location, String itemType, + AnimationArmorStandItemLocation asLocation ); public int getMaxHeight(); 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 59ada78fa..fea3f5495 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 @@ -21,6 +21,7 @@ import java.text.DecimalFormat; import tech.mcprison.prison.Prison; +import tech.mcprison.prison.bombs.MineBombs.AnimationArmorStandItemLocation; import tech.mcprison.prison.internal.ArmorStand; import tech.mcprison.prison.internal.Entity; import tech.mcprison.prison.internal.EntityType; @@ -340,9 +341,9 @@ public ArmorStand spawnArmorStand() { return getWorld().spawnArmorStand( this ); } - public ArmorStand spawnArmorStand( String itemName ) { + public ArmorStand spawnArmorStand( String itemName, AnimationArmorStandItemLocation asLocation ) { - return getWorld().spawnArmorStand( this, itemName ); + return getWorld().spawnArmorStand( this, itemName, asLocation ); } diff --git a/prison-core/src/test/java/tech/mcprison/prison/TestWorld.java b/prison-core/src/test/java/tech/mcprison/prison/TestWorld.java index 942522818..4b42963f5 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/TestWorld.java +++ b/prison-core/src/test/java/tech/mcprison/prison/TestWorld.java @@ -21,6 +21,7 @@ import java.util.ArrayList; import java.util.List; +import tech.mcprison.prison.bombs.MineBombs.AnimationArmorStandItemLocation; import tech.mcprison.prison.internal.ArmorStand; import tech.mcprison.prison.internal.Entity; import tech.mcprison.prison.internal.EntityType; @@ -91,7 +92,7 @@ public Entity spawnEntity( Location location, EntityType entityType ) { } @Override - public ArmorStand spawnArmorStand(Location location) { + public ArmorStand spawnArmorStand( Location location ) { return null; } @@ -101,7 +102,8 @@ public int getMaxHeight() { } @Override - public ArmorStand spawnArmorStand(Location location, String itemType ) { + public ArmorStand spawnArmorStand( Location location, String itemType, + AnimationArmorStandItemLocation asLocation ) { return null; } diff --git a/prison-core/src/test/java/tech/mcprison/prison/internal/WorldTest.java b/prison-core/src/test/java/tech/mcprison/prison/internal/WorldTest.java index 783c71f42..7834279bf 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/internal/WorldTest.java +++ b/prison-core/src/test/java/tech/mcprison/prison/internal/WorldTest.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.List; +import tech.mcprison.prison.bombs.MineBombs.AnimationArmorStandItemLocation; import tech.mcprison.prison.internal.block.Block; import tech.mcprison.prison.internal.block.MineResetType; import tech.mcprison.prison.internal.block.MineTargetPrisonBlock; @@ -61,7 +62,7 @@ public ArmorStand spawnArmorStand(Location location) { } @Override - public ArmorStand spawnArmorStand(Location location, String itemType ) { + public ArmorStand spawnArmorStand(Location location, String itemType, AnimationArmorStandItemLocation asLocation ) { return null; } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotWorld.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotWorld.java index 36a5113b4..db23cf30f 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotWorld.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotWorld.java @@ -28,6 +28,7 @@ import com.cryptomorin.xseries.XEntityType; import com.cryptomorin.xseries.XMaterial; +import tech.mcprison.prison.bombs.MineBombs.AnimationArmorStandItemLocation; import tech.mcprison.prison.internal.ArmorStand; import tech.mcprison.prison.internal.Entity; import tech.mcprison.prison.internal.EntityType; @@ -289,7 +290,7 @@ public org.bukkit.entity.Entity spawnBukkitEntity( Location location, EntityType } @Override - public ArmorStand spawnArmorStand( Location location ) { + public ArmorStand spawnArmorStand(Location location) { org.bukkit.entity.ArmorStand armorStand = spawnBukkitArmorStand( location ); @@ -327,7 +328,8 @@ public org.bukkit.entity.ArmorStand spawnBukkitArmorStand( Location location ) { @Override - public ArmorStand spawnArmorStand( Location location, String itemType ) { + public ArmorStand spawnArmorStand( Location location, String itemType, + AnimationArmorStandItemLocation asLocation ) { // NOTE: Once spawned, the armor stand is not being teleported back to the @@ -371,9 +373,6 @@ public ArmorStand spawnArmorStand( Location location, String itemType ) { } else { - as.setArms( true ); - -// XMaterial.ARMOR_STAND. XMaterial xMat = XMaterial.matchXMaterial( itemType ).orElse( null ); bItemStack = xMat == null ? null : xMat.parseItem(); @@ -383,12 +382,25 @@ public ArmorStand spawnArmorStand( Location location, String itemType ) { bItemStack = XMaterial.COBBLESTONE.parseItem(); } + + if ( asLocation == AnimationArmorStandItemLocation.hand ) { + + as.setItemInHand(bItemStack); + as.setArms( true ); + +// as.setItem( EquipmentSlot.HAND, bItemStack); + } + else { + as.setHelmet(bItemStack); + + } - as.setItemInHand(bItemStack); -// as.setItem( EquipmentSlot.HAND, bItemStack); } + as.getHelmet(); + as.setHelmet(bItemStack); + // String msg = "SpigotWorld.spawnArmorStand: itemInHand: " + // ( as.getItemInHand() == null ? "null" : as.getItemInHand().toString()) + // " hasArmms: " + as.hasArms() + diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotArmorStand.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotArmorStand.java index a7424c907..2fe6cd813 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotArmorStand.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotArmorStand.java @@ -12,7 +12,8 @@ public class SpigotArmorStand private org.bukkit.entity.ArmorStand bArmorStand; - private SpigotItemStack sItemStack = null; + private SpigotItemStack sHandItemStack = null; + private SpigotItemStack sHelmetItemStack = null; public SpigotArmorStand( org.bukkit.entity.ArmorStand bArmorStand ) { super( bArmorStand ); @@ -127,7 +128,7 @@ public void setRemoveWhenFarAway(boolean removeWhenFarAway) { @Override public ItemStack getItemInHand() { - return sItemStack; + return sHandItemStack; } @Override @@ -135,6 +136,7 @@ public void setItemInHand(ItemStack item) { if ( item == null ) { bArmorStand.setItemInHand( null ); bArmorStand.setArms( false ); + this.sHandItemStack = null; } else { SpigotItemStack sItemStack = @@ -142,7 +144,7 @@ public void setItemInHand(ItemStack item) { (SpigotItemStack) item : new SpigotItemStack( item ) ); - this.sItemStack = sItemStack; + this.sHandItemStack = sItemStack; org.bukkit.inventory.ItemStack bas = sItemStack.getBukkitStack(); @@ -150,6 +152,34 @@ public void setItemInHand(ItemStack item) { bArmorStand.setItemInHand( bas ); } } + + + @Override + public ItemStack getHelmet() { + return sHelmetItemStack; + } + + @Override + public void setHelmet(ItemStack item) { + if ( item == null ) { + bArmorStand.setHelmet( null ); + this.sHelmetItemStack = null; + } + else { + SpigotItemStack sItemStack = + ( item instanceof SpigotItemStack ? + (SpigotItemStack) item : + new SpigotItemStack( item ) ); + + this.sHelmetItemStack = sItemStack; + + org.bukkit.inventory.ItemStack bas = sItemStack.getBukkitStack(); + + bArmorStand.setItemInHand( bas ); + } + } + + @Override public void setRightArmPose(EulerAngle arm) { From 1b040fc3388c69a361ad8cde9415c19e4eef1746 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 30 Aug 2024 01:41:21 -0400 Subject: [PATCH 151/323] Player Cache: Fixed a problem with creating missing directories.... forgot to use the parent of the file, which is the current directory for the player cache files. --- docs/changelog_v3.3.x.md | 5 ++++- .../main/java/tech/mcprison/prison/cache/CoreCacheFiles.java | 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 417890cef..a3c2db797 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.18d 2024-08-29 +# 3.3.0-alpha.18d 2024-08-30 + + +* **Player Cache: Fixed a problem with creating missing directories.... forgot to use the parent of the file, which is the current directory for the player cache files.** * **Mine bomb: Added more features for control of the animations: ** diff --git a/prison-core/src/main/java/tech/mcprison/prison/cache/CoreCacheFiles.java b/prison-core/src/main/java/tech/mcprison/prison/cache/CoreCacheFiles.java index 39bb18b8e..37de84347 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/cache/CoreCacheFiles.java +++ b/prison-core/src/main/java/tech/mcprison/prison/cache/CoreCacheFiles.java @@ -228,7 +228,7 @@ public void toJsonFile(CoreCacheData cacheData) { // getPlayerFiles().put( playerFile.getName(), playerFile ); // } - if ( outTemp.mkdirs() ) { + if ( outTemp.getParentFile().mkdirs() ) { Output.get().logInfo( "CoreCacheFiles.toJsonFile(): Created missing directories: %s", outTemp.getParentFile().getAbsolutePath() ); } From ed50286e1ef0256919883c34e4af5e82fa028c66 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 30 Aug 2024 01:42:51 -0400 Subject: [PATCH 152/323] Moved the Prison File System Check to the PrisonStatsUtil class and got it out of the SpigotPlatform. --- docs/changelog_v3.3.x.md | 4 + .../mcprison/prison/util/PrisonStatsUtil.java | 87 ++++++++++++++++++ .../prison/spigot/SpigotPlatform.java | 92 +------------------ 3 files changed, 95 insertions(+), 88 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index a3c2db797..5f5b15628 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.18d 2024-08-30 +* **Moved the Prison File System Check to the PrisonStatsUtil class and got it out of the SpigotPlatform.** + + + * **Player Cache: Fixed a problem with creating missing directories.... forgot to use the parent of the file, which is the current directory for the player cache files.** 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 1b00164f5..ae397c6c4 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 @@ -132,6 +132,11 @@ public ChatDisplay displayVersion(String options) { boolean showLaddersAndRanks = true; Prison.get().getPlatform().prisonVersionFeatures(display, isBasic, showLaddersAndRanks); + + // check directory structures: + checkDirectoryStructures( display ); + + return display; } @@ -141,6 +146,88 @@ public StringBuilder getSupportSubmitVersionData() { return text; } + + private void checkDirectoryStructures(ChatDisplay display) { + + + display.addText("."); + display.addText("&7Prison File System Check:"); + + display.addText( checkDirectory( "/" ) ); + display.addText( checkDirectory( "backpacks" ) ); + display.addText( checkDirectory( "backups" ) ); + display.addText( checkDirectory( "data_storage" ) ); + display.addText( checkDirectory( "data_storage/mines" ) ); + display.addText( checkDirectory( "data_storage/playerCache" ) ); + display.addText( checkDirectory( "data_storage/ranksDb" ) ); + display.addText( checkDirectory( "data_storage/ranksDb/ladders" ) ); + display.addText( checkDirectory( "data_storage/ranksDb/players" ) ); + display.addText( checkDirectory( "data_storage/ranksDb/ranks" ) ); + display.addText( checkDirectory( "module_conf" ) ); + + } + + private String checkDirectory( String dirPath ) { + + String pathMask = Prison.get().getDataFolder().getParentFile().getAbsolutePath(); + + File path = new File( Prison.get().getDataFolder(), dirPath ); + boolean pathCreated = path.mkdirs(); + + int countDirs = 0; + int countFiles = 0; + double fileSize = 0; + String fileSizeUnit = ""; + + File[] files = path.listFiles(); + for (File f : files) { + + if ( f.isDirectory() ) { + countDirs++; + } + else if ( f.isFile() ) { + countFiles++; + fileSize += f.length(); + } + } + + if ( fileSize > 0 ) { + fileSizeUnit = "bytes"; + + if ( fileSize >= 1024 ) { + fileSize /= 1024.0; + fileSizeUnit = "KB"; + + if ( fileSize >= 1024 ) { + fileSize /= 1024.0; + fileSizeUnit = "MB"; + + if ( fileSize >= 1024 ) { + fileSize /= 1024.0; + fileSizeUnit = "GB"; + + } + } + } + } + + + + DecimalFormat iFmt = Prison.getDecimalFormatStaticInt(); + DecimalFormat dFmt = Prison.getDecimalFormatStaticDouble(); + String msg = String.format( + " &bplugins%-40s &2dirs: &b%3s &2files: &b%3s &2totalFileSize: &b%7s &3%s %s", + path.getAbsolutePath().replace(pathMask, ""), + (countDirs == 0 ? "&3" : "") + iFmt.format( countDirs ), + (countFiles == 0 ? "&3" : "") + iFmt.format( countFiles ), + (fileSize == 0 ? "&3" : "") + dFmt.format( fileSize ), + fileSizeUnit, + ( pathCreated ? " &6DirCreated!" : "" ) + ); + + return msg; + } + public StringBuilder getColorTest() { StringBuilder sb = new StringBuilder(); 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 4bc089a62..af9e04790 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 @@ -2793,93 +2793,11 @@ else if ( !isBasic ) { // new WorldGuardSettings(); - // check directory structures: - checkDirectoryStructures( display ); - + } - private void checkDirectoryStructures(ChatDisplay display) { - - - display.addText("."); - display.addText("&7Prison File System Check:"); - - display.addText( checkDirectory( "/" ) ); - display.addText( checkDirectory( "backpacks" ) ); - display.addText( checkDirectory( "backups" ) ); - display.addText( checkDirectory( "data_storage" ) ); - display.addText( checkDirectory( "data_storage/mines" ) ); - display.addText( checkDirectory( "data_storage/playerCache" ) ); - display.addText( checkDirectory( "data_storage/ranksDb" ) ); - display.addText( checkDirectory( "data_storage/ranksDb/ladders" ) ); - display.addText( checkDirectory( "data_storage/ranksDb/players" ) ); - display.addText( checkDirectory( "data_storage/ranksDb/ranks" ) ); - display.addText( checkDirectory( "module_conf" ) ); - - } - - private String checkDirectory( String dirPath ) { - - String pathMask = Prison.get().getDataFolder().getParentFile().getAbsolutePath(); - - File path = new File( Prison.get().getDataFolder(), dirPath ); - boolean pathCreated = path.mkdirs(); - - int countDirs = 0; - int countFiles = 0; - double fileSize = 0; - String fileSizeUnit = ""; - - File[] files = path.listFiles(); - for (File f : files) { - - if ( f.isDirectory() ) { - countDirs++; - } - else if ( f.isFile() ) { - countFiles++; - fileSize += f.length(); - } - } - - if ( fileSize > 0 ) { - fileSizeUnit = "bytes"; - - if ( fileSize >= 1024 ) { - fileSize /= 1024.0; - fileSizeUnit = "KB"; - - if ( fileSize >= 1024 ) { - fileSize /= 1024.0; - fileSizeUnit = "MB"; - - if ( fileSize >= 1024 ) { - fileSize /= 1024.0; - fileSizeUnit = "GB"; - - } - } - } - } - - - - DecimalFormat iFmt = Prison.getDecimalFormatStaticInt(); - DecimalFormat dFmt = Prison.getDecimalFormatStaticDouble(); - String msg = String.format( - " plugins&b%-40s &2dirs: &b%3s &2files: &b%3s &2totalFileSize: &b%7s &3%s %s", - path.getAbsolutePath().replace(pathMask, ""), - iFmt.format( countDirs ), - iFmt.format( countFiles ), - dFmt.format( fileSize ), - fileSizeUnit, - ( pathCreated ? " &6DirCreated!" : "" ) - ); - - return msg; - } @Override public PlayerUtil getPlayerUtil( UUID playerUuid ) { @@ -2905,14 +2823,12 @@ public String dumpEventListenersBlockBreakEvents() { // NOTE: the use of '..==..' prevents these packages from being shortened. See end of this function. sb.append( "\n" ); - sb.append( "&2NOTE: Prison Block Event Listeners:\n" ); + sb.append( "&2NOTE: Prison's Block-Event Listeners:\n" ); - sb.append( "&2. . Prison Internal BlockBreakEvents: " + + sb.append( "&2. . Prison Internal BlockBreakEvents (non-auto features): " + "tmps.SpigotListener\n" ); sb.append( "&2. . Auto Features: " + - "tmps.ae.AutoManagerBlockBreakEvents$AutoManagerBlockBreakEventListener\n" ); - sb.append( "&2. . Prison's multi-block explosions (bombs): " + - "tmpsae.AutoManagerPrisonsExplosiveBlockBreakEvents$AutoManagerExplosiveBlockBreakEventListener\n" ); + "tmps.ae.AutoManagerBlockBreakEvents$*]\n" ); sb.append( "&2. . Prison Abbrv: '&3tmps.&2' = '&3tech..==..mcprison.prison.spigot.&2' & " + "'&3tmps.ae.&2' = '&3tmps..==..autofeatures.events.&2'\n" ); From b507735bc48b4ee9b89cdb5629f15fe8522c2a36 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 2 Sep 2024 11:01:37 -0400 Subject: [PATCH 153/323] Auto Features: Can now trigger auto pickup, auto smelt, and auto block with the use of enchantments. This adds to the ability to trigger them with Lore and permissions for greater flexibility in working with other plugins. The enchantment names must be the full qualified name as found in the blockbreak debug messages that shows the details for that tool, or you can use `/sellall items inspect` while holding a tool with the enchantment you're interested in using. For example, enable auto features, but keep the globals turned off, then enabled the custom enchantments and add 'minecraft:smelter' to both the auto pickup and auto smelt enchantments. This enchantment is from another enchantment plugin and is not standard, but this is how it's listed. Note that you can also use the same enchantment in more than one option too. --- docs/changelog_v3.3.x.md | 9 ++- .../tech/mcprison/prison/PrisonCommand.java | 25 ++++++++ .../autofeatures/AutoFeaturesFileConfig.java | 34 ++++++++++- .../autofeatures/AutoManagerFeatures.java | 61 ++++++++++++++++++- 4 files changed, 124 insertions(+), 5 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 5f5b15628..92e3f7479 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.18d 2024-08-30 +# 3.3.0-alpha.18d 2024-09-02 + + + +* **Auto Features: Can now trigger auto pickup, auto smelt, and auto block with the use of enchantments.*** +This adds to the ability to trigger them with Lore and permissions for greater flexibility in working with other plugins. +The enchantment names must be the full qualified name as found in the blockbreak debug messages that shows the details for that tool, or you can use `/sellall items inspect` while holding a tool with the enchantment you're interested in using. +For example, enable auto features, but keep the globals turned off, then enabled the custom enchantments and add 'minecraft:smelter' to both the auto pickup and auto smelt enchantments. This enchantment is from another enchantment plugin and is not standard, but this is how it's listed. Note that you can also use the same enchantment in more than one option too. * **Moved the Prison File System Check to the PrisonStatsUtil class and got it out of the SpigotPlatform.** 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 441e7cab1..510b5b28b 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java +++ b/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java @@ -1070,6 +1070,31 @@ public void autoFeaturesInformation(CommandSender sender) { + display.addText( "&b " ); + display.addText( "&b options.lore.isLoreEnabled %s", + afw.isBoolean( AutoFeatures.isLoreEnabled )); + display.addText( "&b options.lore.lorePickupValue %s", + afw.isBoolean( AutoFeatures.lorePickupValue )); + display.addText( "&b options.lore.loreSmeltValue %s", + afw.isBoolean( AutoFeatures.loreSmeltValue )); + display.addText( "&b options.lore.loreBlockValue %s", + afw.isBoolean( AutoFeatures.loreBlockValue )); + + + + + display.addText( "&b " ); + display.addText( "&b options.customEnchants.isCustomEnchantsEnabled %s", + afw.isBoolean( AutoFeatures.isCustomEnchantsEnabled )); + display.addText( "&b options.customEnchants.customEnchantsAutoPickup %s", + afw.isBoolean( AutoFeatures.customEnchantsAutoPickup )); + display.addText( "&b options.customEnchants.customEnchantsAutoSmelt %s", + afw.isBoolean( AutoFeatures.customEnchantsAutoSmelt )); + display.addText( "&b options.customEnchants.customEnchantsAutoBlock %s", + afw.isBoolean( AutoFeatures.customEnchantsAutoBlock )); + + + display.addText( "&b " ); display.addText( "&b options.inventory.includePlayerInventoryWhenSmelting %s", 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 bbd5c22e5..d182ec832 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 @@ -267,7 +267,7 @@ public enum AutoFeatures { permissionAutoSmelt(permissions, "prison.automanager.smelt"), permissionAutoBlock(permissions, "prison.automanager.block"), - permissionAuto__readme(permissions, "If permmissions are enabled, of which they are by default, " + + permissionAuto__readme(permissions, "If permissions are enabled, of which they are enabled by default, " + "and 'isAutoFeaturesEnabled' is enabled, then all OPs will automatically " + "enable auto pickup, auto smelt, and auto block because bukkit will always " + "test 'true' for any permmission when OP'd. There is no way around this, " + @@ -275,6 +275,24 @@ public enum AutoFeatures { "players should not be playing as OP'd. To disable these perms, then " + "use a value of 'disable'."), + + customEnchants(options), + + isCustomEnchantsEnabled(customEnchants, false), + + customEnchantsAutoPickup(customEnchants, "disable"), + customEnchantsAutoSmelt(customEnchants, "disable"), + customEnchantsAutoBlock(customEnchants, "disable"), + + customEnchants__readme(customEnchants, "If customEnchants are enabled, of which they " + + "are disabled by default, " + + "and 'isCustomEnchantsEnabled' is enabled, then Prison can use custom " + + "enchantments to trigger auto pickup, auto smelt, and auto blocking. " + + "Use '/sellall item inspect' to find out what the actual enchantment name " + + "is for easier setup of these features. A value of 'disable' will also prevent " + + "the individual enchantments from being used."), + + lore(options), isLoreEnabled(lore, true), @@ -1216,12 +1234,26 @@ public TreeMap getBstatsDetails() { bStatsDetailBoolean( AutoFeatures.isLoreEnabled, tm ); if ( isFeatureBoolean( AutoFeatures.isLoreEnabled )) { + bStatsDetailBoolean( AutoFeatures.lorePickupValue, tm ); + bStatsDetailBoolean( AutoFeatures.loreSmeltValue, tm ); + bStatsDetailBoolean( AutoFeatures.loreBlockValue, tm ); + bStatsDetailBoolean( AutoFeatures.loreTrackBlockBreakCount, tm ); bStatsDetailBoolean( AutoFeatures.loreDurabiltyResistance, tm ); } + bStatsDetailBoolean( AutoFeatures.isCustomEnchantsEnabled, tm ); + if ( isFeatureBoolean( AutoFeatures.isCustomEnchantsEnabled )) { + + bStatsDetailBoolean( AutoFeatures.customEnchantsAutoPickup, tm ); + bStatsDetailBoolean( AutoFeatures.customEnchantsAutoSmelt, tm ); + bStatsDetailBoolean( AutoFeatures.customEnchantsAutoBlock, tm ); + } + + + bStatsDetailBoolean( AutoFeatures.isCalculateDurabilityEnabled, tm ); bStatsDetailBoolean( AutoFeatures.isPreventToolBreakage, tm ); bStatsDetailBoolean( AutoFeatures.preventToolBreakageThreshold, tm ); 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 faab4d126..59e3335f4 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 @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Map.Entry; import java.util.Random; import java.util.Set; @@ -590,6 +591,19 @@ private int applyAutoEventsDetails( PrisonMinesBlockBreakEvent pmEvent ) { boolean loreSmelt = isLoreEnabled && checkLore( itemInHand, getMessage( AutoFeatures.loreSmeltValue) ); boolean loreBlock = isLoreEnabled && checkLore( itemInHand, getMessage( AutoFeatures.loreBlockValue ) ); + boolean isCustomEnchantEnabled = isBoolean( AutoFeatures.isCustomEnchantsEnabled ); + + boolean enchantsPickup = isCustomEnchantEnabled && checkEnchant( itemInHand, getMessage( AutoFeatures.customEnchantsAutoPickup ) ); + boolean enchantsSmelt = isCustomEnchantEnabled && checkEnchant( itemInHand, getMessage( AutoFeatures.customEnchantsAutoSmelt) ); + boolean enchantsBlock = isCustomEnchantEnabled && checkEnchant( itemInHand, getMessage( AutoFeatures.customEnchantsAutoBlock ) ); + + int enchantsPickupLevel = isCustomEnchantEnabled && enchantsPickup ? + getEnchantLevel( itemInHand, getMessage( AutoFeatures.customEnchantsAutoPickup ) ) : -1; + int enchantsSmeltLevel = isCustomEnchantEnabled && enchantsSmelt ? + getEnchantLevel( itemInHand, getMessage( AutoFeatures.customEnchantsAutoSmelt) ) : -1; + int enchantsBlockLevel = isCustomEnchantEnabled && enchantsBlock ? + getEnchantLevel( itemInHand, getMessage( AutoFeatures.customEnchantsAutoBlock ) ) : -1; + boolean isAutoFeaturesEnabled = isBoolean( AutoFeatures.isAutoFeaturesEnabled ); String permAutoPickup = getMessage( AutoFeatures.permissionAutoPickup ); @@ -622,15 +636,15 @@ private int applyAutoEventsDetails( PrisonMinesBlockBreakEvent pmEvent ) { boolean limit2minesSmelt = isBoolean( AutoFeatures.smeltLimitToMines ); boolean limit2minesBlock = isBoolean( AutoFeatures.blockLimitToMines ); - boolean isAutoPickup = lorePickup || configPickup || permPickup; + boolean isAutoPickup = lorePickup || enchantsPickup || configPickup || permPickup; isAutoPickup = (mine != null || mine == null && !limit2minesPickup) && isAutoPickup; - boolean isAutoSmelt = loreSmelt || configSmelt || permSmelt; + boolean isAutoSmelt = loreSmelt || enchantsSmelt || configSmelt || permSmelt; isAutoSmelt = (mine != null || mine == null && !limit2minesSmelt) && isAutoSmelt; - boolean isAutoBlock = loreBlock || configBlock || permBlock; + boolean isAutoBlock = loreBlock || enchantsPickup || configBlock || permBlock; isAutoBlock = (mine != null || mine == null && !limit2minesBlock) && isAutoBlock; @@ -657,6 +671,7 @@ private int applyAutoEventsDetails( PrisonMinesBlockBreakEvent pmEvent ) { .append( isAutoPickup ? "enabled: " : Output.get().getColorCodeError() + "disabled:" + Output.get().getColorCodeDebug() ) .append( lorePickup ? "lore " : "" ) + .append( enchantsPickup ? "enchant " + enchantsPickupLevel + " " : "" ) .append( permPickup ? "perm " : "" ) .append( configPickup ? "config " : "" ) .append( limit2minesPickup ? "mines" : "noLimit" ) @@ -666,6 +681,7 @@ private int applyAutoEventsDetails( PrisonMinesBlockBreakEvent pmEvent ) { .append( isAutoSmelt ? "enabled: " : Output.get().getColorCodeError() + "disabled:" + Output.get().getColorCodeDebug() ) .append( loreSmelt ? "lore " : "" ) + .append( enchantsSmelt ? "enchant " + enchantsSmeltLevel + " " : "" ) .append( permSmelt ? "perm " : "" ) .append( configSmelt ? "config " : "" ) .append( limit2minesSmelt ? "mines" : "noLimit" ) @@ -676,6 +692,7 @@ private int applyAutoEventsDetails( PrisonMinesBlockBreakEvent pmEvent ) { .append( isAutoBlock ? "enabled: " : Output.get().getColorCodeError() + "disabled:" + Output.get().getColorCodeDebug() ) .append( loreBlock ? "lore " : "" ) + .append( enchantsBlock ? "enchant " + enchantsBlockLevel + " " : "" ) .append( permBlock ? "perm " : "" ) .append( configBlock ? "config " : "" ) .append( limit2minesBlock ? "mines" : "noLimit" ) @@ -791,6 +808,44 @@ private int applyAutoEventsDetails( PrisonMinesBlockBreakEvent pmEvent ) { } + private boolean checkEnchant(SpigotItemStack itemInHand, String enchantmentName) { + boolean results = false; + + Map enchants = itemInHand.getEnchantments(); + + Set enchs = enchants.keySet(); + for (Enchantment enchant : enchs) { + if ( enchant.getKey().toString().equalsIgnoreCase(enchantmentName) ) { + results = true; + break; + } + } + + return results; + } + + + private int getEnchantLevel(SpigotItemStack itemInHand, String enchantmentName) { + int enchantLevel = -1; + + Map enchants = itemInHand.getEnchantments(); + + Set enchs = enchants.keySet(); + for (Enchantment enchant : enchs) { + if ( enchant.getKey().toString().equalsIgnoreCase(enchantmentName) ) { + Integer eLevel = enchants.get(enchant); + if ( eLevel != null ) { + + enchantLevel = eLevel; + } + break; + } + } + + return enchantLevel; + } + + /** *

This function gets called for EACH block that is impacted by the * explosion event. The event may have have a list of blocks, but not all From 6c070f554c391eb9806d32c12cbff38ffc2aacc1 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 4 Sep 2024 23:21:10 -0400 Subject: [PATCH 154/323] Sellall Items: Expanded the number of default sellall items. Can use `/sellall items setDefaults` to add the missing items. --- docs/changelog_v3.3.x.md | 6 +- .../prison/spigot/SpigotPlatform.java | 109 +++++++++++++----- 2 files changed, 82 insertions(+), 33 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 92e3f7479..f5358ecf3 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.18d 2024-09-02 +# 3.3.0-alpha.18d 2024-09-04 +* **Sellall Items: Expanded the number of default sellall items.** +Can use `/sellall items setDefaults` to add the missing items. + + * **Auto Features: Can now trigger auto pickup, auto smelt, and auto block with the use of enchantments.*** This adds to the ability to trigger them with Lore and permissions for greater flexibility in working with other plugins. The enchantment names must be the full qualified name as found in the blockbreak debug messages that shows the details for that tool, or you can use `/sellall items inspect` while holding a tool with the enchantment you're interested in using. 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 af9e04790..316f4c044 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 @@ -1929,46 +1929,91 @@ public List buildBlockListXMaterial() { blockList.add( new SellAllBlockData( XMaterial.COBBLESTONE, 4, true) ); blockList.add( new SellAllBlockData( XMaterial.ANDESITE, 5, true) ); blockList.add( new SellAllBlockData( XMaterial.DIORITE, 6, true) ); - blockList.add( new SellAllBlockData( XMaterial.COAL_ORE, 13, true) ); blockList.add( new SellAllBlockData( XMaterial.GRANITE, 8, true) ); blockList.add( new SellAllBlockData( XMaterial.STONE, 9, true) ); - blockList.add( new SellAllBlockData( XMaterial.IRON_ORE, 18, true) ); blockList.add( new SellAllBlockData( XMaterial.POLISHED_ANDESITE, 7, true) ); - blockList.add( new SellAllBlockData( XMaterial.GOLD_ORE, 45, true) ); - blockList.add( new SellAllBlockData( XMaterial.MOSSY_COBBLESTONE, 29, true) ); - + + blockList.add( new SellAllBlockData( XMaterial.CHARCOAL, 13, true) ); + blockList.add( new SellAllBlockData( XMaterial.COAL, 13, true) ); + blockList.add( new SellAllBlockData( XMaterial.COAL_ORE, 13, true) ); blockList.add( new SellAllBlockData( XMaterial.COAL_BLOCK, 135, true) ); + blockList.add( new SellAllBlockData( XMaterial.DEEPSLATE_COAL_ORE, 13, true) ); + + + blockList.add( new SellAllBlockData( XMaterial.IRON_NUGGET, 2, true) ); + blockList.add( new SellAllBlockData( XMaterial.IRON_ORE, 18, true) ); + blockList.add( new SellAllBlockData( XMaterial.IRON_INGOT, 18, true) ); + blockList.add( new SellAllBlockData( XMaterial.RAW_IRON, 18, true) ); + blockList.add( new SellAllBlockData( XMaterial.RAW_IRON_BLOCK, 162, true) ); + blockList.add( new SellAllBlockData( XMaterial.IRON_BLOCK, 190, true) ); + blockList.add( new SellAllBlockData( XMaterial.DEEPSLATE_IRON_ORE, 18, true) ); - blockList.add( new SellAllBlockData( XMaterial.NETHER_QUARTZ_ORE, 34, true) ); - blockList.add( new SellAllBlockData( XMaterial.LAPIS_ORE, 100, true) ); + blockList.add( new SellAllBlockData( XMaterial.GOLD_NUGGET, 5, true) ); + blockList.add( new SellAllBlockData( XMaterial.GOLD_ORE, 45, true) ); + blockList.add( new SellAllBlockData( XMaterial.GOLD_INGOT, 45, true) ); + blockList.add( new SellAllBlockData( XMaterial.RAW_GOLD, 45, true) ); + blockList.add( new SellAllBlockData( XMaterial.RAW_GOLD_BLOCK, 405, true) ); + blockList.add( new SellAllBlockData( XMaterial.GOLD_BLOCK, 450, true) ); + blockList.add( new SellAllBlockData( XMaterial.DEEPSLATE_GOLD_ORE, 45, true) ); + blockList.add( new SellAllBlockData( XMaterial.NETHER_GOLD_ORE, 45, true) ); + + blockList.add( new SellAllBlockData( XMaterial.COPPER_ORE, 22, true) ); + blockList.add( new SellAllBlockData( XMaterial.RAW_COPPER, 22, true) ); + blockList.add( new SellAllBlockData( XMaterial.RAW_COPPER_BLOCK, 198, true) ); + blockList.add( new SellAllBlockData( XMaterial.COPPER_BLOCK, 198, true) ); + blockList.add( new SellAllBlockData( XMaterial.DEEPSLATE_COPPER_ORE, 22, true) ); - blockList.add( new SellAllBlockData( XMaterial.END_STONE, 14, true ) ); - blockList.add( new SellAllBlockData( XMaterial.IRON_BLOCK, 190, true) ); + blockList.add( new SellAllBlockData( XMaterial.REDSTONE, 45, true) ); blockList.add( new SellAllBlockData( XMaterial.REDSTONE_ORE, 45, true) ); - blockList.add( new SellAllBlockData( XMaterial.DIAMOND_ORE, 200, true) ); + blockList.add( new SellAllBlockData( XMaterial.REDSTONE_BLOCK, 405, true) ); + blockList.add( new SellAllBlockData( XMaterial.DEEPSLATE_REDSTONE_ORE, 45, true) ); - blockList.add( new SellAllBlockData( XMaterial.QUARTZ_BLOCK, 136, true) ); + + blockList.add( new SellAllBlockData( XMaterial.DIAMOND, 222, true) ); + blockList.add( new SellAllBlockData( XMaterial.DIAMOND_ORE, 222, true) ); + blockList.add( new SellAllBlockData( XMaterial.DIAMOND_BLOCK, 1998, true) ); + blockList.add( new SellAllBlockData( XMaterial.DEEPSLATE_DIAMOND_ORE, 222, true) ); + + + blockList.add( new SellAllBlockData( XMaterial.EMERALD, 250, true) ); blockList.add( new SellAllBlockData( XMaterial.EMERALD_ORE, 250, true) ); + blockList.add( new SellAllBlockData( XMaterial.EMERALD_BLOCK, 2250, true) ); + blockList.add( new SellAllBlockData( XMaterial.DEEPSLATE_EMERALD_ORE, 250, true) ); + - blockList.add( new SellAllBlockData( XMaterial.GOLD_BLOCK, 450, true) ); + blockList.add( new SellAllBlockData( XMaterial.PRISMARINE_SHARD, 13, true ) ); blockList.add( new SellAllBlockData( XMaterial.PRISMARINE, 52, true ) ); + blockList.add( new SellAllBlockData( XMaterial.DARK_PRISMARINE, 54, true ) ); - blockList.add( new SellAllBlockData( XMaterial.DARK_PRISMARINE, 54, true ) ); + blockList.add( new SellAllBlockData( XMaterial.LAPIS_ORE, 100, true) ); + blockList.add( new SellAllBlockData( XMaterial.LAPIS_LAZULI, 100, true) ); + blockList.add( new SellAllBlockData( XMaterial.LAPIS_BLOCK, 900, true) ); + blockList.add( new SellAllBlockData( XMaterial.DEEPSLATE_LAPIS_ORE, 100, true) ); - blockList.add( new SellAllBlockData( XMaterial.LAPIS_BLOCK, 950, true) ); - blockList.add( new SellAllBlockData( XMaterial.REDSTONE_BLOCK, 405, true) ); + + blockList.add( new SellAllBlockData( XMaterial.QUARTZ, 34, true) ); + blockList.add( new SellAllBlockData( XMaterial.NETHER_QUARTZ_ORE, 34, true) ); + blockList.add( new SellAllBlockData( XMaterial.QUARTZ_BLOCK, 136, true) ); + blockList.add( new SellAllBlockData( XMaterial.CHISELED_QUARTZ_BLOCK, 136, true) ); + blockList.add( new SellAllBlockData( XMaterial.SMOOTH_QUARTZ, 136, true) ); + + + + blockList.add( new SellAllBlockData( XMaterial.MOSSY_COBBLESTONE, 29, true) ); + + + blockList.add( new SellAllBlockData( XMaterial.END_STONE, 14, true ) ); + blockList.add( new SellAllBlockData( XMaterial.OBSIDIAN, 450, true ) ); - blockList.add( new SellAllBlockData( XMaterial.DIAMOND_BLOCK, 2000, true) ); - blockList.add( new SellAllBlockData( XMaterial.EMERALD_BLOCK, 2250, true) ); @@ -1998,13 +2043,13 @@ public List buildBlockListXMaterial() { - blockList.add( new SellAllBlockData( XMaterial.QUARTZ, 34 ) ); +// blockList.add( new SellAllBlockData( XMaterial.QUARTZ, 34 ) ); blockList.add( new SellAllBlockData( XMaterial.QUARTZ_SLAB, 68) ); - blockList.add( new SellAllBlockData( XMaterial.CHISELED_QUARTZ_BLOCK, 136 ) ); +// blockList.add( new SellAllBlockData( XMaterial.CHISELED_QUARTZ_BLOCK, 136 ) ); blockList.add( new SellAllBlockData( XMaterial.QUARTZ_BRICKS, 136 ) ); blockList.add( new SellAllBlockData( XMaterial.QUARTZ_PILLAR, 136 ) ); - blockList.add( new SellAllBlockData( XMaterial.SMOOTH_QUARTZ, 136 ) ); +// blockList.add( new SellAllBlockData( XMaterial.SMOOTH_QUARTZ, 136 ) ); blockList.add( new SellAllBlockData( XMaterial.SMOOTH_RED_SANDSTONE, 14 ) ); @@ -2012,11 +2057,11 @@ public List buildBlockListXMaterial() { blockList.add( new SellAllBlockData( XMaterial.SMOOTH_STONE, 14 ) ); - blockList.add( new SellAllBlockData( XMaterial.CHARCOAL, 16 ) ); +// blockList.add( new SellAllBlockData( XMaterial.CHARCOAL, 16 ) ); blockList.add( new SellAllBlockData( XMaterial.CRACKED_NETHER_BRICKS, 16 ) ); blockList.add( new SellAllBlockData( XMaterial.CRACKED_STONE_BRICKS, 14 ) ); - blockList.add( new SellAllBlockData( XMaterial.EMERALD, 14 ) ); +// blockList.add( new SellAllBlockData( XMaterial.EMERALD, 14 ) ); blockList.add( new SellAllBlockData( XMaterial.END_STONE_BRICKS, 14 ) ); @@ -2024,7 +2069,7 @@ public List buildBlockListXMaterial() { // BLUE_DYE is used as LAPIS_LAZULI for bukkit v1.8.x etc... - blockList.add( new SellAllBlockData( XMaterial.LAPIS_LAZULI, 14 ) ); +// blockList.add( new SellAllBlockData( XMaterial.LAPIS_LAZULI, 14 ) ); blockList.add( new SellAllBlockData( XMaterial.BLUE_DYE, 14 ) ); blockList.add( new SellAllBlockData( XMaterial.MOSSY_STONE_BRICKS, 14 ) ); @@ -2069,13 +2114,13 @@ public List buildBlockListXMaterial() { - blockList.add( new SellAllBlockData( XMaterial.IRON_NUGGET, 3 ) ); - blockList.add( new SellAllBlockData( XMaterial.IRON_INGOT, 27 ) ); - - blockList.add( new SellAllBlockData( XMaterial.GOLD_NUGGET, 12 ) ); - blockList.add( new SellAllBlockData( XMaterial.GOLD_INGOT, 108 ) ); - - blockList.add( new SellAllBlockData( XMaterial.REDSTONE, 45 ) ); +// blockList.add( new SellAllBlockData( XMaterial.IRON_NUGGET, 3 ) ); +// blockList.add( new SellAllBlockData( XMaterial.IRON_INGOT, 27 ) ); +// +// blockList.add( new SellAllBlockData( XMaterial.GOLD_NUGGET, 12 ) ); +// blockList.add( new SellAllBlockData( XMaterial.GOLD_INGOT, 108 ) ); +// +// blockList.add( new SellAllBlockData( XMaterial.REDSTONE, 45 ) ); blockList.add( new SellAllBlockData( XMaterial.GLOWSTONE, 52 ) ); @@ -2083,8 +2128,8 @@ public List buildBlockListXMaterial() { - blockList.add( new SellAllBlockData( XMaterial.COAL, 15 ) ); - blockList.add( new SellAllBlockData( XMaterial.DIAMOND, 200 ) ); +// blockList.add( new SellAllBlockData( XMaterial.COAL, 15 ) ); +// blockList.add( new SellAllBlockData( XMaterial.DIAMOND, 200 ) ); blockList.add( new SellAllBlockData( XMaterial.SUGAR_CANE, 13 ) ); blockList.add( new SellAllBlockData( XMaterial.SUGAR, 13 ) ); From 3546f27caf03175dd4af35e965b5423aadceadb6 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 4 Sep 2024 23:22:19 -0400 Subject: [PATCH 155/323] Mine block searches: Changed them so if the command is ran from the console, it will list all items without any paging. --- docs/changelog_v3.3.x.md | 2 ++ .../mines/commands/MinesBlockCommands.java | 19 ++++++++++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index f5358ecf3..5736dc3cd 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.18d 2024-09-04 +* **Mine block searches: Changed them so if the command is ran from the console, it will list all items without any paging.** + * **Sellall Items: Expanded the number of default sellall items.** Can use `/sellall items setDefaults` to add the missing items. 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 2da38fe43..a1687677a 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 @@ -569,7 +569,8 @@ public void searchBlockCommand(CommandSender sender, ChatDisplay display = null; display = prisonBlockSearchBuilder(search, page, true, - blockSeachCommand, commandBlockAdd, targetText ); + blockSeachCommand, commandBlockAdd, targetText, + !sender.isPlayer() ); display.send(sender); @@ -592,7 +593,8 @@ public void searchBlockAllCommand(CommandSender sender, ChatDisplay display = null; display = prisonBlockSearchBuilder(search, page, false, - blockSeachCommand, commandBlockAdd, targetText ); + blockSeachCommand, commandBlockAdd, targetText, + !sender.isPlayer() ); display.send(sender); @@ -603,7 +605,8 @@ private ChatDisplay prisonBlockSearchBuilder(String search, String page, boolean restrictToBlocks, String commandBlockSearch, String commandBlockAdd, - String targetText ) + String targetText, + boolean console ) { PrisonBlockTypes prisonBlockTypes = Prison.get().getPlatform().getPrisonBlockTypes(); @@ -635,7 +638,10 @@ private ChatDisplay prisonBlockSearchBuilder(String search, String page, BulletedListComponent.BulletedListBuilder builder = new BulletedListComponent.BulletedListBuilder(); - for ( int i = cmdPageData.getPageStart(); i < cmdPageData.getPageEnd(); i++ ) + + int start = console ? 0 : cmdPageData.getPageStart(); + int end = console ? blocks.size() : cmdPageData.getPageEnd(); + for ( int i = start; i < end; i++ ) { PrisonBlock block = blocks.get(i); FancyMessage msg = @@ -655,7 +661,10 @@ private ChatDisplay prisonBlockSearchBuilder(String search, String page, // This command plus parameters used: // String pageCmd = "/mines block search " + search; - cmdPageData.generatePagedCommandFooter( display ); + if ( !console ) { + + cmdPageData.generatePagedCommandFooter( display ); + } return display; } From de510e55d3ef54c2e0478f9c581a5095444e01cf Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 4 Sep 2024 23:25:30 -0400 Subject: [PATCH 156/323] Startup directory check: Changed where and how the startup directory check is ran so it is actually included on startup, which it was skipping it. --- docs/changelog_v3.3.x.md | 4 ++++ .../src/main/java/tech/mcprison/prison/Prison.java | 11 +++++++++-- .../tech/mcprison/prison/util/PrisonStatsUtil.java | 10 +++++----- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 5736dc3cd..de72158c7 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.18d 2024-09-04 +* **Startup directory check: Changed where and how the startup directory check is ran so it is actually included on startup, which it was skipping it.** + + + * **Mine block searches: Changed them so if the command is ran from the console, it will list all items without any paging.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/Prison.java b/prison-core/src/main/java/tech/mcprison/prison/Prison.java index 3c3e2363a..032486e17 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/Prison.java +++ b/prison-core/src/main/java/tech/mcprison/prison/Prison.java @@ -306,6 +306,9 @@ public boolean init( File dataFolder ) { Output.get().logInfo("Enabling and starting..."); + + //getPrisonStatsUtil().checkDirectoryStructures( ); + // Initialize various parts of the API. The magic happens here :) initManagers(); if (!initMetaDatabase()) { @@ -323,7 +326,8 @@ public boolean init( File dataFolder ) { long stopTime = System.currentTimeMillis(); Output.get() - .logInfo("Enabled &3Prison v%s in %d milliseconds.", getPlatform().getPluginVersion(), + .logInfo("Enabled &3Prison v%s in %d milliseconds.", + getPlatform().getPluginVersion(), (stopTime - startTime)); registerInbuiltTroubleshooters(); @@ -367,12 +371,15 @@ private void sendBanner() { display.addText(""); + + getPrisonStatsUtil().checkDirectoryStructures( display ); + display.sendtoOutputLogInfo(); } public void displaySystemSettings( ChatDisplay display ) { - display.addText("&7Server runtime: %s", Prison.get().getServerRuntimeFormatted() );; + display.addText("&7Server runtime: %s", Prison.get().getServerRuntimeFormatted() ); Runtime runtime = Runtime.getRuntime(); 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 ae397c6c4..dd604581b 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 @@ -147,7 +147,7 @@ public StringBuilder getSupportSubmitVersionData() { } - private void checkDirectoryStructures(ChatDisplay display) { + public void checkDirectoryStructures(ChatDisplay display) { display.addText("."); @@ -216,11 +216,11 @@ else if ( f.isFile() ) { DecimalFormat iFmt = Prison.getDecimalFormatStaticInt(); DecimalFormat dFmt = Prison.getDecimalFormatStaticDouble(); String msg = String.format( - " &bplugins%-40s &2dirs: &b%3s &2files: &b%3s &2totalFileSize: &b%7s &3%s %s", + " &bplugins%-40s &2dirs: %s%3s &2files: %s%3s &2totalFileSize: %s%7s &3%s %s", path.getAbsolutePath().replace(pathMask, ""), - (countDirs == 0 ? "&3" : "") + iFmt.format( countDirs ), - (countFiles == 0 ? "&3" : "") + iFmt.format( countFiles ), - (fileSize == 0 ? "&3" : "") + dFmt.format( fileSize ), + (countDirs == 0 ? "&3" : "&b"), iFmt.format( countDirs ), + (countFiles == 0 ? "&3" : "&b"), iFmt.format( countFiles ), + (fileSize == 0 ? "&3" : "&b"), dFmt.format( fileSize ), fileSizeUnit, ( pathCreated ? " &6DirCreated!" : "" ) ); From c9b1ac1cb751ddee35d8da6bfbe8bf82aa9c497b Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 4 Sep 2024 23:30:11 -0400 Subject: [PATCH 157/323] WorldGuard Region support: Starting to add WorldGuard region support to mines. These initially are intended to help create regions, update regions, and view the regions based upon the mine sizes. There are some default command listings in config.yml so they can be customized and expanded to meet your server's needs. The commands are: `/mines worldGuard region` --- docs/changelog_v3.3.x.md | 6 + .../prison/mines/commands/MinesCommands.java | 418 +++++++++++++++++- .../commands/MinesWorldGuardCommands.java | 11 + prison-spigot/src/main/resources/config.yml | 73 ++- 4 files changed, 486 insertions(+), 22 deletions(-) create mode 100644 prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesWorldGuardCommands.java diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index de72158c7..8fe77f566 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.18d 2024-09-04 +* **WorldGuard Region support: Starting to add WorldGuard region support to mines.** +These initially are intended to help create regions, update regions, and view the regions based upon the mine sizes. +There are some default command listings in config.yml so they can be customized and expanded to meet your server's needs. +The commands are: `/mines worldGuard region` + + * **Startup directory check: Changed where and how the startup directory check is ran so it is actually included on startup, which it was skipping it.** 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 26c36669b..ba7ad0905 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 @@ -75,7 +75,7 @@ * @author Dylan M. Perks */ public class MinesCommands - extends MinesImportCommands { + extends MinesWorldGuardCommands { public MinesCommands() { super( "MinesCommands" ); @@ -5319,4 +5319,420 @@ public void commandAdd(CommandSender sender, } + + @Command(identifier = "mines worldguard region mineInfo", + description = "WorldGuard Regions: shows a mine region info.", + onlyPlayers = false, permissions = "mines.set") + public void commandWorldGuardRegionsMineInfo(CommandSender sender, + @Arg(name = "mineName", description = "mine name") String mineName, + @Arg(name = "playerName", def = "view", + description = "An online player who can run the " + + "world guard region commands. Optional. If no player is " + + "specified and ran from console, it will only list the " + + "commands and will not try to run them.") String playerName, + @Arg(name = "options", def = "view", + description = "Options: default 'view' [view, run]. The option 'view' will generate the " + + "list of commands and display them in the console. The 'run' will submit them " + + "to be ran as the player, who must be online. They will be " + + "teleported to the mine's spawn point to ensure they are in the correct " + + "world.") @Wildcard String options) { + + String cmd = "mineInfo"; + + String wgSetting = "prison-mines.world-guard.mine-region-commands.info"; + + worldGuardRegions( sender, wgSetting, mineName, playerName, options, cmd ); + + } + + @Command(identifier = "mines worldguard region mineDefine", + description = "WorldGuard Regions: define a mine region based upon the mine's size.", + onlyPlayers = false, permissions = "mines.set") + public void commandWorldGuardRegionsMineDefine(CommandSender sender, + @Arg(name = "mineName", description = "mine name") String mineName, + @Arg(name = "playerName", def = "view", + description = "An online player who can run the " + + "world guard region commands. Optional. If no player is " + + "specified and ran from console, it will only list the " + + "commands and will not try to run them.") String playerName, + @Arg(name = "options", def = "view", + description = "Options: default 'view' [view, run]. The option 'view' will generate the " + + "list of commands and display them in the console. The 'run' will submit them " + + "to be ran as the player, who must be online. They will be " + + "teleported to the mine's spawn point to ensure they are in the correct " + + "world.") @Wildcard String options) { + + String cmd = "mineDefine"; + + String wgSetting = "prison-mines.world-guard.mine-region-commands.define"; + + worldGuardRegions( sender, wgSetting, mineName, playerName, options, cmd ); + } + + @Command(identifier = "mines worldguard region mineRedefine", + description = "WorldGuard Regions: define a mine region based upon the mine's size.", + onlyPlayers = false, permissions = "mines.set") + public void commandWorldGuardRegionsMineRedfine(CommandSender sender, + @Arg(name = "mineName", description = "mine name") String mineName, + @Arg(name = "playerName", def = "view", + description = "An online player who can run the " + + "world guard region commands. Optional. If no player is " + + "specified and ran from console, it will only list the " + + "commands and will not try to run them.") String playerName, + @Arg(name = "options", def = "view", + description = "Options: default 'view' [view, run]. The option 'view' will generate the " + + "list of commands and display them in the console. The 'run' will submit them " + + "to be ran as the player, who must be online. They will be " + + "teleported to the mine's spawn point to ensure they are in the correct " + + "world.") @Wildcard String options) { + + String cmd = "mineRedefine"; + + String wgSetting = "prison-mines.world-guard.mine-region-commands.redefine"; + + worldGuardRegions( sender, wgSetting, mineName, playerName, options, cmd ); + } + + + @Command(identifier = "mines worldguard region mineSelect", + description = "WorldGuard Regions: select a mine region", + onlyPlayers = false, permissions = "mines.set") + public void commandWorldGuardRegionsMineSelect(CommandSender sender, + @Arg(name = "mineName", description = "mine name") String mineName, + @Arg(name = "playerName", def = "view", + description = "An online player who can run the " + + "world guard region commands. Optional. If no player is " + + "specified and ran from console, it will only list the " + + "commands and will not try to run them.") String playerName, + @Arg(name = "options", def = "view", + description = "Options: default 'view' [view, run]. The option 'view' will generate the " + + "list of commands and display them in the console. The 'run' will submit them " + + "to be ran as the player, who must be online. They will be " + + "teleported to the mine's spawn point to ensure they are in the correct " + + "world.") @Wildcard String options) { + + String cmd = "mineSelect"; + + String wgSetting = "prison-mines.world-guard.mine-region-commands.select"; + + worldGuardRegions( sender, wgSetting, mineName, playerName, options, cmd ); + } + + + @Command(identifier = "mines worldguard region globalInfo", + description = "WorldGuard Regions: info on the global region '__global__'.", + onlyPlayers = false, permissions = "mines.set") + public void commandWorldGuardRegionsGlobalInfo(CommandSender sender, + @Arg(name = "playerName", def = "view", + description = "An online player who can run the " + + "world guard region commands. Optional. If no player is " + + "specified and ran from console, it will only list the " + + "commands and will not try to run them.") String playerName, + @Arg(name = "options", def = "view", + description = "Options: default 'view' [view, run]. The option 'view' will generate the " + + "list of commands and display them in the console. The 'run' will submit them " + + "to be ran as the player, who must be online. They will be " + + "teleported to the mine's spawn point to ensure they are in the correct " + + "world.") @Wildcard String options) { + + String cmd = "globalInfo"; + + String wgSetting = "prison-mines.world-guard.global-region-commands.info"; + + String mineName = "*global*"; + + worldGuardRegions( sender, wgSetting, mineName, playerName, options, cmd ); + } + + + @Command(identifier = "mines worldguard region globalDefine", + description = "WorldGuard Regions: define the global region '__global__' based " + + "upon the config settings within config.yml..", + onlyPlayers = false, permissions = "mines.set") + public void commandWorldGuardRegionsGlobalDefine(CommandSender sender, + @Arg(name = "playerName", def = "view", + description = "An online player who can run the " + + "world guard region commands. Optional. If no player is " + + "specified and ran from console, it will only list the " + + "commands and will not try to run them.") String playerName, + @Arg(name = "options", def = "view", + description = "Options: default 'view' [view, run]. The option 'view' will generate the " + + "list of commands and display them in the console. The 'run' will submit them " + + "to be ran as the player, who must be online. They will be " + + "teleported to the mine's spawn point to ensure they are in the correct " + + "world.") @Wildcard String options) { + + String cmd = "globalDefine"; + + String wgSetting = "prison-mines.world-guard.global-region-commands.define"; + + String mineName = "*global*"; + + worldGuardRegions( sender, wgSetting, mineName, playerName, options, cmd ); + } + + @Command(identifier = "mines worldguard region globalMobSpawningDeny", + description = "WorldGuard Regions: prevent mob spawning using global region '__global__' based " + + "upon the config settings within config.yml..", + onlyPlayers = false, permissions = "mines.set") + public void commandWorldGuardRegionsGlobalMobSpawningDeny(CommandSender sender, + @Arg(name = "playerName", def = "view", + description = "An online player who can run the " + + "world guard region commands. Optional. If no player is " + + "specified and ran from console, it will only list the " + + "commands and will not try to run them.") String playerName, + @Arg(name = "options", def = "view", + description = "Options: default 'view' [view, run]. The option 'view' will generate the " + + "list of commands and display them in the console. The 'run' will submit them " + + "to be ran as the player, who must be online. They will be " + + "teleported to the mine's spawn point to ensure they are in the correct " + + "world.") @Wildcard String options) { + + String cmd = "globalMobSpawningDeny"; + + String wgSetting = "prison-mines.world-guard.global-region-commands.deny-mob-spawning"; + + String mineName = "*global*"; + + worldGuardRegions( sender, wgSetting, mineName, playerName, options, cmd ); + } + + + @Command(identifier = "mines worldguard region mineAreaInfo", + description = "WorldGuard Regions: info on the mine area's region. " + + "&6NOTE: mine areas have not been added to prison yet, so this will do nothing.", + onlyPlayers = false, permissions = "mines.set") + public void commandWorldGuardRegionsMineAreaInfo(CommandSender sender, + @Arg(name = "mineName", description = "mine name") String mineName, + @Arg(name = "playerName", def = "view", + description = "An online player who can run the " + + "world guard region commands. Optional. If no player is " + + "specified and ran from console, it will only list the " + + "commands and will not try to run them.") String playerName, + @Arg(name = "options", def = "view", + description = "Options: default 'view' [view, run]. The option 'view' will generate the " + + "list of commands and display them in the console. The 'run' will submit them " + + "to be ran as the player, who must be online. They will be " + + "teleported to the mine's spawn point to ensure they are in the correct " + + "world.") @Wildcard String options) { + + String cmd = "mineAreaInfo"; + + String wgSetting = "prison-mines.world-guard.mine-area-region-commands.info"; + + sender.sendMessage( "&6Notice: mine areas have not been added to prison yet. This will do nothing."); + + worldGuardRegions( sender, wgSetting, mineName, playerName, options, cmd ); + } + + @Command(identifier = "mines worldguard region mineAreaDefine", + description = "WorldGuard Regions: define the mine area's region. " + + "&6NOTE: mine areas have not been added to prison yet, so this will do nothing.", + onlyPlayers = false, permissions = "mines.set") + public void commandWorldGuardRegionsMineAreaDefine(CommandSender sender, + @Arg(name = "mineName", description = "mine name") String mineName, + @Arg(name = "playerName", def = "view", + description = "An online player who can run the " + + "world guard region commands. Optional. If no player is " + + "specified and ran from console, it will only list the " + + "commands and will not try to run them.") String playerName, + @Arg(name = "options", def = "view", + description = "Options: default 'view' [view, run]. The option 'view' will generate the " + + "list of commands and display them in the console. The 'run' will submit them " + + "to be ran as the player, who must be online. They will be " + + "teleported to the mine's spawn point to ensure they are in the correct " + + "world.") @Wildcard String options) { + + String cmd = "mineAreaDefine"; + + String wgSetting = "prison-mines.world-guard.mine-area-region-commands.define"; + + sender.sendMessage( "&6Notice: mine areas have not been added to prison yet. This will do nothing."); + + worldGuardRegions( sender, wgSetting, mineName, playerName, options, cmd ); + } + + @Command(identifier = "mines worldguard region mineAreaRedefine", + description = "WorldGuard Regions: redefine the mine area's region. " + + "&6NOTE: mine areas have not been added to prison yet, so this will do nothing.", + onlyPlayers = false, permissions = "mines.set") + public void commandWorldGuardRegionsMineAreaRedefine(CommandSender sender, + @Arg(name = "mineName", description = "mine name") String mineName, + @Arg(name = "playerName", def = "view", + description = "An online player who can run the " + + "world guard region commands. Optional. If no player is " + + "specified and ran from console, it will only list the " + + "commands and will not try to run them.") String playerName, + @Arg(name = "options", def = "view", + description = "Options: default 'view' [view, run]. The option 'view' will generate the " + + "list of commands and display them in the console. The 'run' will submit them " + + "to be ran as the player, who must be online. They will be " + + "teleported to the mine's spawn point to ensure they are in the correct " + + "world.") @Wildcard String options) { + + String cmd = "mineAreaRedefine"; + + String wgSetting = "prison-mines.world-guard.mine-area-region-commands.redefine"; + + sender.sendMessage( "&6Notice: mine areas have not been added to prison yet. This will do nothing."); + + worldGuardRegions( sender, wgSetting, mineName, playerName, options, cmd ); + } + + + @Command(identifier = "mines worldguard region mineAreaSelect", + description = "WorldGuard Regions: select the mine area's region. " + + "&6NOTE: mine areas have not been added to prison yet, so this will do nothing.", + onlyPlayers = false, permissions = "mines.set") + public void commandWorldGuardRegionsMineAreaSelect(CommandSender sender, + @Arg(name = "mineName", description = "mine name") String mineName, + @Arg(name = "playerName", def = "view", + description = "An online player who can run the " + + "world guard region commands. Optional. If no player is " + + "specified and ran from console, it will only list the " + + "commands and will not try to run them.") String playerName, + @Arg(name = "options", def = "view", + description = "Options: default 'view' [view, run]. The option 'view' will generate the " + + "list of commands and display them in the console. The 'run' will submit them " + + "to be ran as the player, who must be online. They will be " + + "teleported to the mine's spawn point to ensure they are in the correct " + + "world.") @Wildcard String options) { + + String cmd = "mineAreaSelect"; + + String wgSetting = "prison-mines.world-guard.mine-area-region-commands.select"; + + sender.sendMessage( "&6Notice: mine areas have not been added to prison yet. This will do nothing."); + + worldGuardRegions( sender, wgSetting, mineName, playerName, options, cmd ); + } + + + public void worldGuardRegions( CommandSender sender, String wbSetting, + String mineName, String playerName, String options, String command ) { + + PrisonMines pMines = PrisonMines.getInstance(); + + Mine mine = "*global*".equalsIgnoreCase(mineName) ? null : pMines.getMine( mineName ); + Player player = null; + boolean run = false; + + if ( mine == null && !"*global*".equalsIgnoreCase(mineName) ) { + sender.sendMessage( "A valid mine name is required. Try again.");; + return; + } + + if ( playerName.equalsIgnoreCase("run") ) { + + if ( sender.isPlayer() ) { + run = true; + player = sender.getPlatformPlayer(); + } + else { + sender.sendMessage( "A valid player name must be provided if this command is ran from the console."); + } + } + else if ( playerName.equalsIgnoreCase( "view" ) || options.equalsIgnoreCase( "view" ) ) { + run = false; + } + else { + player = getPlayer( sender, playerName ); + + if ( player == null ) { + } + + if ( options.equalsIgnoreCase( "run" ) ) { + run = true; + } + } + + + String mode = run ? "Running" : "Viewing"; + ChatDisplay display = new ChatDisplay("WorldGuard Region Commands - " + mode); + display.addText("'/mines worldGuard regions " + command +"'"); + display.addText(""); + + if ( mine != null ) { + display.addText( "&3Mine: &7%s", mine.getTag() ); + + } + else if ( "*global*".equalsIgnoreCase(mineName) ) { + display.addText( "&3Global: &7__global__"); + } + + if ( run && player != null ) { + player.sendMessage( String.format( + "&cTeleporting you to mine &3%s &bto run WorldGuard Region " + + "commands on your behalf.", + mine.getTag()) ); + teleportPlayer(player, mine, "spawn"); + } + + String world = mine != null && !mine.isVirtual() ? + mine.getWorldName() : + player != null ? player.getLocation().getWorld().getName() : + "world-not-set"; + display.addText( "&3World: &7%s", world ); + + display.addText(""); + + + List wbCommands = Prison.get().getPlatform().getConfigStringArray( wbSetting ); + + if ( wbCommands.size() > 0 ) { + + List cmds = new ArrayList<>(); + + + String regionMineName = Prison.get().getPlatform().getConfigString( + "prison-mines.world-guard.region-mine.region-mine-name", "prison_mine_{mine}"); + String regionGroupPerms = Prison.get().getPlatform().getConfigString( + "prison-mines.world-guard.region-mine.region-group-permission", "g:prison.mines.{mine}"); + + regionMineName = regionMineName.replace("{mine}", mine == null ? "(no-mine)" : mine.getName() ); + regionGroupPerms = regionGroupPerms.replace("{mine}", mine == null ? "(no-mine)" : mine.getName() ); + + String minePos1 = mine == null ? "(no-mine)" : + mine.isVirtual() ? "(virtual-mine-no-coordinates)" : + mine.getBounds().getxBlockMin() + "," + + mine.getBounds().getyBlockMin() + "," + + mine.getBounds().getzBlockMin(); + String minePos2 = mine == null ? "(no-mine)" : + mine.isVirtual() ? "(virtual-mine-no-coordinates)" : + mine.getBounds().getxBlockMax() + "," + + mine.getBounds().getyBlockMax() + "," + + mine.getBounds().getzBlockMax(); + + for (String cmd : wbCommands) { + + String msg = cmd.replace("{mine-pos1}", minePos1) + .replace("{mine-pos2}", minePos2) + .replace("{region-mine-name}", regionMineName) + .replace("{region-group-permission}", regionGroupPerms); + + cmds.add( msg ); + display.addText( "&4 %s", msg ); + + } + + if ( run ) { + // submit the commands in cmds: + + for (String cmd : cmds) { + + Prison.get().getPlatform().dispatchCommand(player, cmd); + } + + } + + display.send( sender ); + + } + else { + sender.sendMessage( + String.format( "Invalid settings: config.yml does not have the proper WorldGuard settings. " + + "[%s]", wbSetting ) ); + } + + } } diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesWorldGuardCommands.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesWorldGuardCommands.java new file mode 100644 index 000000000..31413f30f --- /dev/null +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesWorldGuardCommands.java @@ -0,0 +1,11 @@ +package tech.mcprison.prison.mines.commands; + +public class MinesWorldGuardCommands +extends MinesImportCommands { + + + public MinesWorldGuardCommands( String cmdGroup ) { + super( cmdGroup ); + } + +} diff --git a/prison-spigot/src/main/resources/config.yml b/prison-spigot/src/main/resources/config.yml index 6ba8affaf..6b6a0c333 100644 --- a/prison-spigot/src/main/resources/config.yml +++ b/prison-spigot/src/main/resources/config.yml @@ -366,33 +366,64 @@ prison-mines: - SampleMineName world-guard: WARNING: WorldGuard support is not yet available. Coming soon. + + global-region-commands: + info: + - '/rg list' + - '/rg info __global__' + define: + - '/rg flag __global__ passthrough deny' + deny-mob-spawning: + - 'rg flag __global__ mob-spawning deny' + - '/gamerule doMobSpawning false' + mine-region-commands: + info: + - '/rg list' + - '/rg info {region-mine-name}' + redefine: + - '//pos1 {mine-pos1}' + - '//pos2 {mine-pos2}' + - '//region redefine {region-mine-name}' + define: + - '/region define {region-mine-name}' + - '/region addmember {region-mine-name} {region-group-permission}' + - '/region setpriority {region-mine-name} 20' + - '/region flag {region-mine-name} block-break allow' + - '/region flag {region-mine-name} item-pickup allow' + - '/region flag {region-mine-name} exp-drops allow' + - '/region flag {region-mine-name} item-drop allow' + select: + - '/region select {region-mine-name}' + + mine-area-region-commands: + info: + - '/rg list' + - '/rg info {region-mine-area-name}' + redefine: + - '//pos1 {mine-area-pos1}' + - '//pos2 {mine-area-pos2}' + - '/region redefine {region-mine-area-name}' + define: + - '/region define {region-mine-area-name}' + - '/region addmember {region-mine-area-name} {region-group-permission}' + - '/region setpriority {region-mine-area-name} 10' + - '/region flag {region-mine-area-name} block-break deny' + - '/region flag {region-mine-area-name} item-pickup allow' + - '/region flag {region-mine-area-name} exp-drops allow' + - '/region flag {region-mine-area-name} item-drop allow' + select: + - '/region select {region-mine-area-name}' + 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-name: 'prison_mine_{mine}' + region-group-permission: 'g:prison.mines.{mine}' region-mine-area: - enable: true - name-prefix: prison_mine_area_ + enable: false + region-mine-area-name: 'prison_mine_area_{mine}' 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 From 5a84a9d7217ddc9aec0fbba474bec6274401ca49 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 4 Sep 2024 23:30:38 -0400 Subject: [PATCH 158/323] Update a couple of docs.... --- ...rison_docs_012_setting_up_prison_basics.md | 40 +++++- docs/prison_docs_013_Prison_Help.md | 88 +++++++++----- docs/prison_docs_311_guide_automanager.md | 114 ++++++++++++++++-- 3 files changed, 200 insertions(+), 42 deletions(-) diff --git a/docs/prison_docs_012_setting_up_prison_basics.md b/docs/prison_docs_012_setting_up_prison_basics.md index 71d18ace3..927072042 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-07-24* +*Documented updated: 2024-08-30*


@@ -86,6 +86,30 @@ We say an economy is required, but it's still optional. Without an economy, you Background: CMI "tries" to load last, so it can ensure all of it's dependencies and hooks are in place before it starts up. That's understandable, but Prison also has similar requirements and expectations. Unfortunately, this also causes a conflict with Prison, since Prison must perform validation on startup, and if there is no economy, then Prison could fail to start the Ranks module. The document, [Setting up CMI Economy](prison_docs_028_setting_up_CMI_economy.md), explains in detail how to get everything working perfectly. + + +**Coins Engine** is supported. A multi-currency economy. +*Need to provide more details* + + +**Gems Econommy** is supported. A multi-currency economy. +*Need to provide more details* + + +**EdPrison Economy** is supported. +*Need to provide more details* + + +**ESS Economy** is supported. +*Need to provide more details* + + +**The New Economy** is supported. +*Need to provide more details* + + +**Sane Economy** is supported. +*Need to provide more details* ### Chat Prefix Plugins - Optional @@ -200,6 +224,8 @@ But perhaps the biggest reason why I dropped support for MVdW is because it's 10 ### Enchantment Plugins +*NOTE: this section needs more work. It's not up to date, and does not list all of the various features.* + * **CustomItems** - Recommended - *A Premium Plugin* - Allows for the use of custom blocks within Prison. This provides for a great deal of customizations, including custom textures for your custom blocks. Prison supports CI at about 95% or more. If you need additional support added for CI, please contact Blue and he will add it for you. [https://polymart.org/resource/custom-items.1](https://polymart.org/resource/custom-items.1) @@ -239,10 +265,22 @@ Or if you are not using Prison Block Events, then just MONITOR should be used fo **Please note:** These settings may also apply to the other enchantment plugins if you do not want to use Prison's block handling. +* **EntityExplodeEvents** - This is a built in bukkit explosion event that lists multiple blocks. Some other enchantment plugins may support this event for their enchantments, and if they do, then prison will be able to support those plugins without the need of custom handlers. +*NOTE: This enchantment cannot identify the original block that triggered the explosion. Therefore there could be possible issues once in a while.* + + + +* **ExcellentEnchants** - Uses EntityExplodeEvents. + + +* **XPrison** - Prison supports some features form XPrison. This could allow you to continue to use XPrison for enchantment, but switch over to use prison for managing your ranks and mines. + + * **Zenchantments** - Optional - Some support is provided for zen, but it may not be 100%. More work needs to be done to improve the integration in to prison. This is an open source project. It identifies that it supports spigot 1.9 through 1.14 (different versions). [https://www.spigotmc.org/resources/zenchantments.12948/](https://www.spigotmc.org/resources/zenchantments.12948/). + * **Tokens** - **NOT SUPPORTED!!** Warning: People have paid for this plugin only to find out after the fact that it is not supported and they mistook it for *TokenEnchant* (see above). This plugin does not have a block explosion event that prison can hook in to, so it can never be supported. The developers have been asked a few times to add such an event, but they refused stating they did not see a purpose to add something like that. Hopefully in the future they will add support, and when they do, then we can add it to Prison. 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. diff --git a/docs/prison_docs_013_Prison_Help.md b/docs/prison_docs_013_Prison_Help.md index 353dfa148..f9c209877 100644 --- a/docs/prison_docs_013_Prison_Help.md +++ b/docs/prison_docs_013_Prison_Help.md @@ -7,7 +7,7 @@ This document provides some important information on how to find help in setting up your prison server, and ultimately, how and where to ask for help. -*Documented updated: 2021-12-03* +*Documented updated: 2024-08-30*
@@ -15,10 +15,14 @@ This document provides some important information on how to find help in setting 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. +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. + +We have gone out of our way, many times, to try to provide the best support that we can. We've made custom changes to prison to support specific needs, and to help solve specific problems. Many of these new features have become a standard part of prison too. So the bottom line here is, we take support seriously, and we're willing to find a solution to your challenges even if we have to some times go out of our way. + 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. * Review topics that may address your issue * At the end of the table of contents are some FAQs. Special situations may be added to them. @@ -136,14 +140,20 @@ 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. +Prison has a built in way to share your configurations and settings with support personnel. + +The way this works, is that when you generate a report, prison gathers all of the various data, and creates a single page (a very long page) document which it uploads to a 3rd party server. This information is very detailed and can help us better support everyone since we can see exactly how prison is configured. The service prison uses, is called PrivateBin. The reports are encrypted on the client (not at the server) and is held for only 7 days. Only people with the password can read the these documents. Prison defaults to a standard password for the encryption so we're able to read the reports when they are posted for us. That password, and time to live can be changed in the prison's config.yml file, but you probably do not need to change it. + + +We went with this service since the other paste bin that we were using in the past would never delete any of the documents. Generally they are only needed for a few hours, and worst case a few days. Any older than that, then they probably are not current and new docs need to be generated. So having a service that would auto-delete these was critical to find. Plus with it being encrypted on the client, no one can stumble across them and read them. So they are extra secure. Of course, with the URLs being posted within prison, anyone there can access them, and they probably can lookup the default password. Generally we're not too concerned about the Prison community seeing these documents, since they would not contain anything sensitive (except for logs maybe?) but it's your choice. You can DM them to us, change the password and DM us the password, or request that we delete the link as soon as we open it. If it's a concern to you, please let us know and ask questions and we'll figure out a procedure that will work for you. -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. +These commands will collect all of the related information from your Prison setup, and send it to the website `https://privatebin.net`. The older website that would not purge them or encrypt them is `https://paste.helpch.at`, and that is still available as a standby service. + +These commands 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 ` @@ -156,21 +166,17 @@ Once entered, it will enable the following submit 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. +**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 configs, listeners, and the command cache. This support page has expanded to include more details so there are fewer items to submit, if needed. +Listeners are dumps of the event listeners for BlockBreak, chat, and playerinteract. The blockbreak listeners include any that you have enabled. These can be used to identify problems with priorities and other possible conflicts. + **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. @@ -181,7 +187,9 @@ Here are two examples that I generated from one of my test servers on 2021-12-03 # 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. +**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. + +The reason why this format is not used with the privatebin.net service is because style sheets cannot be embedded in to a markdown document. HTML can be placed in a markdown document, which is what this version of support files are based upon, but without the style sheets and the simple javascript, these do not work and will not be formatted correctly. This file format is also good for server owners who do not want to post their server information on another website. @@ -198,7 +206,7 @@ If an existing file exists, it will generate the next one in the series. When r 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. +NOTE: Hyperlinks and table of contents will be added to this HTML support document in the near-ish future.
@@ -219,27 +227,32 @@ To enable the debugger, you can toggle them all on with `/prison debug` once to To review the options available, use the command `/prison debug help`. There are also debug targets that only enable specific debug statements and the list of the available targets can be displayed with `/prison debug targets`. +Please note, on busy servers, hundreds of messages can be logged in a very short amount of time. Therefore, one feature of the debug command is that it can target a specific user and only log a specified number of statements. That way, if you need to collect logs for sellall or block break events, you can enable it for yourself, or another player, do a few transactions, and it will auto shutoff. Please see the help text below for more information on how to use that feature. + + ``` >prison debug help -[12:16:39 INFO]: ---------- < Cmd: /prison debug > ------------- (3.2.11-alpha.9) -[12:16:39 INFO]: Enables debugging and trouble shooting information. For internal use only. Do not use unless instructed. -[12:16:39 INFO]: /prison debug [targets] -[12:16:39 INFO]: [targets] Optional. Enable or disable a debugging target. [on, off, targets, jarScan, testPlayerUtil, testLocale, rankup] 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. jarScan will identify what Java version compiled the class files within the listed jars -[12:16:39 INFO]: Permissions: -[12:16:39 INFO]: prison.debug +[23:02:19 INFO]: ---------- < Cmd: /prison debug > ------------- (3.3.0-alpha.18d) +[23:02:19 INFO]: Enables debugging and trouble shooting information. For internal use only. Do not use unless instructed. This will add a lot of data to the console. +[23:02:19 INFO]: /prison debug [targets] +[23:02:19 INFO]: [targets] Optional. Enable or disable a debugging target, or set a count down timer. [on, off, targets, (count-down-timer), selective, jarScan, testPlayerUtil, testLocale, rankup, blockConstraints, 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. 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. +[23:02:19 INFO]: Permissions: +[23:02:19 INFO]: prison.debug +[23:02:19 INFO]: Aliases: +[23:02:19 INFO]: [prison support debug] >prison debug targets -[12:17:19 INFO]: Global Debug Logging is enabled -[12:17:19 INFO]: . Valid Targets: all, on, off, blockBreak, blockBreakFortune, rankup, support +[23:03:19 INFO]: Global Debug Logging is disabled +[23:03:19 INFO]: . Valid Targets: all, on, off, blockBreak, blockBreakFortune, targetBlockMismatch, rankup, blockConstraints >prison debug [12:18:18 INFO]: Global Debug Logging is enabled -[12:18:18 INFO]: . Valid Targets: all, on, off, blockBreak, blockBreakFortune, rankup, support +[12:18:18 INFO]: . Valid Targets: all, on, off, blockBreak, blockBreakFortune, targetBlockMismatch, rankup, blockConstraints >prison debug [12:18:20 INFO]: Global Debug Logging is disabled -[12:18:20 INFO]: . Valid Targets: all, on, off, blockBreak, blockBreakFortune, rankup, support +[12:18:20 INFO]: . Valid Targets: all, on, off, blockBreak, blockBreakFortune, targetBlockMismatch, rankup, blockConstraints ``` It should be noted that every time you use the command, other than with the help keyword, it will always show the current status of the debugging information. It will show if the global logging is enabled or not, and if any targets are enabled, it will list all of the active ones. Plus it will show all of the available targets too. @@ -250,10 +263,10 @@ The following shows toggling the global settings: ``` >prison debug [21:12:10 INFO]: Global Debug Logging is enabled -[21:12:10 INFO]: . Valid Targets: all, on, off, blockBreak, blockBreakFortune, durability +[21:12:10 INFO]: . Valid Targets: all, on, off, blockBreak, blockBreakFortune, targetBlockMismatch, rankup, blockConstraints >prison debug [21:12:15 INFO]: Global Debug Logging is disabled -[21:12:15 INFO]: . Valid Targets: all, on, off, blockBreak, blockBreakFortune, durability +[21:12:15 INFO]: . Valid Targets: all, on, off, blockBreak, blockBreakFortune, targetBlockMismatch, rankup, blockConstraints ``` The following will show how you can toggle on a few features. Without using the actions 'on' or 'off' it will toggle the specified targets. The use of 'on' and 'off' can occur anywhere in the list of targets, and if both 'on' and 'off' are specified, then 'on' will take precedence over 'off'. @@ -266,13 +279,13 @@ First notice two targets are activated with two different uses of the `/prison d [21:17:23 INFO]: Global Debug Logging is disabled [21:17:23 INFO]: . Active Debug Targets: [21:17:23 INFO]: . . Target: blockBreak -[21:17:23 INFO]: . Valid Targets: all, on, off, blockBreak, blockBreakFortune, durability +[21:17:23 INFO]: . Valid Targets: all, on, off, blockBreak, blockBreakFortune, targetBlockMismatch, rankup, blockConstraints >prison debug blockBreakFortune [21:17:30 INFO]: Global Debug Logging is disabled [21:17:30 INFO]: . Active Debug Targets: [21:17:30 INFO]: . . Target: blockBreak [21:17:30 INFO]: . . Target: blockBreakFortune -[21:17:30 INFO]: . Valid Targets: all, on, off, blockBreak, blockBreakFortune, durability +[21:17:30 INFO]: . Valid Targets: all, on, off, blockBreak, blockBreakFortune, targetBlockMismatch, rankup, blockConstraints ``` Then using both of the same targets, they are toggled off. @@ -280,7 +293,7 @@ Then using both of the same targets, they are toggled off. ``` >prison debug blockBreakFortune blockBreak [21:17:42 INFO]: Global Debug Logging is disabled -[21:17:42 INFO]: . Valid Targets: all, on, off, blockBreak, blockBreakFortune, durability +[21:17:42 INFO]: . Valid Targets: all, on, off, blockBreak, blockBreakFortune, targetBlockMismatch, rankup, blockConstraints ``` Next, this is showing multiple targets being used, with the 'on' keyword mixed in. Notice it lists all of these active targets. Then `/prison debug` is used to globally turn on all features, which removes any individual targets. Then the global is used again to turn them all off. @@ -292,13 +305,13 @@ Next, this is showing multiple targets being used, with the 'on' keyword mixed i [21:18:31 INFO]: . . Target: durability [21:18:31 INFO]: . . Target: blockBreak [21:18:31 INFO]: . . Target: blockBreakFortune -[21:18:31 INFO]: . Valid Targets: all, on, off, blockBreak, blockBreakFortune, durability +[21:18:31 INFO]: . Valid Targets: all, on, off, blockBreak, blockBreakFortune, targetBlockMismatch, rankup, blockConstraints >prison debug [21:18:38 INFO]: Global Debug Logging is enabled -[21:18:38 INFO]: . Valid Targets: all, on, off, blockBreak, blockBreakFortune, durability +[21:18:38 INFO]: . Valid Targets: all, on, off, blockBreak, blockBreakFortune, targetBlockMismatch, rankup, blockConstraints >prison debug [21:18:43 INFO]: Global Debug Logging is disabled -[21:18:43 INFO]: . Valid Targets: all, on, off, blockBreak, blockBreakFortune, durability +[21:18:43 INFO]: . Valid Targets: all, on, off, blockBreak, blockBreakFortune, targetBlockMismatch, rankup, blockConstraints ``` @@ -309,6 +322,9 @@ Next, this is showing multiple targets being used, with the 'on' keyword mixed i # Prison v3.2.1 and it's Pre-Release Versions +NOTE: A lot has been added and changed since v3.2.1. This should be updated in the near future, but for now, view the current version in the console. + + The Prison startup screen contains a lot of information that can be used help identify issues that are detected by Prison on start up, and can provide useful information about the general environment. See the screen prints below. @@ -410,6 +426,14 @@ These screen prints may not contain the most recent enhancements to prison, sinc
+# Prison - Older versions + +We're happy to help support prison, but we cannot support older versions of prison. If a problem was found, we have tried to fix it, or to replace the faulty command. We also no long have the source code to go back, make a change, and produce a custom build for you. We encourage upgrading to the latest release of prison since we can better support you with those newer features, and we can make changes to the source code if needed. + +Generally, when you upgrade prison, you could always revert to an older version of prison. New features will be lost, but the data saved in the save files should be backwards compatible. This is no longer possible with Prison v3.3.0-alpha.18. That is because we are starting to change the save file formats so we can usher in newer features and also start to support database storage. + +Whenever prison upgrades, there was a new feature added a couple of years ago, to auto backup all of prison's config settings and store them in a zip file within the directory: `plugins/Prison/backups/` So although the newest versions of prison cannot be down-graded automatically, you can restore the older save files that have been backedup. + # Prison v3.1.0 and Earlier - General Information diff --git a/docs/prison_docs_311_guide_automanager.md b/docs/prison_docs_311_guide_automanager.md index 78c9e2404..f4f322084 100644 --- a/docs/prison_docs_311_guide_automanager.md +++ b/docs/prison_docs_311_guide_automanager.md @@ -12,23 +12,60 @@ See below for information on:
-# Auto Manager +# Auto Manager, Auto Features -AutoManager is Prison's block handler. It provides support for breaking blocks within mines, auto pickup, normal drops, fortune, mine access, block events, auto-sell, and many other features. Auto Manager has been one of the most enhanced features of Prison, and what it is capable of doing is probably more that what has been documented in this document due to the complexities involved, and the number of new features added that have not made it to this document. +AutoManager is Prison's block handler. It's also referred to as Auto Features, mostly because of the name of the config file. It provides support for breaking blocks within mines, auto pickup, normal drops, fortune, mine access, block events, auto-sell, and many other features. Auto Manager has been one of the most enhanced features of Prison, and what it is capable of doing is probably more that what has been documented in this document due to the complexities involved, and the number of new features added that have not made it to this document. Extensive work has been done with auto manager to improve the performance, and to extend the compatibility with other plugins. Many plugins have direct support (Auto Manager has event listeners for their custom events), but prison has been modified to work with many plugins that do not provide custom events too. +The configuration file for the auto features is: `plugins/Prison/autoFeaturesConfig.yml`. + + +*Documented updated: 2024-09-02* + +
+ + +# Canceling by Event or by Drops + +Perhaps one of the most important items to setup correctly is how prison should cancel the events or cancel the drops. + +These two settings are: + +`options.blockBreakEvents.cancelAllBlockBreakEvents: false` +`options.blockBreakEvents.cancelAllBlockEventBlockDrops: true` + + +For spigot versions 1.8.x through v1.11.x it's a moot point, since the only option is cancel by event. If you try to cancel by drops it will mess up your server, so don't do it. + +If you are using spigot v1.12.x or higher (paper and other flavors included), then you should almost always use cancel by drops. There may be a few situations where you may need to cancel the events, but that maybe due to other plugins not being written correctly to handle canceled drops. This would be more of an issue for plugins that have been written for spigot versions less than 1.12 or around 1.12's release. Modern plugins properly handle the cancel by drops. + + +Canceling by drops is where prison will change the drops on an event so the drops are empty. No drops. That way other plugins can properly handle the event, and get access to which block (or blocks) are part of the event, but using bukkit's `getDrop()` function will result in zero items. This will prevent double or triple drops for each block being broken. Some of the older plugins would ignore the `getDrops()` function and would generate their own drops incorrectly. + + +By using Canceling by drops, this can allow prison to be one of the lowest priority listeners on the event, and handle the block breakage and the drops, but then allow all the other plugins to properly handle the event too. If they honor the zero drops, then those other plugins can behave as if prison was not even there. Hence prison can seamlessly work with almost any plugin. But as you can imagine, not all plugins are created equally, and not all handles the events in the same way either. It's not to say they are wrong in how they handle the event, it's just that they have different requirements and expectations, and it's those perspectives that gives their plugins a unique appeal for everyone wanting to use them. + + +In general, there isn't much variation in how to setup this setting. It's either cancel by event for older versions of bukkit(paper), or by drops for all the newer versions. But once in a while this can be a significantly important setting to get correct for your environment. + + +Prison currently allows both of these settings to be set with the same value. It may give warnings in the console, but it will allow it happen. And if it does, then things will never work correctly. So never, ever, set them to the same values. I've been tempted to create a new setting that will replace these two settings, and the values would be something more obvious and clear, such as `CANCEL_BY_EVENT` or `CANCEL_BY_DROPS`. This could eliminate the rare situation where both settings are set to the same value. + -*Documented updated: 2023-02-28*
+ # Auto Manager Event Listener Priorities Prison listens to a number of block break event types, and each one can be enabled or disabled. By enabling these listeners, any combination of priorities can be applied to any of the listeners. These priorities cover the standard Bukkit priorities (LOWEST to HIGHEST, plus MONITOR), but also has custom Prison priorities to extend the behaviors. -At this time, these event listeners only apply within mines. In the near future they may be extended to work outside of mines and in other worlds too, but for now, they are only Prison mine specfic. +At this time, these event listeners only apply within mines. In the near future they may be extended to work outside of mines and in other worlds too, but for now, they are only Prison mine specific. + +These priorities are tied to the parameters that are under the path of: +`options.blockBreakEvents.` Valid values for the priorities are: @@ -50,21 +87,73 @@ Valid values for the priorities are: - `ACCESSBLOCKEVENTS` - Same as `ACCESS` but adds a second listener to the stack for a `BLOCKEVENTS` priority too. So this generates two listeners; see both `ACCESS` and `BLOCKEVENTS`. +NOTE that the standard bukkit priorities are: LOWEST, LOW, NORMAL, HIGH, HIGHEST, and MONITOR. Prison extends those basic priorities to provide variations in how it will respond. Some of the custom priorities will actually enable two monitors, such as the ACCESSMONITOR where it uses LOWEST for prison access features, and then MONITOR to record block breakage. + +
+ + +# Event Processor Handling - Sync Tasks for Breaking Blocks + +Prison is capable handling the processing of breaking the blocks in two different ways. It can handle it "inline" or by running it in another sync task which could speed up reactions times. + +Also see the section **Sync Tasks for Breaking Blocks** below for more information. + + +The config setting is in the same block as the other event listeners: +`options.blockBreakEvents.applyBlockBreaksThroughSyncTask: true` -Valid event listeners are as follows, including their default values. Any of the above Prison priorities can be used with the following: +The value of `true` is the default value. + +The concept of this feature is to take an expensive part of the block break handling, the actual breaking of the blocks, and run it in another sync task thread so the original event can be freed up and continue to allow other plugins to process it. The reason why it can be expensive is because the block breakage must run in the synch task (only one sych task thread on a server, and it's the primary thread at that). And it will make changes to the world, which will in turn trigger chunk saving. If it crosses the boundaries of multiple chunks, then it could add more delays. The chunks should be preloaded because the player is already in the area, unlike a mine reset which may have no players in the region. + +This setting is very important. It saves some time, but what makes it important is that on some servers, with higher loads with less resources to process them (cores, cpu, clock frequencies, etc) it can appear like it is causing lag. It actually does not cause lag, but because there could be a slight delay from when the processing of the event happens, and when the blocks are actually broken, that delay could be more obvious. If this is the situation, then just set this value to `false` and force the block breakage to happen while the thread is still processing the event. + + + + +# Event Listeners and Event Priorities + + +The event listeners, and their related event priorities are under the path of: +`options.blockBreakEvents.` + + +Valid event listeners are as follows, including their default values. Any of the above Prison priorities can be used with the following. Pay careful attention to the parameter name and which enchantment plugin it supports since some of the parameter names have become confusing since they are similar to each other (it's too late to change them now, since it will break existing configs). + + + + + +- `blockBreakEventPriority: LOW` - This applies to the 'org.bukkit.BlockBreakEvent' and is the primary way Prison deals with standard block events. There may be some situations where prison would need to DISABLE this listener. All other enchantment plugins MUST also listen to this event too, so it can become complicated on how to properly configure. +- `entityExplodeEventPriority: LOW` - This applies to the 'org.bukkit.event.entity.EntityExplodeEvent'. This is the multi-block explosion event that bukkit has always used for creepers and probably TNT too. But this is also used by the enchantment plugin ExcellentEnchants, and probably others too. + + The only problem with this event, and a few others listed here, is that it does not identify what the initial block was that triggered this event. Prison uses the first block to identify which mine the explosion is in, and if the player has access. This potentially becomes a problem if the player break a block on the edge of the mine, but the first block in this list of blocks is outside the mine; prison will reject the whole explosion event. -- `blockBreakEventPriority: LOW` - This applies to the org.bukkit.BlockBreakEvent and is the primary way Prison deals with standard block events. There may be some situations where prison would need to DISABLE this listener. - `ProcessPrisons_ExplosiveBlockBreakEventsPriority: LOW` - This is the event that must be enabled for Prison Mine Bombs to work. Other plugins may also use this Prison multi-block explosion event too. + - `TokenEnchantBlockExplodeEventPriority: DISABLED` - For TokenEnchant (premium) + - `CrazyEnchantsBlastUseEventPriority: DISABLED` - For CrazyEnchant (open source) + - `RevEnchantsExplosiveEventPriority: DISABLED` - For RevEnchants ExplosiveEvent (premium) - `RevEnchantsJackHammerEventPriority: DISABLED` - For RevEnchants JackHammerEvent (premium) - `ZenchantmentsBlockShredEventPriority: DISABLED` - For ZenChantments (open source) -- `PrisonEnchantsExplosiveEventPriority: DISABLED` - Pulsi's Plugin - (Premium and free... not currently in active development for at this time) +- `PrisonEnchantsExplosiveEventPriority: DISABLED` - Pulsi's Plugin - (Premium and free) Prison supports all version of Pulsi's plugin. + + +- `XPrisonExplosionTriggerEventPriority: DISABLED` (discontinued premium) +- `XPrisonLayerTriggerEventPriority: DISABLED` +- `XPrisonNukeTriggerEventPriority: DISABLED` + + Prison supports XPrison's enchantments. So if you were using XPrison, and you move over to prison, you can continue to use XPrison's enchantment tools. If you have them setup and they are still working well for you, you might as well keep using them since it can be very difficult to reconfigure enchantments in another plugin. + + +NOTE: Prison currently supports importing mine configurations from JetPrisonMines. Visit our discord server and talk to Blue if you would like prison to import from other plugins; it may not be possible, but it also could be. -Do not enable any event listener if you are not using that plugin. Doing so will not contribute to lag, but it will try to setup a useless event listener that could delay startup, and consume a little more memory. + +Do not enable an event listener if you are not using that plugin. Doing so will not contribute to any lag, but it will try to setup a useless event listener that could slightly delay startup while trying to detect that plugin. Overall, if you try to enable a plugin event that you do not have setup on your server, it's not a big deal and prison will ignore them. @@ -74,6 +163,12 @@ Do not enable any event listener if you are not using that plugin. Doing so wil # Sync Tasks for Breaking Blocks +NOTE: This is additional information on the following setting. See the section above titled **Event Processor Handling - Sync Tasks for Breaking Blocks**: +`options.blockBreakEvents.applyBlockBreaksThroughSyncTask: true` + +The value of `true` is the default value. + + Prison is trying its best to optimize performance so your server will have the best experience with no lag. In order to provide the best performance, some features do not always work the best on all servers due to memory limitations, processor performance, huge number of plugins, or almost any other variable which is outside of the control of Prison. Therefore, there are some performance features that work really well on some servers, but not on others. This is not a "problem" with any specific plugin, or server, but it's an expected behavior because all servers are different and they can perform in very different ways based upon configurations. One way Prison is able to improve performance when breaking blocks, is to process as much as it can within the block break events, except for breaking the actual blocks, and for that, prison submits a task that performs the actual block breakage. Since the act of breaking the blocks can be considerably slower than performing the calculations that lead up to the block breakage, it has been shown that by submitting the breakage as a task will improve the overall performance when you have very high over powered tools, and when there are many players online mining. @@ -88,6 +183,7 @@ This feature can be turned off with a simple setting change. The following is t
+ # Auto Manager's Canceling the Event vs. Canceling the Drops Prison's primary way of dealing with BlockBreakEvents, and other block events, has always been done by the canceling the event. @@ -156,7 +252,7 @@ options: # Prison's Auto Manager - Setting Up and Enabling Other Plugins -Prison's Auto Manger deals with the whole block breaking events. It's able to provide advanced features such as auto pickup, auto smelt, and auto block, along with providing the player with XP, applying OP fortune, plus many other features. All with maintaining full compatibility from Spigot v1.8 through Spigot v1.16. +Prison's Auto Manger deals with the whole block breaking events. It's able to provide advanced features such as auto pickup, auto smelt, and auto block, along with providing the player with XP, applying OP fortune, plus many other features. All with maintaining full compatibility from Spigot v1.8 through Spigot v1.21.x Auto Manager is a very complex "process" and as a result, there are many features that can be configured, and many possible interactions with other plugins. Needless to say, there are many things that can go wrong, especially when it may not be configured correctly. From 845455e65d9febffafd3fd97bc1bd81f242ee4d4 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 4 Sep 2024 23:33:44 -0400 Subject: [PATCH 159/323] Mine reset: Not sure if this was a problem but found that the wrong value was being used as a key to access a set of blocks. --- docs/changelog_v3.3.x.md | 3 +++ .../main/java/tech/mcprison/prison/mines/data/MineReset.java | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 8fe77f566..28a3f2dc8 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.18d 2024-09-04 +* **Mine reset: Not sure if this was a problem but found that the wrong value was being used as a key to access a set of blocks.** + + * **WorldGuard Region support: Starting to add WorldGuard region support to mines.** These initially are intended to help create regions, update regions, and view the regions based upon the mine sizes. There are some default command listings in config.yml so they can be customized and expanded to meet your server's needs. 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 e7dda5f87..c80c39679 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 @@ -1007,8 +1007,11 @@ public List getTargetBlockStatsPerLevel() { String blockName = sBlock.getBlockName(); statsBlock = getBlockStats().get( blockName ); + + // TODO Not sure if air.getBlockName() is correct! It was just 'air' which was wrong. + // Did not have time to review this code to see if blockName is correct. if ( statsBlock == null ) { - statsBlock = getBlockStats().get( air ); + statsBlock = getBlockStats().get( air.getBlockName() ); } From 8f4bf95415437a6d15775f5dc1044016ac096684 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 4 Sep 2024 23:39:49 -0400 Subject: [PATCH 160/323] Auto Manager: Bug Fix! I realized by chance that the whole normal drop config was setup incorrectly! This was fixed. What was wrong, was that the normal drops for smelting and blocking were not tied to the perms, lore, and enchantment activators! Also I found that if auto features (auto pickup, auto smelt, and auto blocking) is disabled, then it was bypassing normal drop processing too. So these fixes have normal drops correctly get used if auto pickup is not used. For example, if auto smelt is enabled, but auto pickup is off, and auto pickup does not get triggered by lore, perms, or enchantments, then it will fall back to normal drops and will enable the smelting for that. --- docs/changelog_v3.3.x.md | 6 ++ .../autofeatures/AutoManagerFeatures.java | 75 +++++++++++++------ .../spigot/block/OnBlockBreakEventCore.java | 6 +- 3 files changed, 64 insertions(+), 23 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 28a3f2dc8..d4802847d 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.18d 2024-09-04 +* **Auto Manager: Bug Fix! I realized by chance that the whole normal drop config was setup incorrectly! This was fixed.** +What was wrong, was that the normal drops for smelting and blocking were not tied to the perms, lore, and enchantment activators! +Also I found that if auto features (auto pickup, auto smelt, and auto blocking) is disabled, then it was bypassing normal drop processing too. +So these fixes have normal drops correctly get used if auto pickup is not used. For example, if auto smelt is enabled, but auto pickup is off, and auto pickup does not get triggered by lore, perms, or enchantments, then it will fall back to normal drops and will enable the smelting for that. + + * **Mine reset: Not sure if this was a problem but found that the wrong value was being used as a key to access a set of blocks.** 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 59e3335f4..a188df23a 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 @@ -648,6 +648,14 @@ private int applyAutoEventsDetails( PrisonMinesBlockBreakEvent pmEvent ) { isAutoBlock = (mine != null || mine == null && !limit2minesBlock) && isAutoBlock; + + boolean isNormalSmelt = loreSmelt || enchantsSmelt || configNormalDropSmelt || permSmelt; + isNormalSmelt = (mine != null || mine == null && !limit2minesSmelt) && isNormalSmelt; + + boolean isNormalBlock = loreBlock || enchantsPickup || configNormalDropBlock || permBlock; + isNormalBlock = (mine != null || mine == null && !limit2minesBlock) && isNormalBlock; + + boolean includePlayerInventoryWhenSmelting = isBoolean( AutoFeatures.includePlayerInventoryWhenSmelting ); boolean includePlayerInventoryWhenBlocking = isBoolean( AutoFeatures.includePlayerInventoryWhenBlocking ); @@ -709,7 +717,8 @@ private int applyAutoEventsDetails( PrisonMinesBlockBreakEvent pmEvent ) { // Ops will have to have the perms set to actually use them. // AutoPickup - if ( (mine != null || mine == null && !isBoolean( AutoFeatures.pickupLimitToMines )) ) { +// if ( (mine != null || mine == null && !isBoolean( AutoFeatures.pickupLimitToMines )) ) + { if ( isAutoPickup ) { @@ -728,14 +737,29 @@ private int applyAutoEventsDetails( PrisonMinesBlockBreakEvent pmEvent ) { // .append( "{br}|| ") .append( "(&7NormalDrop handling enabled&3: " ) .append( "&7normalDropSmelt&3[" ) - .append( configNormalDropSmelt ? "enabled" : + .append( isNormalSmelt ? "enabled" : Output.get().getColorCodeError() + "disabled:" + Output.get().getColorCodeDebug() ) - .append( configNormalDropSmelt && includePlayerInventoryWhenSmelting ? " includePlayerInventory" : "" ) + + .append( loreSmelt ? "lore " : "" ) + .append( enchantsSmelt ? "enchant " + enchantsSmeltLevel + " " : "" ) + .append( permSmelt ? "perm " : "" ) + .append( configNormalDropSmelt ? "config " : "" ) + + .append( isNormalSmelt && includePlayerInventoryWhenSmelting ? " includePlayerInventory" : "" ) + + .append( "] " ) .append( "&7normalDropBlock&3[" ) - .append( configNormalDropBlock ? "enabled" : + .append( isNormalBlock ? "enabled" : Output.get().getColorCodeError() + "disabled:" + Output.get().getColorCodeDebug() ) - .append( configNormalDropBlock && includePlayerInventoryWhenBlocking ? " includePlayerInventory" : "" ) + + .append( loreBlock ? "lore " : "" ) + .append( enchantsBlock ? "enchant " + enchantsBlockLevel + " " : "" ) + .append( permBlock ? "perm " : "" ) + .append( configNormalDropBlock ? "config " : "" ) + + + .append( isNormalBlock && includePlayerInventoryWhenBlocking ? " includePlayerInventory" : "" ) .append( "] " ) .append( "&7normalDropCheckForFullInventory&3[" ) @@ -746,7 +770,7 @@ private int applyAutoEventsDetails( PrisonMinesBlockBreakEvent pmEvent ) { // process normal drops here: - totalDrops = calculateNormalDrop( pmEvent ); + totalDrops = calculateNormalDrop( pmEvent, isNormalSmelt, isNormalBlock ); } else { @@ -813,11 +837,14 @@ private boolean checkEnchant(SpigotItemStack itemInHand, String enchantmentName) Map enchants = itemInHand.getEnchantments(); - Set enchs = enchants.keySet(); - for (Enchantment enchant : enchs) { - if ( enchant.getKey().toString().equalsIgnoreCase(enchantmentName) ) { - results = true; - break; + if ( enchants != null && enchants.size() > 0 ) { + + Set enchs = enchants.keySet(); + for (Enchantment enchant : enchs) { + if ( enchant.getKey().toString().equalsIgnoreCase(enchantmentName) ) { + results = true; + break; + } } } @@ -830,15 +857,18 @@ private int getEnchantLevel(SpigotItemStack itemInHand, String enchantmentName) Map enchants = itemInHand.getEnchantments(); - Set enchs = enchants.keySet(); - for (Enchantment enchant : enchs) { - if ( enchant.getKey().toString().equalsIgnoreCase(enchantmentName) ) { - Integer eLevel = enchants.get(enchant); - if ( eLevel != null ) { - - enchantLevel = eLevel; + if ( enchants != null && enchants.size() > 0 ) { + + Set enchs = enchants.keySet(); + for (Enchantment enchant : enchs) { + if ( enchant.getKey().toString().equalsIgnoreCase(enchantmentName) ) { + Integer eLevel = enchants.get(enchant); + if ( eLevel != null ) { + + enchantLevel = eLevel; + } + break; } - break; } } @@ -1263,7 +1293,8 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, - public int calculateNormalDrop( PrisonMinesBlockBreakEvent pmEvent ) { + public int calculateNormalDrop( PrisonMinesBlockBreakEvent pmEvent, + boolean isNormalSmelt, boolean isNormalBlock ) { // Count should be the total number of items that are to be "dropped". // So effectively it will be the sum of all bukkitDrops counts. @@ -1343,7 +1374,7 @@ public int calculateNormalDrop( PrisonMinesBlockBreakEvent pmEvent ) { drops = mergeDrops( drops ); - if ( isBoolean( AutoFeatures.normalDropSmelt ) ) { + if ( isNormalSmelt ) { pmEvent.getDebugInfo().append( "(normSmelting: " ); normalDropSmelt( pmEvent.getPlayer(), drops, pmEvent.getDebugInfo() ); @@ -1352,7 +1383,7 @@ public int calculateNormalDrop( PrisonMinesBlockBreakEvent pmEvent ) { } - if ( isBoolean( AutoFeatures.normalDropBlock ) ) { + if ( isNormalBlock ) { pmEvent.getDebugInfo().append( "(normBlocking: " ); normalDropBlock( pmEvent.getPlayer(), drops, pmEvent.getDebugInfo() ); 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 3512f8023..19a6f897d 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 @@ -1345,7 +1345,11 @@ private int processPrisonBlockEventCommands( PrisonMinesBlockBreakEvent pmEvent, public boolean doAction( PrisonMinesBlockBreakEvent pmEvent ) { AutoManagerFeatures aMan = SpigotPrison.getInstance().getAutoFeatures(); - int totalDrops = aMan.calculateNormalDrop( pmEvent ); + + boolean isNormalSmelt = false; + boolean isNormalBlock = false; + + int totalDrops = aMan.calculateNormalDrop( pmEvent, isNormalSmelt, isNormalBlock ); pmEvent.getDebugInfo().append( "(normalDrops totalDrops: " + totalDrops + ") "); From 2689481847c07f39e60803ecd4a68d7ed3432c65 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 4 Sep 2024 23:42:45 -0400 Subject: [PATCH 161/323] Auto features: PrisonEnchants plugin support. Adjustments to get it to work better for all versions. Needed to have it perform the checks in two different areas. --- docs/changelog_v3.3.x.md | 3 + .../events/AutoManagerPrisonEnchants.java | 118 ++++++++++++------ 2 files changed, 81 insertions(+), 40 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index d4802847d..6c4e7a405 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -16,6 +16,9 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.18d 2024-09-04 +* **Auto features: PrisonEnchants plugin support.** Adjustments to get it to work better for all versions. +Needed to have it perform the checks in two different areas. + * **Auto Manager: Bug Fix! I realized by chance that the whole normal drop config was setup incorrectly! This was fixed.** What was wrong, was that the normal drops for smelting and blocking were not tied to the perms, lore, and enchantment activators! 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 a246d6bf4..b91aff240 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 @@ -45,7 +45,7 @@ public class AutoManagerPrisonEnchants extends AutoManagerFeatures implements PrisonEventManager { - private PEExplosionEventVersion peApiVersion; + private PEExplosionEventVersion peApiVersion = null; private BlockBreakPriority bbPriority; @@ -63,9 +63,9 @@ public AutoManagerPrisonEnchants() { public AutoManagerPrisonEnchants( BlockBreakPriority bbPriority ) { super(); - this.peApiVersion = PEExplosionEventVersion.undefined; - this.bbPriority = bbPriority; + + } @@ -95,6 +95,9 @@ public class AutoManagerPEExplosiveEventListener public AutoManagerPEExplosiveEventListener( BlockBreakPriority bbPriority ) { super( bbPriority ); + + // Setup the plugin's version: + getPEPluginVersion(); } @EventHandler(priority=EventPriority.NORMAL) @@ -117,7 +120,7 @@ public void onPrisonEnchantsExplosiveEvent( PEExplosionEvent e, BlockBreakPriori } - @SuppressWarnings("unused") +// @SuppressWarnings("unused") @Override public void initialize() { @@ -125,6 +128,7 @@ public void initialize() { BlockBreakPriority bbPriority = BlockBreakPriority.fromString( eP ); setBbPriority( bbPriority ); + //setPeApiVersion( PEExplosionEventVersion.undefined ); // boolean isEventEnabled = eP != null && !"DISABLED".equalsIgnoreCase( eP ); @@ -183,42 +187,12 @@ public void initialize() { +// HandlerList handlerList = PEExplosionEvent.getHandlerList(); - Class klass = PEExplosionEvent.class; - if ( hasMethod( "getBlockBroken", klass ) && - hasMethod( "getExplodedBlocks", klass ) ) { - - setPeApiVersion( PEExplosionEventVersion.pev1_0_0 ); - } - else if ( hasMethod( "getBlocks", klass ) && - !hasMethod( "getOrigin", klass ) ) { - - setPeApiVersion( PEExplosionEventVersion.pev2_0_0 ); - } - else if ( hasMethod( "getBlocks", klass ) && - hasMethod( "getOrigin", klass ) ) { - - setPeApiVersion( PEExplosionEventVersion.pev2_2_1 ); - } - - String msg = ""; - if ( getPeApiVersion() == PEExplosionEventVersion.undefined ) { - msg = "&cWarning: AutoFeatures has been configured to use Pulsi's " - + "PrisonEnchant's PEExplosionEvent but the plugin is not " - + "loaded or active."; - } - else if ( getPeApiVersion() == PEExplosionEventVersion.pev2_2_1 ) { - msg = "&6PEExplosionEvent API based on v2.2.1 or newer has been found and registered."; - } - else { - msg = "&6PEExplosionEvent API has been found and registered, but it is " - + "out of date. &cPlease upgrade PrisonEnchants to the lastest release " - + "for best results. &66https://polymart.org/resource/prisonenchants.1434"; - } + getPEPluginVersion(); + - Output.get().logWarn( msg ); - @@ -247,6 +221,47 @@ else if ( getPeApiVersion() == PEExplosionEventVersion.pev2_2_1 ) { } } + private void getPEPluginVersion() { + Class klass = PEExplosionEvent.class; + + setPeApiVersion( PEExplosionEventVersion.undefined ); + + if ( hasMethod( "getBlockBroken", klass ) && + hasMethod( "getExplodedBlocks", klass ) ) { + + setPeApiVersion( PEExplosionEventVersion.pev1_0_0 ); + } + else if ( hasMethod( "getBlocks", klass ) && + !hasMethod( "getOrigin", klass ) ) { + + setPeApiVersion( PEExplosionEventVersion.pev2_0_0 ); + } + else if ( hasMethod( "getBlocks", klass ) && + hasMethod( "getOrigin", klass ) ) { + + setPeApiVersion( PEExplosionEventVersion.pev2_2_1 ); + } + + + String msg = ""; + if ( getPeApiVersion() == PEExplosionEventVersion.undefined ) { + msg = "&cWarning: AutoFeatures has been configured to use Pulsi's " + + "PrisonEnchant's PEExplosionEvent but the plugin is not " + + "loaded or active."; + } + else if ( getPeApiVersion() == PEExplosionEventVersion.pev2_2_1 ) { + msg = "&6PEExplosionEvent API based on v2.2.1 or newer has been found and &2successfully &6registered."; + } + else { + msg = "&6PEExplosionEvent API has been found and &2successfully &6registered, but it is " + + "out of date. &cPlease upgrade PrisonEnchants to the lastest release " + + "for best results. &6https://polymart.org/resource/prisonenchants.1434"; + } + + Output.get().logWarn( msg ); + + } + /** *

Checks a Class to see if the given function exists. * Based upon our own specific needs with this, we are just checking @@ -275,6 +290,10 @@ private boolean hasMethod( String methodName, Class klass ) { private Block getBlock( PEExplosionEvent event ) { Block results = null; + if ( getPeApiVersion() == null ) { + getPEPluginVersion(); + } + if ( getPeApiVersion() == PEExplosionEventVersion.pev1_0_0 ) { results = event.getBlockBroken(); @@ -289,6 +308,9 @@ else if ( getPeApiVersion() == PEExplosionEventVersion.pev2_2_1 ) { Location bLocation = event.getOrigin(); results = bLocation.getWorld().getBlockAt(bLocation); } + else if ( getPeApiVersion() == PEExplosionEventVersion.undefined ) { + Output.get().logWarn( "AutoManager: Pulsi_'s PrisonEnchants api version is &6undefined&3!" ); + } return results; } @@ -296,6 +318,10 @@ else if ( getPeApiVersion() == PEExplosionEventVersion.pev2_2_1 ) { private List getBlocks( PEExplosionEvent event ) { List results = new ArrayList<>(); + if ( getPeApiVersion() == null ) { + getPEPluginVersion(); + } + if ( getPeApiVersion() == PEExplosionEventVersion.pev1_0_0 ) { results.addAll( event.getExplodedBlocks() ); @@ -308,6 +334,9 @@ else if ( getPeApiVersion() == PEExplosionEventVersion.pev2_2_1 ) { results.addAll( event.getBlocks() ); } + else if ( getPeApiVersion() == PEExplosionEventVersion.undefined ) { + Output.get().logWarn( "AutoManager: Pulsi_'s PrisonEnchants api version is &6undefined&3!" ); + } return results; } @@ -339,7 +368,7 @@ public void execute(Listener l, Event e) { @Override public void unregisterListeners() { - + setPeApiVersion( null ); // super.unregisterListeners(); } @@ -378,9 +407,11 @@ public void dumpEventListeners( StringBuilder sb ) { Class.forName( "me.pulsi_.prisonenchants.events.PEExplosionEvent", false, this.getClass().getClassLoader() ); - HandlerList handlers = PEExplosionEvent.getHandlerList(); + // debug only: + Output.get().logInfo( "PEExplosionEvent: " + handlers.getClass().getName() ); + // String eP = getMessage( AutoFeatures.blockBreakEventPriority ); BlockBreakPriority bbPriority = BlockBreakPriority.fromString( eP ); @@ -528,6 +559,7 @@ public void handlePEExplosionEvent( PEExplosionEvent e, BlockBreakPriority bbPri if ( pmEvent.isCancelOriginalEvent() ) { + e.getBlocks().clear(); e.setCancelled( true ); } @@ -565,6 +597,10 @@ else if ( pmEvent.getBbPriority().isMonitor() ) { e.setCancelled( true ); debugInfo.append( "(event canceled) " ); } + + e.getBlocks().clear(); + + // else if ( cancelBy == EventListenerCancelBy.drops ) { // try // { @@ -603,10 +639,12 @@ protected int checkBonusXp( Player player, Block block, ItemStack item ) { } public PEExplosionEventVersion getPeApiVersion() { - return peApiVersion; + return this.peApiVersion; +// return AutoManagerPrisonEnchants.peApiVersion; } public void setPeApiVersion(PEExplosionEventVersion peApiVersion) { this.peApiVersion = peApiVersion; +// AutoManagerPrisonEnchants.peApiVersion = peApiVersion; } From a480c016642f93f9db546c037261ae9624a49988 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 5 Sep 2024 22:45:03 -0400 Subject: [PATCH 162/323] Auto Features: blocking: Fixed a bug where 'blockAllBlocks' was incorrectly using 'smeltAllBlocks'. Fixed. 'blockAllBlocks' now works properly. --- docs/changelog_v3.3.x.md | 6 +++++- .../prison/spigot/autofeatures/AutoManagerFeatures.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 6c4e7a405..fa833175b 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.18d 2024-09-04 +# 3.3.0-alpha.18d 2024-09-05 + +* **Auto Features: blocking: Fixed a bug where 'blockAllBlocks' was incorrectly using 'smeltAllBlocks'.** +Fixed. 'blockAllBlocks' now works properly. + * **Auto features: PrisonEnchants plugin support.** Adjustments to get it to work better for all versions. Needed to have it perform the checks in two different areas. 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 a188df23a..7bf849a52 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 @@ -2674,7 +2674,7 @@ else if ( sItemStack.getMaterial() != null ) { */ protected void normalDropBlock( Player player, List drops, StringBuilder debugInfo ) { - boolean isAll = isBoolean( AutoFeatures.smeltAllBlocks ); + boolean isAll = isBoolean( AutoFeatures.blockAllBlocks ); boolean includePlayerInventory = isBoolean( AutoFeatures.includePlayerInventoryWhenSmelting ); From c56343a47f817f72ad50b502c1116d7c6cf0f23e Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 5 Sep 2024 22:47:24 -0400 Subject: [PATCH 163/323] Auto Manager: Use RevEnchant's fortune. This may have been a bug, but not sure. Was successfully loading Rev's fortune level, but it appears like the default minecraft fortune level may have overwritten it. If so, its now fixed. --- docs/changelog_v3.3.x.md | 5 +++++ .../spigot/autofeatures/AutoManagerFeatures.java | 10 ++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index fa833175b..ad4825248 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.18d 2024-09-05 + +* **Auto Manager: Use RevEnchant's fortune.** +This may have been a bug, but not sure. Was successfully loading Rev's fortune level, but it appears like the default minecraft fortune level may have overwritten it. If so, its now fixed. + + * **Auto Features: blocking: Fixed a bug where 'blockAllBlocks' was incorrectly using 'smeltAllBlocks'.** Fixed. 'blockAllBlocks' now works properly. 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 7bf849a52..44af1722b 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 @@ -445,9 +445,9 @@ protected int getFortune(SpigotItemStack itemInHand, StringBuilder debugInfo ){ try { Class.forName( "me.revils.revenchants.api.RevEnchantApi", false, this.getClass().getClassLoader() ); - boolean has1 = PrisonNBTUtil.hasNBTInt( itemInHand.getBukkitStack(), "tag"); - boolean has2 = PrisonNBTUtil.hasNBTInt( itemInHand.getBukkitStack(), "tag.Enchants"); - boolean has3 = PrisonNBTUtil.hasNBTInt( itemInHand.getBukkitStack(), "tag.Enchants.Fortune"); +// boolean has1 = PrisonNBTUtil.hasNBTInt( itemInHand.getBukkitStack(), "tag"); +// boolean has2 = PrisonNBTUtil.hasNBTInt( itemInHand.getBukkitStack(), "tag.Enchants"); +// boolean has3 = PrisonNBTUtil.hasNBTInt( itemInHand.getBukkitStack(), "tag.Enchants.Fortune"); if ( RevEnchantsApi.isTool( itemInHand.getBukkitStack() ) && PrisonNBTUtil.hasNBTInt( itemInHand.getBukkitStack(), "tag.Enchants.Fortune") ) { @@ -457,6 +457,7 @@ protected int getFortune(SpigotItemStack itemInHand, StringBuilder debugInfo ){ if ( fortRevEnchants > -1 ) { fortLevel = fortRevEnchants; + usedRevEnchantsFortune = true; debugInfo.append( "used RevEnchant NBT: level " ).append( fortLevel ); } @@ -466,7 +467,7 @@ protected int getFortune(SpigotItemStack itemInHand, StringBuilder debugInfo ){ } - usedRevEnchantsFortune = true; +// usedRevEnchantsFortune = true; } } catch ( Exception e ) { @@ -484,6 +485,7 @@ protected int getFortune(SpigotItemStack itemInHand, StringBuilder debugInfo ){ try { if ( !usedTEFortune && + !usedRevEnchantsFortune && itemInHand != null && itemInHand.getBukkitStack() != null && itemInHand.getBukkitStack().containsEnchantment( Enchantment.LOOT_BONUS_BLOCKS ) && From d0ce4c9ff4975f1d1101db8293205d5faee7cb82 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 5 Sep 2024 22:50:29 -0400 Subject: [PATCH 164/323] Auto Features: Added support for 9 new Blocking combinations. These can be individually controlled to disable. --- docs/changelog_v3.3.x.md | 4 + .../autofeatures/AutoFeaturesFileConfig.java | 32 ++++-- .../autofeatures/AutoManagerFeatures.java | 107 +++++++++++++++++- 3 files changed, 131 insertions(+), 12 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index ad4825248..e4433476f 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.18d 2024-09-05 +* **Auto Features: Added support for 9 new Blocking combinations.** +These can be individually controlled to disable. + + * **Auto Manager: Use RevEnchant's fortune.** This may have been a bug, but not sure. Was successfully loading Rev's fortune level, but it appears like the default minecraft fortune level may have overwritten it. If so, its now fixed. 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 d182ec832..3536e470c 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 @@ -452,22 +452,36 @@ public enum AutoFeatures { blockAllBlocks(blockFeature, true), + blockRawCopperBlock(blockFeature, true), + blockCopperBlock(blockFeature, true), + + blockGoldIngot(blockFeature, true), blockRawGoldBlock(blockFeature, true), blockGoldBlock(blockFeature, true), - blockIronBlock(blockFeature, true), + + blockIronIngot(blockFeature, true), blockRawIronBlock(blockFeature, true), - blockCoalBlock(blockFeature, true), + blockIronBlock(blockFeature, true), + + blockAmethystBlock(blockFeature, true), blockDiamondBlock(blockFeature, true), - blockRedstoneBlock(blockFeature, true), blockEmeraldBlock(blockFeature, true), - blockQuartzBlock(blockFeature, true), - blockPrismarineBlock(blockFeature, true), + blockRedstoneBlock(blockFeature, true), + + blockCoalBlock(blockFeature, true), blockLapisBlock(blockFeature, true), - blockSnowBlock(blockFeature, true), + blockPrismarineBlock(blockFeature, true), + blockQuartzBlock(blockFeature, true), + + blockBoneBlock(blockFeature, true), + blockDriedKelpBlock(blockFeature, true), blockGlowstone(blockFeature, true), - blockRawCopperBlock(blockFeature, true), - blockCopperBlock(blockFeature, true), - + blockHayBlock(blockFeature, true), + blockNetherWartBlock(blockFeature, true), + blockMelon(blockFeature, true), + blockPackedIceBlock(blockFeature, true), + blockSnowBlock(blockFeature, true), + blockConverters(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 44af1722b..430bb608c 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 @@ -2705,9 +2705,20 @@ protected void normalDropBlock( Player player, List drops, Stri switch ( source ) { + case GOLD_NUGGET: + if ( isAll || isBoolean( AutoFeatures.blockGoldIngot ) ) { + + if ( includePlayerInventory ) { + SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( + player, source, drop ); + } + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.GOLD_INGOT, 9, debugInfo ); + } + break; + case RAW_GOLD: if ( isAll || isBoolean( AutoFeatures.blockRawGoldBlock ) ) { - + if ( includePlayerInventory ) { SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( player, source, drop ); @@ -2727,9 +2738,20 @@ protected void normalDropBlock( Player player, List drops, Stri } break; - case RAW_IRON: - if ( isAll || isBoolean( AutoFeatures.blockRawIronBlock ) ) { + case IRON_NUGGET: + if ( isAll || isBoolean( AutoFeatures.blockIronIngot ) ) { + if ( includePlayerInventory ) { + SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( + player, source, drop ); + } + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.IRON_INGOT, 9, debugInfo ); + } + break; + + case RAW_IRON: + if ( isAll || isBoolean( AutoFeatures.blockRawIronBlock ) ) { + if ( includePlayerInventory ) { SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( player, source, drop ); @@ -2826,6 +2848,72 @@ protected void normalDropBlock( Player player, List drops, Stri } break; + case PACKED_ICE: + if ( isAll || isBoolean( AutoFeatures.blockPackedIceBlock ) ) { + + if ( includePlayerInventory ) { + SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( + player, source, drop ); + } + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.BLUE_ICE, 9, debugInfo ); + } + break; + + case BONE_MEAL: + if ( isAll || isBoolean( AutoFeatures.blockBoneBlock ) ) { + + if ( includePlayerInventory ) { + SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( + player, source, drop ); + } + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.BONE_BLOCK, 9, debugInfo ); + } + break; + + case DRIED_KELP: + if ( isAll || isBoolean( AutoFeatures.blockDriedKelpBlock ) ) { + + if ( includePlayerInventory ) { + SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( + player, source, drop ); + } + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.DRIED_KELP_BLOCK, 9, debugInfo ); + } + break; + + case WHEAT: + if ( isAll || isBoolean( AutoFeatures.blockHayBlock ) ) { + + if ( includePlayerInventory ) { + SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( + player, source, drop ); + } + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.HAY_BLOCK, 9, debugInfo ); + } + break; + + case MELON_SLICE: + if ( isAll || isBoolean( AutoFeatures.blockMelon ) ) { + + if ( includePlayerInventory ) { + SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( + player, source, drop ); + } + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.MELON, 9, debugInfo ); + } + break; + + case NETHER_WART: + if ( isAll || isBoolean( AutoFeatures.blockNetherWartBlock ) ) { + + if ( includePlayerInventory ) { + SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( + player, source, drop ); + } + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.NETHER_WART_BLOCK, 9, debugInfo ); + } + break; + case GLOWSTONE_DUST: if ( isAll || isBoolean( AutoFeatures.blockGlowstone ) ) { @@ -2870,6 +2958,19 @@ protected void normalDropBlock( Player player, List drops, Stri } break; + + + case AMETHYST_SHARD: + if ( isAll || isBoolean( AutoFeatures.blockAmethystBlock ) ) { + + if ( includePlayerInventory ) { + SpigotUtil.getAllDroppedItemTypesFromPlayerInventory( + player, source, drop ); + } + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.AMETHYST_BLOCK, 4, debugInfo ); + } + break; + default: break; } From b5cfd029f26b70614250378d1b2f7d3a228b58d0 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 6 Sep 2024 22:32:01 -0400 Subject: [PATCH 165/323] AutoFeatures: PrisonEnchants (Pulsi's): Made changes to handle explosion events that happen outside of the mine, but there are some blocks that are within the mine. This prevents PrisonEnchants, or bukkit, from breaking the blocks within the mine. --- docs/changelog_v3.3.x.md | 6 +- .../tech/mcprison/prison/util/Bounds.java | 13 +- .../events/AutoManagerPrisonEnchants.java | 104 ++++++--- .../spigot/block/OnBlockBreakMines.java | 202 +++++++++++++++++- 4 files changed, 291 insertions(+), 34 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index e4433476f..8ea8e2eb7 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.18d 2024-09-05 +# 3.3.0-alpha.18d 2024-09-06 + + +* **AutoFeatures: PrisonEnchants (Pulsi's): Made changes to handle explosion events that happen outside of the mine, but there are some blocks that are within the mine.** +This prevents PrisonEnchants, or bukkit, from breaking the blocks within the mine. * **Auto Features: Added support for 9 new Blocking combinations.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/util/Bounds.java b/prison-core/src/main/java/tech/mcprison/prison/util/Bounds.java index 707f2b3bf..39de171b9 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/util/Bounds.java +++ b/prison-core/src/main/java/tech/mcprison/prison/util/Bounds.java @@ -478,12 +478,21 @@ public Location getCenter() { return center; } + + + public double getRadius() { + double radius = getDistance3d() / 2.0; + return radius; + } + - @Override public String toString() { + @Override + public String toString() { return "Bounds{" + "min=" + min.toCoordinates() + ", max=" + max.toCoordinates() + '}'; } - @Override public boolean equals(Object o) { + @Override + public boolean equals(Object o) { if (this == o) { return true; } 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 b91aff240..b7f97eaf9 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 @@ -1,7 +1,6 @@ package tech.mcprison.prison.spigot.autofeatures.events; import java.lang.reflect.Method; -import java.util.ArrayList; import java.util.List; import org.bukkit.Bukkit; @@ -315,31 +314,31 @@ else if ( getPeApiVersion() == PEExplosionEventVersion.undefined ) { return results; } - private List getBlocks( PEExplosionEvent event ) { - List results = new ArrayList<>(); - - if ( getPeApiVersion() == null ) { - getPEPluginVersion(); - } - - if ( getPeApiVersion() == PEExplosionEventVersion.pev1_0_0 ) { - - results.addAll( event.getExplodedBlocks() ); - } - else if ( getPeApiVersion() == PEExplosionEventVersion.pev2_0_0 ) { - - results.addAll( event.getBlocks().subList(1, event.getBlocks().size())); - } - else if ( getPeApiVersion() == PEExplosionEventVersion.pev2_2_1 ) { - - results.addAll( event.getBlocks() ); - } - else if ( getPeApiVersion() == PEExplosionEventVersion.undefined ) { - Output.get().logWarn( "AutoManager: Pulsi_'s PrisonEnchants api version is &6undefined&3!" ); - } - - return results; - } +// private List getBlocks( PEExplosionEvent event ) { +// List results = new ArrayList<>(); +// +// if ( getPeApiVersion() == null ) { +// getPEPluginVersion(); +// } +// +// if ( getPeApiVersion() == PEExplosionEventVersion.pev1_0_0 ) { +// +// results.addAll( event.getExplodedBlocks() ); +// } +// else if ( getPeApiVersion() == PEExplosionEventVersion.pev2_0_0 ) { +// +// results.addAll( event.getBlocks().subList(1, event.getBlocks().size())); +// } +// else if ( getPeApiVersion() == PEExplosionEventVersion.pev2_2_1 ) { +// +// results.addAll( event.getBlocks() ); +// } +// else if ( getPeApiVersion() == PEExplosionEventVersion.undefined ) { +// Output.get().logWarn( "AutoManager: Pulsi_'s PrisonEnchants api version is &6undefined&3!" ); +// } +// +// return results; +// } private void createListener(BlockBreakPriority bbPriority) { @@ -483,6 +482,31 @@ public void handlePEExplosionEvent( PEExplosionEvent e, BlockBreakPriority bbPri // or if the targetBlock has been set to ignore all block events which // means the block has already been processed. + + if ( e.getBlocks().size() == 0 ) { + // Nothing to process: + return ; + } + + + // Remove all invalid blocks: + // The original collection in the event will be updated... + int blocksBefore = e.getBlocks().size(); + + // verified blocks: + List vBlocks = removeAllInvalidBlocks( e.getPlayer(), e.getBlocks(), bbPriority, true ); + int blocksAfter = vBlocks.size(); + + Output.get().logInfo( "&6 #### PEExplosionEvent: &7removeAllInvalidBlocks:&3 before: %d after: %d", + blocksBefore, blocksAfter ); + + + if ( vBlocks.size() == 0 ) { + // No blocks are within prison mines... ignore this event. + return; + } + + // NOTE: support for v1.0, v2.2, and v2.2.1 has different block structures: Block bBlock = getBlock( e ); @@ -490,17 +514,35 @@ public void handlePEExplosionEvent( PEExplosionEvent e, BlockBreakPriority bbPri e.getPlayer(), bBlock, bbPriority, true ); + // The primary block is not in the mine, or they don't have access to it, so ignore event: if ( eventResults.isIgnoreEvent() ) { - return; + + // But if vBlocks.size() > 0, the try the first block in that list to see if it will work: + if ( vBlocks.size() > 0 ) { + bBlock = vBlocks.remove( 0 ); + + eventResults = ignoreMinesBlockBreakEvent( e, + e.getPlayer(), bBlock, + bbPriority, true ); + + if ( eventResults.isIgnoreEvent() ) { + return; + } + } + else { + + return; + } } StringBuilder debugInfo = new StringBuilder(); debugInfo.append( String.format( "&6### ** handlePEEExplosionEvent (Pulsi) ** ###&3 " + - "(event: &6PEExplosionEvent&3, config: %s, priority: %s, canceled: %s) ", + "(event: &6PEExplosionEvent&3, config: %s, priority: %s, %scanceled: %s) ", bbPriority.name(), bbPriority.getBukkitEventPriority().name(), + (e.getEventName() == null ? "" : "EventName: " + e.getEventName()), (e.isCancelled() ? "TRUE " : "FALSE") ) ); @@ -540,9 +582,11 @@ public void handlePEExplosionEvent( PEExplosionEvent e, BlockBreakPriority bbPri return; } - List blocks = getBlocks( e ); +// List blocks = getBlocks( e ); - pmEvent.setUnprocessedRawBlocks( blocks ); + // vBlocks have been verified to be within a mine. There may be restrictions that prevent them + // from being used, but they passed the first check. + pmEvent.setUnprocessedRawBlocks( vBlocks ); // Check to see if the blockConverter's EventTrigger should have 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 378683f87..06252e9a5 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 @@ -5,6 +5,7 @@ import java.util.TreeMap; import java.util.UUID; +import org.bukkit.Location; import org.bukkit.block.Block; import org.bukkit.entity.Player; @@ -24,11 +25,12 @@ import tech.mcprison.prison.output.Output; import tech.mcprison.prison.spigot.SpigotUtil; import tech.mcprison.prison.spigot.api.PrisonMinesBlockBreakEvent; +import tech.mcprison.prison.spigot.game.SpigotLocation; import tech.mcprison.prison.spigot.game.SpigotPlayer; import tech.mcprison.prison.spigot.utils.BlockUtils; import tech.mcprison.prison.tasks.PrisonCommandTaskData; -import tech.mcprison.prison.tasks.PrisonCommandTasks; import tech.mcprison.prison.tasks.PrisonCommandTaskData.TaskMode; +import tech.mcprison.prison.tasks.PrisonCommandTasks; public class OnBlockBreakMines extends OnBlockBreakEventCoreMessages @@ -274,6 +276,203 @@ public Mine findMine( UUID playerUUID, SpigotBlock sBlock, List altBlocks // return eventResults.isIgnoreEvent(); // } + + public List removeAllInvalidBlocks( Player player, + List blocks, + BlockBreakPriority bbPriority, + boolean ignoreBlockReuse ) { + + List goodBlocks = new ArrayList<>(); + + if ( blocks.size() == 0 || getPrisonMineManager() == null ) { + // Mines are not enabled, so exit with request to ignore event: + return goodBlocks; + } + + + + // searching for mines is expensive because it's has to check each and every block + // against all possible mines. + + // So first find the "center" of the block list by taking the averages of all blocks's x, y, and z coordinates: + Location locAvgBukkit = getCenterLocationOfBlocks(blocks, player); + + + // next we need to find the greatest distance from the average: + double locAvgRadius = getGreatestDistanceFromLocation(blocks, locAvgBukkit); + + + SpigotLocation locAvg = new SpigotLocation( locAvgBukkit ); + + + // Next we need to find all mines that are within the max distance of the mine, + // to ensure we don't miss the outer corners, take the mine's distance to a corner + // and mult by 1.3 which will potentially include mines that are outside of the + // list of blocks: + List minesShortList = getAllMinesWithinTheRadialDistance( locAvg, locAvgRadius ); + + + + // If no mines are found, then obviously no blocks will be within the mines: + if ( minesShortList.size() == 0 ) { + return goodBlocks; + } + + +// SpigotPlayer sPlayer = new SpigotPlayer( player ); + + + // All blocks must be not be null, and the blocks cannot be identified as an + // unbreakable block, which is usually part of an explosion event such as a + // block decay. + Mine lastMine = null; + + for (Block block : blocks) { + + SpigotBlock sBlock = SpigotBlock.getSpigotBlock( block ); + + if ( block != null && !BlockUtils.getInstance().isUnbreakable( sBlock ) ) { + + // If a block is in the same mine as the 'lastMine', then add it to the + // goodBlocks list. + if ( lastMine != null && lastMine.isInMine(sBlock) ) { + goodBlocks.add(block); + } + + // else if lastMine is null or the block is not in the lastMine, then + // need to check all mines in the short list to see if the block is in + // mine. If it is, then capture it in the goodBlocks list. + else { + + for (Mine mine : minesShortList) { + if ( mine.isInMineExact(locAvg) ) { + lastMine = mine; + + goodBlocks.add(block); + break; + } + } + } + + } + } + +// // Purge all blocks in the parameter List: +// blocks.clear(); +// +// // Add only the goodBlocks back to the parameter's variable: +// blocks.addAll( goodBlocks ); + + return goodBlocks; + } + + + /** + *

This function will take a list of blocks, and calculate the average location, + * which will be the center of the group of blocks. The group of blocks can be + * any shape, and it will still find the center. + *

+ * + *

The way this function works, is that it adds all x's, all y's, and all z's. + * Then divides all these values by the number of blocks that were summed together. + * Basically finding the common vector or everything. + *

+ * + * @param blocks + * @param player + * @return + */ + private Location getCenterLocationOfBlocks(List blocks, Player player) { + long xT = 0; + long yT = 0; + long zT = 0; + int count = 0; + for (Block block : blocks) { + xT += block.getX(); + yT += block.getY(); + zT += block.getZ(); + count++; + } + + double xAvg = (double) xT / count; + double yAvg = (double) yT / count; + double zAvg = (double) zT / count; + Location locAvgBukkit = new Location( player.getWorld(), xAvg, yAvg, zAvg ); + return locAvgBukkit; + } + + + /** + *

This function, given the a location, which should be the center of all blocks + * (See function `getCenterLocationOfBlocks()`), will return the greatest distance + * of all of the included blocks. This will be the outer radius of all the blocks, + * based upon the 'centerLocation'. + *

+ * + * @param blocks + * @param locAvgBukkit + * @return + */ + private double getGreatestDistanceFromLocation(List blocks, Location centerLocation ) { + double locAvgRadius = 0; + for (Block block : blocks) { + double d = centerLocation.distance( block.getLocation() ); + if ( d > locAvgRadius ) { + locAvgRadius = d; + } + } + return locAvgRadius; + } + + /** + *

This function, given a location, and the radius of a sphere around that location, find all + * mines that that has at least one block that will fall within the range of this the location's + * sphere. To ensure a mine is not missed by a block or two, the 'maxPossibleDistance' has + * four added to it. This will help ensure that more mines are included in this list, even if it + * may miss the farthest block by a couple of blocks. It's far better to be more inclusive, than + * to exclude too many. + *

+ * + *

This function basically behaves as if we have two points and spheres around each point. The + * spheres would be the radius from each location, to form a sphere for each location. Between the + * two spheres, we only need to use in our calculations, the closest point on each sphere, such that + * the two chosen points (one of each sphere) are the closest to each other, out of the whole surface + * of those two spheres. Basically, these two points, also happen to be on the line that is formed + * from one location to the other location. And the two points on that line, which represents the + * spheres surface, would be consider intersecting with each other if the distance between the points + * is less than zero. If they don't intersect then the distance will be greater than zero. + *

+ * + *

So basically, the total distance should be less than the two radiuses added together (plus 4.0) + * which indicates there is a probable chance a block may be within that mine. All mines that + * meet this requirement is returned in a List. + *

+ * + * @param locAvg + * @param locAvgRadius + * @return + */ + private List getAllMinesWithinTheRadialDistance( SpigotLocation location, double locationRadius ) { + List minesShortList = new ArrayList<>(); + for (Mine m : getPrisonMineManager().getMines() ) { + if ( !m.isVirtual() ) { + + double mineRadius = m.getBounds().getRadius(); + double maxPossibleDistance = mineRadius + locationRadius + 4; + + double distanceFromMine = m.getBounds().getDistance3d( location ); + + + if ( distanceFromMine <= maxPossibleDistance ) { + minesShortList.add( m ); + } + } + } + return minesShortList; + } + + + /** *

If the event is canceled, it still needs to be processed because of the MONITOR events: @@ -357,6 +556,7 @@ else if ( !mine.hasMiningAccess(sPlayer) ) { results.setResultsReason( EventResultsReasons .results_passed__access_priority__player_has_access ); + // Not sure why that was here? This looks like they should have access?] results.setIgnoreEvent( true ); } From d1c1168ebeaf5c3935e6018b212e402e44227326 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 6 Sep 2024 23:54:58 -0400 Subject: [PATCH 166/323] Mines: Minor change: Simplify how the command is ran so there is one exit point instead of two. --- docs/changelog_v3.3.x.md | 3 +++ .../main/java/tech/mcprison/prison/mines/data/MineData.java | 6 ++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 8ea8e2eb7..0d956c8bc 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.18d 2024-09-06 +* **Mines: Minor change: Simplify how the command is ran so there is one exit point instead of two.** + + * **AutoFeatures: PrisonEnchants (Pulsi's): Made changes to handle explosion events that happen outside of the mine, but there are some blocks that are within the mine.** This prevents PrisonEnchants, or bukkit, from breaking the blocks within the mine. diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineData.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineData.java index f8da89f18..22e6fb8f2 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineData.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineData.java @@ -873,10 +873,8 @@ public TreeMap getBlockStats() { public boolean isInMineExact(Location location) { - if ( isVirtual() ) { - return false; - } - return getBounds().within(location); + + return !isVirtual() && getBounds().within(location); } public boolean isInMineIncludeTopBottomOfMine(Location location) { From cd4e514b63e588cf51ab49c001c0b73160dabef0 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 7 Sep 2024 00:52:25 -0400 Subject: [PATCH 167/323] Change the prison TPS monitor to a singleton. Will be using this in the near future to monitor system loads. --- docs/changelog_v3.3.x.md | 6 +++++- ...PrisonTPS.java => PrisonTPSSingleton.java} | 21 ++++++++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) rename prison-core/src/main/java/tech/mcprison/prison/util/{PrisonTPS.java => PrisonTPSSingleton.java} (97%) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 0d956c8bc..f09647c04 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.18d 2024-09-06 +# 3.3.0-alpha.18d 2024-09-07 + + +* **Change the prison TPS monitor to a singleton.** +Will be using this in the near future to monitor system loads. * **Mines: Minor change: Simplify how the command is ran so there is one exit point instead of two.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/util/PrisonTPS.java b/prison-core/src/main/java/tech/mcprison/prison/util/PrisonTPSSingleton.java similarity index 97% rename from prison-core/src/main/java/tech/mcprison/prison/util/PrisonTPS.java rename to prison-core/src/main/java/tech/mcprison/prison/util/PrisonTPSSingleton.java index aab73a7a5..cc2a094b9 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/util/PrisonTPS.java +++ b/prison-core/src/main/java/tech/mcprison/prison/util/PrisonTPSSingleton.java @@ -158,9 +158,11 @@ *

* */ -public class PrisonTPS +public class PrisonTPSSingleton implements PrisonRunnable { + private static PrisonTPSSingleton instance; + /** * Note: Normally the task would have to run each tick, but by specifying the * SUBMIT_TICKS_INTERVAL it can skip a number of ticks to reduce the @@ -206,6 +208,23 @@ public class PrisonTPS public static final Object tpsLock = new Object(); + private PrisonTPSSingleton() { + super(); + } + + + public static PrisonTPSSingleton getInstance() { + if ( instance == null ) { + synchronized ( PrisonTPSSingleton.class ) { + if ( instance == null ) { + instance = new PrisonTPSSingleton(); + } + } + } + return instance; + } + + // When submitted, taskId identifies the job. A value of -1 indicates the job // failed to be submitted, or is not valid. private int taskId = -1; From 8ddfcbcd15f2fefa06de85696eb8ed3de5e8f275 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 7 Sep 2024 03:44:24 -0400 Subject: [PATCH 168/323] Change the prison TPS monitor to a singleton. Will be using this in the near future to monitor system loads. --- .../main/java/tech/mcprison/prison/Prison.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/prison-core/src/main/java/tech/mcprison/prison/Prison.java b/prison-core/src/main/java/tech/mcprison/prison/Prison.java index 032486e17..f2fac8b72 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/Prison.java +++ b/prison-core/src/main/java/tech/mcprison/prison/Prison.java @@ -47,7 +47,7 @@ import tech.mcprison.prison.troubleshoot.TroubleshootManager; import tech.mcprison.prison.util.EventExceptionHandler; import tech.mcprison.prison.util.PrisonStatsUtil; -import tech.mcprison.prison.util.PrisonTPS; +import tech.mcprison.prison.util.PrisonTPSSingleton; /** * Entry point for implementations.

An instance of Prison can be retrieved using the static @@ -106,7 +106,7 @@ public class Prison private Database metaDatabase; private PrisonStatsUtil statsUtil; - private PrisonTPS prisonTPS; + private PrisonTPSSingleton prisonTPS; private List localeLoadInfo; @@ -293,10 +293,10 @@ public boolean init( File dataFolder ) { this.statsUtil = new PrisonStatsUtil(); - this.prisonTPS = new PrisonTPS(); + this.prisonTPS = PrisonTPSSingleton.getInstance(); this.prisonTPS.submitAsyncTPSTask(); - + // Setup the LocalManager if it is not yet started: getLocaleManager(); @@ -483,14 +483,14 @@ public PrisonStatsUtil getPrisonStatsUtil() { public void displaySystemTPS( ChatDisplay display ) { DecimalFormat iFmt = getDecimalFormatInt(); - PrisonTPS prisonTPS = Prison.get().getPrisonTPS(); + PrisonTPSSingleton prisonTPS = Prison.get().getPrisonTPS(); display.addText( "&7Prison TPS Average: %s Min: %s Max: %s%s " + "Interval: %s ticks Samples: %s", prisonTPS.getAverageTPSFormatted(), prisonTPS.getTPSMinFormatted(), ( prisonTPS.getTpsMax() >= 100 ? ">" : ""), prisonTPS.getTPSMaxFormatted(), - iFmt.format( PrisonTPS.SUBMIT_TICKS_INTERVAL ), + iFmt.format( PrisonTPSSingleton.SUBMIT_TICKS_INTERVAL ), iFmt.format( prisonTPS.getTpsSamples() ) ); @@ -505,7 +505,7 @@ public void displaySystemTPS( ChatDisplay display ) { public void getSystemTPS( LinkedHashMap fields ) { //DecimalFormat iFmt = getDecimalFormatInt(); - PrisonTPS prisonTPS = Prison.get().getPrisonTPS(); + PrisonTPSSingleton prisonTPS = Prison.get().getPrisonTPS(); fields.put( "tps", prisonTPS.getAverageTPSFormatted() ); fields.put( "tpsMin", prisonTPS.getTPSMinFormatted() ); @@ -904,7 +904,7 @@ public String getServerRuntimeFormatted() { return PlaceholdersUtil.formattedTime( runtimeMs / 1000 ); } - public PrisonTPS getPrisonTPS() { + public PrisonTPSSingleton getPrisonTPS() { return prisonTPS; } From 793df4324639c5ef3df0c599fce56d6b435bf660 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 7 Sep 2024 03:48:16 -0400 Subject: [PATCH 169/323] Mines: Air block counting on startup: Change some of the setting to be less demanding on the server. --- docs/changelog_v3.3.x.md | 3 +++ .../OnStartupRefreshBlockBreakCountSyncTask.java | 12 +++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index f09647c04..9a86567ab 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.18d 2024-09-07 +* **Mines: Air block counting on startup: Change some of the setting to be less demanding on the server.** + + * **Change the prison TPS monitor to a singleton.** Will be using this in the near future to monitor system loads. diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/OnStartupRefreshBlockBreakCountSyncTask.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/OnStartupRefreshBlockBreakCountSyncTask.java index d2a7f2964..ce25e6210 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/OnStartupRefreshBlockBreakCountSyncTask.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/OnStartupRefreshBlockBreakCountSyncTask.java @@ -46,7 +46,13 @@ public static void submit( MineReset mine, long delay ) { private void resubmit() { // Must run synchronously!! - setJobId( mine.submitSyncTask( this, 0 ) ); + + + long submitDelay = 0; + + + + setJobId( mine.submitSyncTask( this, submitDelay ) ); } @Override @@ -79,9 +85,9 @@ public void run() { long nanoEnd = System.nanoTime(); long elpased = (nanoEnd - nanoStart ); long elapsedMs = elpased / 1000000; - if ( elapsedMs > 20 ) { + if ( elapsedMs > 15 ) { - // Check every 500 blocks and if been running longer than 20 ms then yield to prevent lag + // Check every 500 blocks and if been running longer than 15 ms then yield to prevent lag this.elapsedNanos += elpased; pages++; From dec9a04c982413be5ed4fbaec78f278d9835b668 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 7 Sep 2024 03:54:47 -0400 Subject: [PATCH 170/323] v3.3.0-alpha.19 2024-09-07 --- 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 9a86567ab..3b24a489b 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.18d 2024-09-07 +# 3.3.0-alpha.19 2024-09-07 + + +**Prison v3.3.0-alpha.19 2024-09-07** * **Mines: Air block counting on startup: Change some of the setting to be less demanding on the server.** diff --git a/gradle.properties b/gradle.properties index ecb7e4c09..dd12b8ffa 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.18d +version=3.3.0-alpha.19 From 9c3d55a02b2f093acb04d1b4aa2dcd37d7b02842 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 8 Sep 2024 23:34:31 -0400 Subject: [PATCH 171/323] Mines: Air Block Counts: Improvement. Rewrote the way prison is handling the air block counts because they were causing the servers to fall behind on TPS by a significant amount. The server, depending upon how many mines, and how large they were, the system (spigot, paper, etc) would warn that it was running behind by 50 ticks to a few hundred ticks. The primary reason was that all the mines would be submitted to run almost at the same time, in different threads, so it would starve all available TPS. These changes were a complete rewrite on how the jobs are submitted and the mines are processed. Now it's just one initial job submission, instead of each mine submitting it's own task. And that one new job steps through each mine, one at time, counting the blocks, and then moving on to the next mine. As such, we are not ensuring only one task is trying to run at the same time, thus allowing other services to get sufficient access to the processing that they need. Where a mine-heavy test server was reporting falling behind by 600+ ticks, after these changes there were no warnings. During, and right after the air counts, the server is reporting a solid 20 TPS. --- docs/changelog_v3.3.x.md | 7 +- .../mcprison/prison/mines/data/MineReset.java | 8 +- ...StartupRefreshBlockBreakCountSyncTask.java | 218 +++++++++++++++--- .../prison/mines/managers/MineManager.java | 14 +- .../spiget/PrisonSpigetUpdateCheckTask.java | 2 +- 5 files changed, 209 insertions(+), 40 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 3b24a489b..04e459d9e 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.19 2024-09-07 +# 3.3.0-alpha.19 2024-09-08 + + +* **Mines: Air Block Counts: Improvement. Rewrote the way prison is handling the air block counts because they were causing the servers to fall behind on TPS by a significant amount.** +The server, depending upon how many mines, and how large they were, the system (spigot, paper, etc) would warn that it was running behind by 50 ticks to a few hundred ticks. The primary reason was that all the mines would be submitted to run almost at the same time, in different threads, so it would starve all available TPS. +These changes were a complete rewrite on how the jobs are submitted and the mines are processed. Now it's just one initial job submission, instead of each mine submitting it's own task. And that one new job steps through each mine, one at time, counting the blocks, and then moving on to the next mine. As such, we are not ensuring only one task is trying to run at the same time, thus allowing other services to get sufficient access to the processing that they need. Where a mine-heavy test server was reporting falling behind by 600+ ticks, after these changes there were no warnings. During, and right after the air counts, the server is reporting a solid 20 TPS. **Prison v3.3.0-alpha.19 2024-09-07** 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 c80c39679..132d984ec 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 @@ -1501,16 +1501,18 @@ public void refreshBlockBreakCountUponStartup( long delay) { // if the mine is being used in a unit test, then it will not have a value for // bounds and therefore do not run the task. - if ( getBounds() != null ) { +// if ( getBounds() != null ) { - OnStartupRefreshBlockBreakCountSyncTask.submit( this, delay ); +// OnStartupRefreshBlockBreakCountSyncTask.getInstance().submit( delay ); + +// OnStartupRefreshBlockBreakCountSyncTask.getInstance().submit( this, delay ); // OnStartupRefreshBlockBreakCountAsyncTask cabAsyncTask = new OnStartupRefreshBlockBreakCountAsyncTask(this); // // // Must run synchronously!! // submitSyncTask( cabAsyncTask ); // //submitAsyncTask( cabAsyncTask ); - } +// } } // protected void resetAirCountStartupAsyncTask() { diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/OnStartupRefreshBlockBreakCountSyncTask.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/OnStartupRefreshBlockBreakCountSyncTask.java index ce25e6210..cba115b05 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/OnStartupRefreshBlockBreakCountSyncTask.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/OnStartupRefreshBlockBreakCountSyncTask.java @@ -1,74 +1,199 @@ package tech.mcprison.prison.mines.data; import java.text.DecimalFormat; +import java.util.ArrayList; import java.util.List; +import java.util.TreeSet; import tech.mcprison.prison.Prison; +import tech.mcprison.prison.mines.PrisonMines; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.tasks.PrisonRunnable; +import tech.mcprison.prison.tasks.PrisonTaskSubmitter; import tech.mcprison.prison.util.Location; public class OnStartupRefreshBlockBreakCountSyncTask implements PrisonRunnable { - + + private static OnStartupRefreshBlockBreakCountSyncTask instance; + +// private List mines; + private MineReset mine; + private int jobId = 0; private List locations = null; private int position = 0; private int pages = 0; + private int pagesStart = 0; private int airCount = 0; private long elapsedNanos = 0; + private double elapsedMsTotal = 0; + private int errorCount = 0; private StringBuilder sbErrors = new StringBuilder(); - public OnStartupRefreshBlockBreakCountSyncTask(MineReset mine) { - this.mine = mine; + private List processedMines; + private int countCurrentMine = 0; + private int countTotalMines = 0; + +// private boolean jobRunning = false; + + + private OnStartupRefreshBlockBreakCountSyncTask() { + super(); + + this.processedMines = new ArrayList<>(); } - public static void submit( MineReset mine, long delay ) { + public static OnStartupRefreshBlockBreakCountSyncTask getInstance() { + if ( instance == null ) { + synchronized ( OnStartupRefreshBlockBreakCountSyncTask.class ) { + if ( instance == null ) { + instance = new OnStartupRefreshBlockBreakCountSyncTask(); + } + } + } + return instance; + } + +// public OnStartupRefreshBlockBreakCountSyncTask(MineReset mine) { +// this.mine = mine; +// } + + public void submit( long delay ) { + + setJobId( PrisonTaskSubmitter.runTaskLater( this, delay) ); + + DecimalFormat dFmt = new DecimalFormat( "#,##0.0" ); + + String msg = String.format( + "Startup Block Count Task Submitted to run in %s seconds.", + dFmt.format(delay / 20) + ); + + Output.get().logInfo( msg ); + + } + + private Mine getNextMine() { + Mine mine = null; + + + List mines = PrisonMines.getInstance().getMineManager().getMines(); + + if ( countTotalMines == 0 ) { + + countTotalMines = mines.size(); + } + + for (Mine m : mines ) { + + // Check to see if we can even submit the job: + if ( !m.isVirtual() && + m.getResetCount() == 0 + && m.refreshAirCountSyncTaskCheckBeforeSubmit() ) { + + // Prevents the mine from being counted again: + m.setResetCount( 1 ); + + countCurrentMine++; + + mine = m; + processedMines.add( m ); + + break; + } + } - OnStartupRefreshBlockBreakCountSyncTask syncTask = - new OnStartupRefreshBlockBreakCountSyncTask( mine ); + if ( mine == null ) { + // done processing: + + TreeSet minesNotProcessed = new TreeSet<>( mines ); + minesNotProcessed.removeAll(processedMines); + + for (Mine m : minesNotProcessed) { + countCurrentMine++; - // Check to see if we can even submit the job: - if ( mine.refreshAirCountSyncTaskCheckBeforeSubmit() ) { + String msg = String.format( + "MineReset startup air-count: Mine [%3d of %3d]: %-10s " + + " Skipped: virtual: %b resetCounts: %s", + countCurrentMine, + countTotalMines, + m.getName(), + m.isVirtual(), + m.getResetCount() + + ); + + Output.get().logInfo( msg ); + + } + + String message = String.format( + "MineReset startup air-count: Completed. [%3d - %3d]: " + + "Mines not processed: %d", + countCurrentMine, + countTotalMines, + minesNotProcessed.size() ); - // The first phase generates a List of Locations which - // can be ran async... - syncTask.setJobId( mine.submitAsyncTask( syncTask, delay ) ); + Output.get().logInfo( message ); } + return mine; } private void resubmit() { - // Must run synchronously!! - - - long submitDelay = 0; - - + long delay = 0; - setJobId( mine.submitSyncTask( this, submitDelay ) ); + if ( mine == null ) { + mine = getNextMine(); + locations = null; + + pagesStart = pages; + + elapsedNanos = 0; + + delay = 2; + } + + if ( mine != null ) { + + // Must run synchronously!! + setJobId( mine.submitSyncTask( this, delay ) ); + } } @Override public void run() { + + if ( mine == null ) { + mine = getNextMine(); + locations = null; + } + if ( locations == null ) { - long nanoStart = System.nanoTime(); - locations = this.mine.refreshAirCountSyncTaskBuildLocations(); - long nanoEnd = System.nanoTime(); - long elpased = (nanoEnd - nanoStart ); - this.elapsedNanos += elpased; + if ( mine != null ) { + + long nanoStart = System.nanoTime(); + locations = this.mine.refreshAirCountSyncTaskBuildLocations(); + long nanoEnd = System.nanoTime(); + long elpased = (nanoEnd - nanoStart ); + this.elapsedNanos += elpased; + +// resubmit(); + } - resubmit(); } - else { +// else // The 'this.mine.refreshAirCountSyncTaskBuildLocations()' is trivial... + { + pages++; long nanoStart = System.nanoTime(); @@ -84,13 +209,13 @@ public void run() { long nanoEnd = System.nanoTime(); long elpased = (nanoEnd - nanoStart ); - long elapsedMs = elpased / 1000000; - if ( elapsedMs > 15 ) { + long elapsedMs = elpased / 1_000_000; + if ( elapsedMs > 20 ) { - // Check every 500 blocks and if been running longer than 15 ms then yield to prevent lag + // Check every 500 blocks and if been running longer than 20 ms then yield to prevent lag this.elapsedNanos += elpased; - pages++; +// pages++; // Need to yield and resubmit resubmit(); @@ -102,7 +227,6 @@ public void run() { // It will only hit this point when done processing all of the locations: - pages++; mine.setAirCount( getAirCount() ); mine.setBlockBreakCount( mine.getBlockBreakCount() + getAirCount() ); @@ -112,20 +236,27 @@ public void run() { this.elapsedNanos += elpased; double elapsedMs = ((double) elapsedNanos) / 1000000d; + elapsedMsTotal += elapsedMs; mine.setAirCountElapsedTimeMs( (long) elapsedMs ); mine.setAirCountTimestamp( System.currentTimeMillis() ); if ( Output.get().isDebug() ) { + DecimalFormat dFmt = Prison.get().getDecimalFormatDouble(); DecimalFormat iFmt = Prison.get().getDecimalFormatInt(); String message = String.format( - "MineReset startup air-count: Mine: %-6s " + - " blocks: %10s pages: %s elapsed %s ms", + "MineReset startup air-count: Mine [%3d of %3d]: %-10s " + + " blocks: %10s pages: [%3s: %3s] [%9s: %9s ms]", + countCurrentMine, + countTotalMines, mine.getName(), iFmt.format( locations.size() ), + iFmt.format( pages - pagesStart ), iFmt.format( pages ), - dFmt.format(elapsedMs) ); + dFmt.format(elapsedMs), + dFmt.format(elapsedMsTotal) + ); Output.get().logInfo( message ); @@ -140,8 +271,29 @@ public void run() { Output.get().logWarn( message ); } + + // Finalize by setting mine and locations to null so it will reset properly the next time: + locations = null; + mine = null; + } + // Submit the next mine, which will be assigned in resubmit(): + resubmit(); + } + +// public List getMines() { +// return mines; +// } +// public void setMines(List mines) { +// this.mines = mines; +// } + + public MineReset getMine() { + return mine; + } + public void setMine(MineReset mine) { + this.mine = mine; } public int getJobId() { 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 2a1513338..5d6a8739c 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 @@ -35,6 +35,7 @@ import tech.mcprison.prison.internal.block.PrisonBlock.PrisonBlockType; import tech.mcprison.prison.mines.PrisonMines; import tech.mcprison.prison.mines.data.Mine; +import tech.mcprison.prison.mines.data.OnStartupRefreshBlockBreakCountSyncTask; import tech.mcprison.prison.mines.data.MineScheduler.MineResetActions; import tech.mcprison.prison.mines.data.MineScheduler.MineResetScheduleType; import tech.mcprison.prison.mines.data.PrisonSortableResults; @@ -254,6 +255,10 @@ public void loadFromDbCollection( PrisonMines pMines ) { getMines().size(), offsetTimingMs)); + // Start task to count air blocks: + OnStartupRefreshBlockBreakCountSyncTask.getInstance().submit( 60 ); + + // // When finished loading the mines, then if there are any worlds that // // could not be loaded, dump the details: // List unavailableWorlds = getUnavailableWorldsListings(); @@ -667,7 +672,7 @@ public void assignAvailableWorld( String worldName ) { // List remove = new ArrayList<>(); - long delay = 0; +// long delay = 0; for ( Mine mine : unenabledMines ) { if ( !mine.isEnabled() ) { @@ -692,7 +697,7 @@ public void assignAvailableWorld( String worldName ) { } // Run the air-counts now that mine can be activated: - mine.refreshBlockBreakCountUponStartup( delay++ ); +// mine.refreshBlockBreakCountUponStartup( delay++ ); } @@ -700,6 +705,11 @@ public void assignAvailableWorld( String worldName ) { // remove.add( mine ); } + + // Count the blocks for the mines that were just loaded.. 2 sec delay + OnStartupRefreshBlockBreakCountSyncTask.getInstance().submit( 40 ); + + // // Purge all removed mines from the unenabledMines list: // if ( remove.size() > 0 ) { // unenabledMines.removeAll( remove ); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/spiget/PrisonSpigetUpdateCheckTask.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/spiget/PrisonSpigetUpdateCheckTask.java index d53812af4..1a53424bf 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/spiget/PrisonSpigetUpdateCheckTask.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/spiget/PrisonSpigetUpdateCheckTask.java @@ -10,7 +10,7 @@ public class PrisonSpigetUpdateCheckTask implements PrisonRunnable { - private long delayTicks = 5 * 20; // 5 seconds + private long delayTicks = 8 * 20; // 8 seconds private int taskId = 0; From 64d2cae99c84681798c89f1cccb5e7cf35f50597 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 8 Sep 2024 23:56:09 -0400 Subject: [PATCH 172/323] Ranks and Ladders: Changed the way the ladder and rank file names are saved. Instead of using their IDs, it is now using their names. The file names are converted upon loading. Once loaded, and converted, the prison config setup cannot be reverted, but the old settings and files will be saved in the saved directories and can be restored if needed. Rank IDs and Ladder IDs are no longer used internally. They are being kept for now, but will be removed in the future. --- docs/changelog_v3.3.x.md | 5 + .../mcprison/prison/file/FileCollection.java | 95 ++++++++++++---- .../tech/mcprison/prison/ranks/data/Rank.java | 17 ++- .../prison/ranks/data/RankLadder.java | 14 ++- .../mcprison/prison/store/Collection.java | 8 +- .../mcprison/prison/util/ConversionUtil.java | 4 +- .../prison/mines/commands/MinesCommands.java | 8 +- .../prison/mines/managers/MineManager.java | 2 +- .../prison/ranks/data/RankFactory.java | 6 +- .../prison/ranks/data/RankLadderFactory.java | 107 +++++++++++++++++- .../prison/ranks/managers/LadderManager.java | 63 +++++++++-- .../prison/ranks/managers/PlayerManager.java | 2 +- .../prison/ranks/managers/RankManager.java | 76 ++++++++++--- .../PlayerNewFileNameCheckAsyncTask.java | 6 +- 14 files changed, 350 insertions(+), 63 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 04e459d9e..9113873e7 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.19 2024-09-08 +* **Ranks and Ladders: Changed the way the ladder and rank file names are saved. Instead of using their IDs, it is now using their names.** +The file names are converted upon loading. Once loaded, and converted, the prison config setup cannot be reverted, but the old settings and files will be saved in the saved directories and can be restored if needed. +Rank IDs and Ladder IDs are no longer used internally. They are being kept for now, but will be removed in the future. + + * **Mines: Air Block Counts: Improvement. Rewrote the way prison is handling the air block counts because they were causing the servers to fall behind on TPS by a significant amount.** The server, depending upon how many mines, and how large they were, the system (spigot, paper, etc) would warn that it was running behind by 50 ticks to a few hundred ticks. The primary reason was that all the mines would be submitted to run almost at the same time, in different threads, so it would starve all available TPS. These changes were a complete rewrite on how the jobs are submitted and the mines are processed. Now it's just one initial job submission, instead of each mine submitting it's own task. And that one new job steps through each mine, one at time, counting the blocks, and then moving on to the next mine. As such, we are not ensuring only one task is trying to run at the same time, thus allowing other services to get sufficient access to the processing that they need. Where a mine-heavy test server was reporting falling behind by 600+ ticks, after these changes there were no warnings. During, and right after the air counts, the server is reporting a solid 20 TPS. diff --git a/prison-core/src/main/java/tech/mcprison/prison/file/FileCollection.java b/prison-core/src/main/java/tech/mcprison/prison/file/FileCollection.java index fb4ee4766..947059d88 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/file/FileCollection.java +++ b/prison-core/src/main/java/tech/mcprison/prison/file/FileCollection.java @@ -86,43 +86,100 @@ public List getAll() { @Override public Optional get(String key) { - String suffix = key.endsWith(FILE_SUFFIX_JSON) ? "" : FILE_SUFFIX_JSON; - File dbFile = new File(collDir, key + suffix); + File dbFile = getFile(key); Document doc = (Document) readJsonFile(dbFile, new Document()); return Optional.ofNullable(doc); } - @Override - public void save(Document document) - { - save((String)document.get("name"), document); - } +// @Override +// public void save(Document document) +// { +// save((String)document.get("name"), document); +// } - @Override - public void save(String filename, Document document) - { - String suffix = filename.endsWith(FILE_SUFFIX_JSON) ? "" : FILE_SUFFIX_JSON; - File dbFile = new File(collDir, filename + suffix); +// @Override +// public void save(String filename, Document document) +// { +// String suffix = filename.endsWith(FILE_SUFFIX_JSON) ? "" : FILE_SUFFIX_JSON; +// File dbFile = new File(collDir, filename + suffix); +// saveJsonFile( dbFile, document ); +// } + + + @Override + public void save(String filename, Document document, + String oldFilename, String fileType ) { + + File dbFile = getFile(filename); saveJsonFile( dbFile, document ); - } + + if ( oldFilename != null ) { + + // Since the new file should have been saved by now... + File oldDbFile = getFile(oldFilename); + + // If both the new file and old file exists, then need to remove the old file: + if ( dbFile.exists() && dbFile.length() > 0 && oldDbFile.exists() ) { + + boolean deleted = oldDbFile.delete(); + + if ( deleted ) { + + Output.get().logInfo( + "&3%s File Converted: &7%s &3--> &7%s", + fileType, + oldFilename + FILE_SUFFIX_JSON, + filename + FILE_SUFFIX_JSON + ); + } + else { + Output.get().logInfo( + "&3The old %s file could not be removed: " + + "Old file &7%s &3. " + + "Reason unknown (check logs?). " + + "New file name &7%s. [%s]", + fileType, + oldFilename + FILE_SUFFIX_JSON, + filename + FILE_SUFFIX_JSON, + oldDbFile.getAbsolutePath() + ); + + } + } + } + } + + private File getFile(String name) + { + String suffix = name.endsWith(FILE_SUFFIX_JSON) ? "" : FILE_SUFFIX_JSON; + File dbFile = new File(collDir, name + suffix); + return dbFile; + } + + @Override + public boolean exists(String name) + { + File dbFile = getFile(name); + return dbFile.exists(); + } + @Override public boolean delete(String name) { - String suffix = name.endsWith(FILE_SUFFIX_JSON) ? "" : FILE_SUFFIX_JSON; - File dbFile = new File(collDir, name + suffix); - return virtualDelete( dbFile ); + File dbFile = getFile(name); + return dbFile.exists() ? virtualDelete( dbFile ) : false; } @Override public File backup( String name ) { - String suffix = name.endsWith(FILE_SUFFIX_JSON) ? "" : FILE_SUFFIX_JSON; - File dbFile = new File(collDir, name + suffix); - File backupFile = virtualBackup( dbFile ); + File dbFile = getFile(name); + File backupFile = dbFile.exists() ? virtualBackup( dbFile ) : null; return backupFile; } + } 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 007d2fd87..2f05c3a23 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 @@ -83,6 +83,8 @@ public class Rank private transient final StatsRankPlayerBalance statsPlayerBlance; + private transient boolean dirty = false; + public Rank() { super(); @@ -314,8 +316,12 @@ public String toString() { return "Rank: " + id + " " + name; } - public String filename() { - return "rank_" + id; + public String filenameNew() { + return "rank_" + getName(); + } + + public String filenameOld() { + return getId() == -1 ? null : "rank_" + getId(); } @@ -559,4 +565,11 @@ public List getPlayers() { return players; } + public boolean isDirty() { + return dirty; + } + public void setDirty(boolean dirty) { + this.dirty = dirty; + } + } diff --git a/prison-core/src/main/java/tech/mcprison/prison/ranks/data/RankLadder.java b/prison-core/src/main/java/tech/mcprison/prison/ranks/data/RankLadder.java index d35788ce7..9e6169aed 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/ranks/data/RankLadder.java +++ b/prison-core/src/main/java/tech/mcprison/prison/ranks/data/RankLadder.java @@ -55,7 +55,7 @@ public class RankLadder private double rankCostMultiplierPerRank = 0.0d; private boolean applyRankCostMultiplierToLadder = true; - private boolean dirty = false; + private transient boolean dirty = false; public RankLadder() { @@ -213,7 +213,10 @@ public boolean isPrestiges() { public Document toDocument() { Document ret = new Document(); - ret.put("id", this.id); + + if ( this.id != -1 ) { + ret.put("id", this.id); + } ret.put("name", this.name); List cmds = new ArrayList<>(); @@ -232,7 +235,12 @@ public Document toDocument() { LinkedTreeMap rnk = new LinkedTreeMap(); // rnk.put( "position", rank.getPosition() ); - rnk.put( "rankId", rank.getId() ); + + // Do not save the rank ID in the ladder file: +// if ( rank.getId() != -1 ) { +// rnk.put( "rankId", rank.getId() ); +// } + rnk.put( "rankName", rank.getName()); ranksLocal.add( rnk ); diff --git a/prison-core/src/main/java/tech/mcprison/prison/store/Collection.java b/prison-core/src/main/java/tech/mcprison/prison/store/Collection.java index 49b8aee74..e2fa7e62c 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/store/Collection.java +++ b/prison-core/src/main/java/tech/mcprison/prison/store/Collection.java @@ -32,10 +32,14 @@ public interface Collection { public Optional get(String key); - public void save(Document document); - public void save(String filename, Document document); +// public void save(Document document); +// public void save(String filename, Document document); + public void save(String filename, Document document, + String oldFilename, String fileType); + boolean exists(String name); + public boolean delete(String name); public File backup(String name); diff --git a/prison-core/src/main/java/tech/mcprison/prison/util/ConversionUtil.java b/prison-core/src/main/java/tech/mcprison/prison/util/ConversionUtil.java index b70e97444..bb7381ffe 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/util/ConversionUtil.java +++ b/prison-core/src/main/java/tech/mcprison/prison/util/ConversionUtil.java @@ -4,11 +4,11 @@ public class ConversionUtil { public static int doubleToInt(Object d) { - return Math.toIntExact(Math.round((double) d)); + return d == null ? -1 : Math.toIntExact(Math.round((double) d)); } public static long doubleToLong(Object d) { - return Math.round((double) d); + return d == null ? -1 : Math.round((double) d); } } 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 ba7ad0905..0e230288c 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 @@ -2774,8 +2774,8 @@ else if ( source == null || "virtual".equalsIgnoreCase( source ) ) { File backupFile = pMines.getMineManager().backupMine( m ); String messageBu = "Mine &7" + m.getName() + " &3has " + - ( backupFile.exists() ? "been successfully" : "failed to be" ) + - " backed up: " + backupFile.getAbsolutePath(); + ( backupFile != null && backupFile.exists() ? "been successfully" : "failed to be" ) + + " backed up: " + (backupFile != null ? backupFile.getAbsolutePath() : "none"); sender.sendMessage( messageBu ); Output.get().logInfo( messageBu ); @@ -2960,8 +2960,8 @@ public void backupMineCommand(CommandSender sender, File backupFile = pMines.getMineManager().backupMine( m ); String messageBu = "Mine &7" + m.getName() + " &3has " + - ( backupFile.exists() ? "been successfully" : "failed to be" ) + - " backed up: " + backupFile.getAbsolutePath(); + ( backupFile != null && backupFile.exists() ? "been successfully" : "failed to be" ) + + " backed up: " + (backupFile != null ? backupFile.getAbsolutePath() : "none"); if ( sender.isPlayer() ) { sender.sendMessage( messageBu ); 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 5d6a8739c..fc88b70d7 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 @@ -375,7 +375,7 @@ private void loadMines( long offsetTimingMs ) { * PrisonMines} */ public void saveMine(Mine mine) { - coll.save(mine.toDocument()); + coll.save( mine.getName(), mine.toDocument(), null, "Mine" ); } public void saveMines(){ diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankFactory.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankFactory.java index 127610aac..7efe71561 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankFactory.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankFactory.java @@ -103,7 +103,11 @@ public Rank createRank( Document document ) public Document toDocument( Rank rank ) { Document ret = new Document(); // ret.put("position", this.position ); - ret.put("id", rank.getId()); + + if ( rank.getId() != -1 ) { + ret.put("id", rank.getId()); + } + ret.put("name", rank.getName() ); ret.put("tag", (rank.getTag() == null ? "none" : rank.getTag()) ); ret.put("cost", rank.getCost() ); diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankLadderFactory.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankLadderFactory.java index 296dc04a4..856a8543a 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankLadderFactory.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankLadderFactory.java @@ -10,15 +10,71 @@ import tech.mcprison.prison.store.Document; import tech.mcprison.prison.util.ConversionUtil; + +/** + *

Conversion of IDs: In general, IDs should not be used. The newer + * format of working with ranks and ladders, is that only the rank's name + * should be used to link ranks to ladders. It's a one way path, where only + * the ladders are saved with a group of ranks. A saved rank has no idea what + * ladder, if any, that it's tied to. + *

+ * + *

The conversion process is simple and does not have to be concerned with + * reverting back to using IDs or adding an id when it has a value of -1. + * The only thing that will change is that new ranks and ladders will be given + * an id of -1. If upon saving an id is -1, then it will not be included in the + * save file. If a rank or ladder already has an id, it will not be changed and + * it will be continually saved with the rank and ladder. + *

+ * + *

The only real "conversion" process is when ladders are loaded, and if a + * rank does not have a name, then it will be joined by the id, then when + * the ladder is fully loaded, it will be resaved, thus dropping the rank + * ids within the ladder's save file. + *

+ * + *

Ranks are always loaded before ladders. + *

+ * + */ public class RankLadderFactory { + public RankLadderFactory() { + super(); + + } + + /** + *

This function loads a ladder from a save file. + *

+ * + *

For conversion to eliminating IDs, if a rank or a ladder has an + * id, then keep it for now. If a rank was saved in the ladder without a + * name, then the ladder needs to be resaved, after loading all ranks + * so the ids won't be saved with the new format. If a rank name is not + * loaded, then the ids will be used to connect the ranks to the ladder. + * Otherwise the name will be used. + *

+ * + *

No special processing needs to be used in the loading of the ladder, + * except to track when a rank does not have a name to trigger a resave at + * the end of the loading process by setting 'isDirty' to true. + *

+ * + * + * @param document + * @param rankManager + * @return + */ @SuppressWarnings( "unchecked" ) public RankLadder createRankLadder(Document document, RankManager rankManager) { RankLadder rankLadder = null; boolean isDirty = false; + + // If an "id" field is not found, doubleToInt will now return a -1. int id = ConversionUtil.doubleToInt(document.get("id")); String name = (String) document.get("name"); @@ -76,14 +132,53 @@ public RankLadder createRankLadder(Document document, RankManager rankManager) { int rRankId = ConversionUtil.doubleToInt((rank.get("rankId"))); String rRankName = (String) rank.get( "rankName" ); - Rank rankPrison = rankManager.getRank( rRankId ); + Rank rankPrison = null; + + if ( rRankId != -1 ) { + // the file was saved with rankIds, so resave to remove them: + isDirty = true; + } + + if ( rRankName == null || rRankName.trim().length() == 0 ) { + + // NOTICE: Loading an older save file that has not been converted + // yet. No name was saved, so link with id and then set + // isDirty to true. + isDirty = true; + + rankPrison = rankManager.getRank( rRankId ); + + } + else { + // Load rank by name: + rankPrison = rankManager.getRank( rRankName ); + + } + if ( rankPrison != null && rankPrison.getLadder() != null ) { - RankMessages rMessages = new RankMessages(); - rMessages.rankFailureLoadingDuplicateRankMsg( - rankPrison.getName(), rankPrison.getLadder().getName(), - rankLadder.getName() ); + if ( rankPrison.getLadder().equals( rankLadder ) ) { + // ignore: The selected rank is already on this ladder. + } + else { + + String msg = String.format( + "&4Loading ladder: %s Rank %s is already assigned to the %s ladder. " + + "You may need to manually move the rank if this is incorrect. ", + rankLadder.getName(), + rankPrison.getName(), + rankPrison.getLadder().getName() + ); + Output.get().logInfo( msg ); + + } + +// RankMessages rMessages = new RankMessages(); +// rMessages.rankFailureLoadingDuplicateRankMsg( +// rankPrison.getName(), +// rankPrison.getLadder().getName(), +// rankLadder.getName() ); isDirty = true; } @@ -159,6 +254,8 @@ else if ( rankPrison != null) { // } // } + + if ( isDirty ) { PrisonRanks.getInstance().getLadderManager().save( rankLadder ); } 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 5b4db10ea..a7ccd8859 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 @@ -110,6 +110,10 @@ public void loadLadders( RankManager rankManager ) rlFactory.createRankLadder(document, rankManager)) ); for ( RankLadder ladder : loadedLadders ) { + + // If old file exists, then set dirty so it can be saved and update the file name: + checkIfOldFileExists( ladder ); + // Will be dirty if load a ladder and the rank name does not exist and it adds them: if ( ladder.isDirty() ) { saveLadder(ladder); @@ -118,14 +122,27 @@ public void loadLadders( RankManager rankManager ) } /** + * If the old file name exists, then this ladder has not been upgraded + * yet. So set it to dirty so it can be saved and update the file name. + * + * @param ladder + */ + private void checkIfOldFileExists(RankLadder ladder) { + if ( collection.exists( getLadderNameOld(ladder) )) { + ladder.setDirty( true ); + } + } + + /** * Saves a ladder to its save file. * * @param ladder The {@link RankLadder} to save. * @param fileKey The key to write the ladder as. + * @param oldFileName The old file name based upon id. * @throws IOException If the ladder could not be serialized, or if the ladder could not be saved to the file. */ - public void saveLadder(RankLadder ladder, String fileKey) throws IOException { - collection.save(fileKey, ladder.toDocument()); + public void saveLadder(RankLadder ladder, String fileKey, String oldFileName) throws IOException { + collection.save(fileKey, ladder.toDocument(), oldFileName, "Ladder"); } /** @@ -135,11 +152,28 @@ 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, getLadderName(ladder)); + + String fileLadderNameNew = getLadderNameNew(ladder); + String fileLadderNameOld = getLadderNameOld(ladder); + + this.saveLadder(ladder, fileLadderNameNew, fileLadderNameOld); } - private String getLadderName( RankLadder ladder ) { - return "ladder_" + ladder.getId(); + private String getLadderNameNew( RankLadder ladder ) { + return "ladder_" + ladder.getName(); + } + + /** + * This function will generate an old ladder name only if the id is not + * -1. If it's -1, then there is no need to return anything other than null. + * This will be used to identify if an old file exists so it can be removed + * when the newer format is saved. + * + * @param ladder + * @return + */ + private String getLadderNameOld( RankLadder ladder ) { + return ladder.getId() == -1 ? null : "ladder_" + ladder.getId(); } /** @@ -251,7 +285,9 @@ public boolean removeLadder(RankLadder ladder) { loadedLadders.remove(ladder); // ... and remove the ladder's save files. - collection.delete("ladder_" + ladder.getId()); + collection.delete( getLadderNameNew(ladder) ); + collection.delete( getLadderNameOld(ladder) ); + // collection.remove("ladder_" + ladder.id); return true; } @@ -379,10 +415,23 @@ public String getLadderByFileName(String fileName) { String results = ""; for (RankLadder rankLadder : loadedLadders) { - String ladderFileName = getLadderName(rankLadder) + ".json"; + + // NOTE: if the ladder was renamed, will need to check the old + // name? + + // Check using the new file name for the ladder: + String ladderFileName = getLadderNameNew(rankLadder) + ".json"; if ( ladderFileName.equalsIgnoreCase(fileName) ) { results = rankLadder.getName(); } + else { + + // Check using the old file name for the ladder: + String ladderFileName2 = getLadderNameOld(rankLadder) + ".json"; + if ( ladderFileName2.equalsIgnoreCase(fileName) ) { + results = rankLadder.getName(); + } + } } return results; } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java index 4b7362261..086d2f53f 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java @@ -170,7 +170,7 @@ private boolean savePlayer(RankPlayer player, String playerFile) throws IOExcept if ( !player.isEnableDirty() || player.isEnableDirty() && player.isDirty() ) { - collection.save(playerFile, RankPlayerFactory.toDocument( player ) ); + collection.save(playerFile, RankPlayerFactory.toDocument( player ), null, "Player" ); player.setDirty( false ); 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 c6d5565cc..9f6b049d0 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 @@ -141,7 +141,10 @@ private void addRank( Rank rank ) { getLoadedRanks().add( rank ); String rankName = rank.getName(); getRanksByName().put( rankName.toLowerCase(), rank ); - getRanksById().put( rank.getId(), rank ); + + if ( rank.getId() != -1 ) { + getRanksById().put( rank.getId(), rank ); + } // Do not have to reset position number since the new rank is // added to the end of the ladder's rank List, and therefore @@ -153,7 +156,11 @@ private void removeRankFromCollections( Rank rank ) { if ( rank != null ) { getLoadedRanks().remove( rank ); getRanksByName().remove( rank.getName().toLowerCase() ); - getRanksById().remove( rank.getId() ); + + if ( rank.getId() != -1 && getRanksById().containsKey( rank.getId() ) ) { + + getRanksById().remove( rank.getId() ); + } // Since the removal of a rank could shift the position of // more than one rank, then all positions should be reset. @@ -206,23 +213,43 @@ public void loadRanks() throws IOException { Rank rank = rankFactory.createRank( rankDocument ); addRank( rank ); - } + + // If old file exists, then set dirty so it can be saved and update the file name: + checkIfOldFileExists( rank ); + + if ( rank.isDirty() ) { + saveRank(rank); + } + } // ranks.forEach(document -> addRank(new Rank(document))); // ranks.forEach(document -> loadedRanks.add(new Rank(document))); } + + /** + * If the old file name exists, then this ladder has not been upgraded + * yet. So set it to dirty so it can be saved and update the file name. + * + * @param ladder + */ + private void checkIfOldFileExists(Rank rank) { + if ( collection.exists( rank.filenameOld() )) { + rank.setDirty( true ); + } + } + /** * Saves a rank to its save file. * * @param rank The {@link Rank} to save. * @param saveFile The key to write the rank as. Case sensitive. */ - public void saveRank(Rank rank, String saveFile) { + public void saveRank(Rank rank, String saveFileNew, String saveFileOld ) { RankFactory rankFactory = new RankFactory(); - collection.save(saveFile, rankFactory.toDocument( rank ) ); + collection.save(saveFileNew, rankFactory.toDocument( rank ), saveFileOld, "Ranks" ); } /** @@ -231,7 +258,7 @@ public void saveRank(Rank rank, String saveFile) { * @param rank The {@link Rank} to save. */ public void saveRank(Rank rank) { - this.saveRank(rank, rank.filename()); + this.saveRank(rank, rank.filenameNew(), rank.filenameOld() ); } /** @@ -278,10 +305,20 @@ public Optional createRank(String name, String tag, double cost) { */ private int getNextAvailableId() { - int current = (getRanksById().size() == 0 ? - -1 : getRanksById().lastKey().intValue()); + int current = -1; + + for (Rank rank : loadedRanks) { + if ( rank.getId() != -1 && rank.getId() > current ) { + current = rank.getId(); + } + } return current + 1; + +// current = (getRanksById().size() == 0 ? +// -1 : getRanksById().lastKey().intValue()); +// +// return current + 1; // // Set the highest to -1 for now, since we'll add one at the end // int highest = -1; @@ -425,7 +462,9 @@ public boolean removeRank(Rank rank) { // connectRanks(); // ... and remove the rank's save files. - collection.delete(rank.filename()); + // try both the old and new names: + collection.delete(rank.filenameNew()); + collection.delete(rank.filenameOld()); } return success; @@ -1584,10 +1623,17 @@ public String getRankByFileName(String fileName) { String results = ""; for (Rank rank : loadedRanks) { - String rankFileName = rank.filename() + ".json"; - if ( rankFileName.equalsIgnoreCase(fileName) ) { + String rankFileNameNew = rank.filenameNew() + ".json"; + if ( rankFileNameNew.equalsIgnoreCase(fileName) ) { results = rank.getName(); } + else { + String rankFileNameOld = rank.filenameOld() + ".json"; + if ( rankFileNameOld.equalsIgnoreCase(fileName) ) { + results = rank.getName(); + } + + } } return results; } @@ -1603,7 +1649,9 @@ public TreeMap getRanksByName() { public TreeMap getRanksById() { return ranksById; } - + public void setRanksById(TreeMap ranksById) { + this.ranksById = ranksById; + } public CommandCommands getRankCommandCommands() { return rankCommandCommands; @@ -1639,9 +1687,7 @@ public void setLoadedRanks(List loadedRanks) { public void setRanksByName(TreeMap ranksByName) { this.ranksByName = ranksByName; } - public void setRanksById(TreeMap ranksById) { - this.ranksById = ranksById; - } + private void resetAllRanks() { diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/tasks/PlayerNewFileNameCheckAsyncTask.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/tasks/PlayerNewFileNameCheckAsyncTask.java index 9c28b0f80..b1ce192b4 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/tasks/PlayerNewFileNameCheckAsyncTask.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/tasks/PlayerNewFileNameCheckAsyncTask.java @@ -16,7 +16,11 @@ /** * This task will run after the server starts up. - * If the 'prison-ranks.use-friendly-user-file-name' + * If the 'prison-ranks.use-friendly-user-file-name' is set. + * + * Please note: this is no longer used. Prison now will automatically + * convert individual files as needed. This will try to convert + * everything at once, but is not required. */ public class PlayerNewFileNameCheckAsyncTask implements PrisonRunnable { From 1357adc2375d837e29859c7ad5a4b692cf7dc9b9 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 9 Sep 2024 00:28:53 -0400 Subject: [PATCH 173/323] Ranks and Ladders: Minor adjustment to properly load ranks and ladders that do not have a rank ID or a ladder ID. --- .../tech/mcprison/prison/file/FileCollection.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/prison-core/src/main/java/tech/mcprison/prison/file/FileCollection.java b/prison-core/src/main/java/tech/mcprison/prison/file/FileCollection.java index 947059d88..40dfa3e93 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/file/FileCollection.java +++ b/prison-core/src/main/java/tech/mcprison/prison/file/FileCollection.java @@ -161,8 +161,15 @@ private File getFile(String name) @Override public boolean exists(String name) { - File dbFile = getFile(name); - return dbFile.exists(); + boolean results = false; + + if ( name != null && name.trim().length() > 0 ) { + + File dbFile = getFile(name); + results = dbFile.exists(); + } + + return results; } @Override From d694b0eba248831a34fada509e3faeeabedd43a3 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 9 Sep 2024 00:43:43 -0400 Subject: [PATCH 174/323] Ranks and Ladders: Minor changes to prevent new ranks and ladders from getting assigned a non -1 id. All new ranks and ladders will have an id of -1. All existing ranks and ladders will keep their ids. --- docs/changelog_v3.3.x.md | 6 +++++- .../tech/mcprison/prison/ranks/managers/LadderManager.java | 7 +++++-- .../tech/mcprison/prison/ranks/managers/RankManager.java | 7 +++++-- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 9113873e7..a39d5efeb 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.19 2024-09-08 +# 3.3.0-alpha.19 2024-09-09 + + +* **Ranks and Ladders: Minor changes to prevent new ranks and ladders from getting assigned a non -1 id.** +All new ranks and ladders will have an id of -1. All existing ranks and ladders will keep their ids. * **Ranks and Ladders: Changed the way the ladder and rank file names are saved. Instead of using their IDs, it is now using their names.** 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 a7ccd8859..953640ff1 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 @@ -229,7 +229,9 @@ public void saveLadders() throws IOException { */ public RankLadder createLadder(String name) { // Set the default values... - RankLadder newLadder = new RankLadder( getNextAvailableId(), name ); + // ladder id is no longer used, so use -1: + RankLadder newLadder = new RankLadder( -1, name ); +// RankLadder newLadder = new RankLadder( getNextAvailableId(), name ); // ... add it to the list... loadedLadders.add(newLadder); @@ -244,7 +246,8 @@ public RankLadder createLadder(String name) { * * @return The next available ladder's ID. */ - private int getNextAvailableId() { + @SuppressWarnings("unused") + private int getNextAvailableId() { // Set the highest to -1 for now, since we'll add one at the end int highest = -1; 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 9f6b049d0..689975cc0 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 @@ -285,7 +285,9 @@ public void saveRanks() { public Optional createRank(String name, String tag, double cost) { // Set the default values... - Rank newRank = new Rank( getNextAvailableId(), name, tag, cost ); + // rank id is no longer used, so use -1: + Rank newRank = new Rank( -1, name, tag, cost ); +// Rank newRank = new Rank( getNextAvailableId(), name, tag, cost ); // ... add it to the list... addRank(newRank); @@ -303,7 +305,8 @@ public Optional createRank(String name, String tag, double cost) { * * @return The next available rank's ID. */ - private int getNextAvailableId() { + @SuppressWarnings("unused") + private int getNextAvailableId() { int current = -1; From a8f4e01692dc6349b4d3424e219c34dbb4a512be Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 9 Sep 2024 00:45:42 -0400 Subject: [PATCH 175/323] Mines: Air block counts: Minor change to the completed message to be more consistent with the other similar messages. Changed "-" to "of". --- docs/changelog_v3.3.x.md | 4 ++++ .../mines/data/OnStartupRefreshBlockBreakCountSyncTask.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 a39d5efeb..157ba98f7 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.19 2024-09-09 +* **Mines: Air block counts: Minor change to the completed message to be more consistent with the other similar messages.** +Changed "-" to "of". + + * **Ranks and Ladders: Minor changes to prevent new ranks and ladders from getting assigned a non -1 id.** All new ranks and ladders will have an id of -1. All existing ranks and ladders will keep their ids. diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/OnStartupRefreshBlockBreakCountSyncTask.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/OnStartupRefreshBlockBreakCountSyncTask.java index cba115b05..7afaf2838 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/OnStartupRefreshBlockBreakCountSyncTask.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/OnStartupRefreshBlockBreakCountSyncTask.java @@ -134,7 +134,7 @@ private Mine getNextMine() { } String message = String.format( - "MineReset startup air-count: Completed. [%3d - %3d]: " + + "MineReset startup air-count: Completed. [%3d of %3d]: " + "Mines not processed: %d", countCurrentMine, countTotalMines, From 2326b7ea33d849f308ff5f1b84363f9c9ff2964e Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 9 Sep 2024 04:28:02 -0400 Subject: [PATCH 176/323] Mines: Air Block Counts: A few more fixes. Found that 'position' was not being reset on each mine, which was causing partial, or no resets for most mines. --- docs/changelog_v3.3.x.md | 3 +++ .../mines/data/OnStartupRefreshBlockBreakCountSyncTask.java | 6 ++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 157ba98f7..dffa829fa 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.19 2024-09-09 +* **Mines: Air Block Counts: A few more fixes. Found that 'position' was not being reset on each mine, which was causing partial, or no resets for most mines.** + + * **Mines: Air block counts: Minor change to the completed message to be more consistent with the other similar messages.** Changed "-" to "of". diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/OnStartupRefreshBlockBreakCountSyncTask.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/OnStartupRefreshBlockBreakCountSyncTask.java index 7afaf2838..a904d6bc3 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/OnStartupRefreshBlockBreakCountSyncTask.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/OnStartupRefreshBlockBreakCountSyncTask.java @@ -153,6 +153,7 @@ private void resubmit() { if ( mine == null ) { mine = getNextMine(); locations = null; + position = 0; pagesStart = pages; @@ -164,7 +165,8 @@ private void resubmit() { if ( mine != null ) { // Must run synchronously!! - setJobId( mine.submitSyncTask( this, delay ) ); + setJobId( PrisonTaskSubmitter.runTaskLater( this, delay) ); +// setJobId( mine.submitSyncTask( this, delay ) ); } } @@ -205,7 +207,7 @@ public void run() { mine.refreshAirCountSyncTaskSetLocation( targetLocation, this ); position++; - if ( (i - start) % 500 == 0 ) { + if ( i != start && (i - start) % 500 == 0 ) { long nanoEnd = System.nanoTime(); long elpased = (nanoEnd - nanoStart ); From e3d39459c7a886fad945a52b9027e88ad3ab2537 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 9 Sep 2024 04:29:02 -0400 Subject: [PATCH 177/323] Minor: variable not being used, so commented out to eliminate a compile warning. --- docs/changelog_v3.3.x.md | 3 +++ prison-core/src/main/java/tech/mcprison/prison/Prison.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 dffa829fa..17ca77a1d 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.19 2024-09-09 +* **Minor: variable not being used, so commented out to eliminate a compile warning.** + + * **Mines: Air Block Counts: A few more fixes. Found that 'position' was not being reset on each mine, which was causing partial, or no resets for most mines.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/Prison.java b/prison-core/src/main/java/tech/mcprison/prison/Prison.java index f2fac8b72..3c6fcd776 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/Prison.java +++ b/prison-core/src/main/java/tech/mcprison/prison/Prison.java @@ -259,7 +259,7 @@ public void setupJUnitInstance( Platform platform ) { * Note that modules should not call this method. This is solely for the implementations. */ public void init(Platform platform, String minecraftVersion ) { - long startTime = System.currentTimeMillis(); + //long startTime = System.currentTimeMillis(); this.platform = platform; From 138794bec7292ac324e485b851641696296fc645 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 9 Sep 2024 04:30:31 -0400 Subject: [PATCH 178/323] Block Break Listeners: If in debug mode, and there is a fast fail, or an ignore on the blocks being broken, log the reasons why. --- docs/changelog_v3.3.x.md | 3 +++ .../spigot/block/OnBlockBreakEventCore.java | 5 +++++ .../spigot/block/OnBlockBreakMines.java | 21 +++++++++++++++---- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 17ca77a1d..48c7f6d2e 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.19 2024-09-09 +* **Block Break Listeners: If in debug mode, and there is a fast fail, or an ignore on the blocks being broken, log the reasons why.** + + * **Minor: variable not being used, so commented out to eliminate a compile warning.** 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 19a6f897d..3c324bb24 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 @@ -156,14 +156,19 @@ public enum ItemLoreEnablers { protected MinesEventResults ignoreMinesBlockBreakEvent( Cancellable event, Player player, Block block, BlockBreakPriority bbPriority, boolean ignoreBlockReuse ) { + + String eventName = event.getClass().getSimpleName(); MinesEventResults eventResults = ignoreMinesBlockBreakEvent( player, block, bbPriority, ignoreBlockReuse ); + eventResults.setEventName( eventName ); if ( eventResults.isCancelEvent() ) { event.setCancelled( eventResults.isCancelEvent() ); } + eventResults.logDebugInfo(); + // return eventResults.isIgnoreEvent(); return eventResults; } 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 06252e9a5..ae943bd69 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 @@ -73,7 +73,9 @@ public class MinesEventResults { private boolean cancelEvent = false; private boolean ignoreEvent = false; - BlockBreakPriority bbPriority; + private String eventName; + + private BlockBreakPriority bbPriority; private Mine mine = null; private SpigotPlayer sPlayer; @@ -90,9 +92,12 @@ public MinesEventResults( BlockBreakPriority bbPriority, SpigotPlayer sPlayer, B } public void logDebugInfo() { - if ( isIgnoreEvent() && + if ( (isIgnoreEvent() || isCancelEvent()) && Output.get().isDebug() ) { + String eventName = getEventName() != null && getEventName().trim().length() > 0 ? + "[event: " + getEventName() + "] " : ""; + String blockName = getSpigotBlock() == null ? "noPrisonBlock" : getSpigotBlock().getBlockName(); @@ -100,7 +105,8 @@ public void logDebugInfo() { "" : getSpigotBlock().getLocation().toWorldCoordinates(); - Output.get().logInfo( "Prison AutoFeatures Fast-Fail: %s %s %s %s%s", + Output.get().logInfo( "Prison AutoFeatures Fast-Fail: %s%s %s %s %s%s", + eventName, getResultsReason().name(), //getBbPriority().name(), getSpigotPlayer().getName(), @@ -140,6 +146,13 @@ public void setResultsReason(EventResultsReasons resultsReason) { this.resultsReason = resultsReason; } + public String getEventName() { + return eventName; + } + public void setEventName(String eventName) { + this.eventName = eventName; + } + public BlockBreakPriority getBbPriority() { return bbPriority; } @@ -668,7 +681,7 @@ else if ( !ignoreBlockReuse && targetBlock.isCounted() ) { results.setResultsReason( EventResultsReasons.results_passed ); } - results.logDebugInfo(); + //results.logDebugInfo(); return results; } From bfafaddaa574fc8589e4997d7b0055ff7ddf9219 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 9 Sep 2024 19:39:35 -0400 Subject: [PATCH 179/323] v3.3.0-alpha.19b 2024-09-09 --- docs/changelog_v3.3.x.md | 7 ++++++- gradle.properties | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 48c7f6d2e..2f35a931b 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.19 2024-09-09 +# 3.3.0-alpha.19b 2024-09-09 + + + +**v3.3.0-alpha.19b 2024-09-09** + * **Block Break Listeners: If in debug mode, and there is a fast fail, or an ignore on the blocks being broken, log the reasons why.** diff --git a/gradle.properties b/gradle.properties index dd12b8ffa..f9e5af755 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.19 +version=3.3.0-alpha.19b From 9adc575a17ffb9c6ef754af334ea7ef476a0cda7 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 13 Sep 2024 01:25:01 -0400 Subject: [PATCH 180/323] Removed various comments that were auto generated. --- docs/changelog_v3.3.x.md | 5 ++++- .../mcprison/prison/internal/block/MineTargetBlockKey.java | 1 - .../tech/mcprison/prison/internal/block/PrisonBlock.java | 2 -- .../prison/placeholders/PlaceholderAttributeBar.java | 4 +--- .../prison/placeholders/PlaceholderAttributeTime.java | 3 --- .../src/test/java/tech/mcprison/prison/TestPlatform.java | 3 --- .../main/java/tech/mcprison/prison/mines/data/BlockOld.java | 1 + .../main/java/tech/mcprison/prison/mines/data/MineData.java | 2 +- .../main/java/tech/mcprison/prison/mines/data/MineReset.java | 3 ++- .../java/tech/mcprison/prison/spigot/SpigotPlatform.java | 2 -- .../main/java/tech/mcprison/prison/spigot/SpigotPrison.java | 2 +- .../prison/spigot/customblock/HeadsCustomBlocks.java | 4 ---- .../mcprison/prison/spigot/game/SpigotOfflinePlayer.java | 1 - .../java/tech/mcprison/prison/spigot/game/SpigotPlayer.java | 1 + 14 files changed, 11 insertions(+), 23 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 2f35a931b..e00b25660 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,10 +14,13 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.19b 2024-09-09 +# 3.3.0-alpha.19b 2024-09-13 +* **Removed various comments that were auto generated.** + + **v3.3.0-alpha.19b 2024-09-09** diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/block/MineTargetBlockKey.java b/prison-core/src/main/java/tech/mcprison/prison/internal/block/MineTargetBlockKey.java index a1ba58713..e527fbffe 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/block/MineTargetBlockKey.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/block/MineTargetBlockKey.java @@ -102,7 +102,6 @@ public int hashCode() hash += x * 13 + y * 37 + z * 17; - // TODO Auto-generated method stub // return super.hashCode(); return hash; 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 be4af9ed8..58a6cdd3b 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 @@ -504,7 +504,6 @@ public boolean breakNaturally() { @Override public List getDrops() { - // TODO Auto-generated method stub return null; } @@ -515,7 +514,6 @@ public List getDrops() @Override public List getDrops( ItemStack tool ) { - // TODO Auto-generated method stub return null; } 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 b3602f68d..3cc93b0a6 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 @@ -219,10 +219,8 @@ public void setBarConfig( PlaceholderProgressBarConfig barConfig ) { @Override public String format( String value ) { - // TODO Auto-generated method stub - return null; + return value; } - } 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 index b96edc9c4..7afcdfe6c 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderAttributeTime.java +++ b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderAttributeTime.java @@ -1,13 +1,10 @@ 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; 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 85a838815..07a51cdab 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/TestPlatform.java +++ b/prison-core/src/test/java/tech/mcprison/prison/TestPlatform.java @@ -586,19 +586,16 @@ public Map loadYaml(File file) { @Override public String dumpEventListenersBlockPlaceEvents() { - // TODO Auto-generated method stub return null; } @Override public String dumpEventListenersPlayerDropItemEvents() { - // TODO Auto-generated method stub return null; } @Override public String dumpEventListenersPlayerPickupItemEvents() { - // TODO Auto-generated method stub return null; } diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/BlockOld.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/BlockOld.java index 414395046..d82aeaccc 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/BlockOld.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/BlockOld.java @@ -27,6 +27,7 @@ * * @deprecated */ +@SuppressWarnings("deprecation") public class BlockOld extends PrisonBlockStatusData implements Comparable { diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineData.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineData.java index 22e6fb8f2..817177a95 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineData.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineData.java @@ -886,7 +886,7 @@ public boolean isInMineIncludeTopBottomOfMine(Location location) { // Obsolete... the old block model: // public boolean isInMine(BlockType blockType) { -// //TODO Not sure if virtual should return false... they do have blocks. +// //TO DO Not sure if virtual should return false... they do have blocks. //// if ( isVirtual() ) { //// return false; //// } 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 132d984ec..71396056d 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 @@ -630,7 +630,8 @@ public void generateBlockListAsync() { addMineTargetPrisonBlock( prisonBlock, targetLocation ); // mtb = new MineTargetPrisonBlock( prisonBlock, x, y, z); - if ( prisonBlock.equals( PrisonBlock.AIR ) ) { + if ( prisonBlock.isAir() ) { +// if ( prisonBlock.equals( PrisonBlock.AIR ) ) { // mAirBlocks[i++] = true; airCount++; } 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 316f4c044..2349e555e 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 @@ -3138,7 +3138,6 @@ public void reloadAutoFeaturesEventListeners() { @Override public void traceEventListenersBlockBreakEvents( tech.mcprison.prison.internal.CommandSender sender ) { - // TODO Auto-generated method stub Output.get().logInfo( "This feature is not enabled yet." ); } @@ -3612,7 +3611,6 @@ public Map loadYaml( File file ) { // } // // } catch (ClassNotFoundException e) { -// // TODO Auto-generated catch block // e.printStackTrace(); // } 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 2d21896de..be5f5a172 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 @@ -1078,7 +1078,7 @@ private void initModulesAndCommands() { boolean isMinesEnabled = false; boolean isRanksEnabled = false; - // TODO: This business logic needs to be moved to the Module Manager: + // TO DO: This business logic needs to be moved to the Module Manager: if (modulesConf.getBoolean("mines")) { isMinesEnabled = true; diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/customblock/HeadsCustomBlocks.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/customblock/HeadsCustomBlocks.java index 2cec5e494..f1c256c99 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/customblock/HeadsCustomBlocks.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/customblock/HeadsCustomBlocks.java @@ -26,7 +26,6 @@ public HeadsCustomBlocks() { @Override public String getCustomBlockId( Block block ) { - // TODO Auto-generated method stub return null; } @@ -34,7 +33,6 @@ public String getCustomBlockId( Block block ) @Override public PrisonBlock getCustomBlock( Block block ) { - // TODO Auto-generated method stub return null; } @@ -42,7 +40,6 @@ public PrisonBlock getCustomBlock( Block block ) @Override public Block setCustomBlockId( Block block, String customId, boolean doBlockUpdate ) { - // TODO Auto-generated method stub return null; } @@ -50,7 +47,6 @@ public Block setCustomBlockId( Block block, String customId, boolean doBlockUpda @Override public void setCustomBlockIdAsync( PrisonBlock prisonBlock, Location location ) { - // TODO Auto-generated method stub } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java index 6b6d56cbf..560e11097 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java @@ -479,7 +479,6 @@ public void incrementMinecraftStatsDropCount( tech.mcprison.prison.internal.Play @Override public void sendMessage(List messages) { - // TODO Auto-generated method stub } 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 2f93c1ba0..6ad2ec60c 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 @@ -1054,6 +1054,7 @@ public boolean isAutoSellEnabled( StringBuilder debugInfo ) { * @param isPlayerAutosellEnabled * @return */ + @SuppressWarnings("unused") private boolean isAutoSellByPermEnabledAutoFeatures( StringBuilder debugInfo ) { boolean autoSellByPerm = true; From 360d19edf31c416c4b4adb336ef319ea62658eca Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 13 Sep 2024 01:26:06 -0400 Subject: [PATCH 181/323] Auto features: PrisonEnchant's listener: minor changes to only display the registration notice once. --- docs/changelog_v3.3.x.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index e00b25660..4318be870 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.19b 2024-09-13 +* **Auto features: PrisonEnchant's listener: minor changes to only display the registration notice once.** + * **Removed various comments that were auto generated.** From 79a359a3676afaf7b42c5390f73b8373e308fec1 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 13 Sep 2024 04:46:31 -0400 Subject: [PATCH 182/323] Auto features: PrisonEnchant's listener: minor changes to only display the registration notice once. --- .../events/AutoManagerPrisonEnchants.java | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) 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 b7f97eaf9..582a7412a 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 @@ -92,11 +92,20 @@ public class AutoManagerPEExplosiveEventListener extends AutoManagerPrisonEnchants implements Listener { - public AutoManagerPEExplosiveEventListener( BlockBreakPriority bbPriority ) { + public AutoManagerPEExplosiveEventListener( + BlockBreakPriority bbPriority, + PEExplosionEventVersion peApiVersion ) { super( bbPriority ); // Setup the plugin's version: - getPEPluginVersion(); + if ( peApiVersion != PEExplosionEventVersion.undefined ) { + // It's already been calculated, so save it: + setPeApiVersion( peApiVersion ); + } + else { + // It was not properly calculated before, so figure it out and save it: + getPEPluginVersion(); + } } @EventHandler(priority=EventPriority.NORMAL) @@ -347,7 +356,7 @@ private void createListener(BlockBreakPriority bbPriority) { EventPriority ePriority = bbPriority.getBukkitEventPriority(); AutoManagerPEExplosiveEventListener autoManagerListener = - new AutoManagerPEExplosiveEventListener( bbPriority ); + new AutoManagerPEExplosiveEventListener( bbPriority, getPeApiVersion() ); pm.registerEvent(PEExplosionEvent.class, autoManagerListener, ePriority, new EventExecutor() { From 6411014997c8e6693aaea731b09aa2b5eac263c7 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 13 Sep 2024 04:52:01 -0400 Subject: [PATCH 183/323] Custom Placeholders: Created support for custom placeholders that are defined in the config.yml file, and one simple short custom placeholder will be replaced by any combination of text and other placeholders. This way you can define complex placeholders within prison, and then use the short custom placeholders in other config files, which will help a lot if you are limited by characters. --- docs/changelog_v3.3.x.md | 4 + .../placeholders/PlaceholderManager.java | 39 ++++-- .../placeholder/PrisonCustomPlaceholders.java | 118 ++++++++++++++++++ .../placeholder/SpigotPlaceholders.java | 72 ++++++++++- prison-spigot/src/main/resources/config.yml | 9 +- 5 files changed, 228 insertions(+), 14 deletions(-) create mode 100644 prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/PrisonCustomPlaceholders.java diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 4318be870..fff352e04 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.19b 2024-09-13 +* **Custom Placeholders: Created support for custom placeholders that are defined in the config.yml file, and one simple short custom placeholder will be replaced by any combination of text and other placeholders.** +This way you can define complex placeholders within prison, and then use the short custom placeholders in other config files, which will help a lot if you are limited by characters. + + * **Auto features: PrisonEnchant's listener: minor changes to only display the registration notice once.** 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 b3cf4bfe7..96876ae24 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 @@ -12,6 +12,8 @@ public class PlaceholderManager { public static final String PRISON_PLACEHOLDER_PREFIX = "prison"; public static final String PRISON_PLACEHOLDER_PREFIX_EXTENDED = PRISON_PLACEHOLDER_PREFIX + "_"; + public static final String PRISON_PLACEHOLDER_CUSTOM_PREFIX_EXTENDED = PRISON_PLACEHOLDER_PREFIX + "__"; + public static final String PRISON_PLACEHOLDER_MINENAME_SUFFIX = "_minename"; public static final String PRISON_PLACEHOLDER_LADDERNAME_SUFFIX = "_laddername"; public static final String PRISON_PLACEHOLDER_RANKNAME_SUFFIX = "_rankname"; @@ -57,7 +59,11 @@ public enum PlaceholderFlags { PLAYERBLOCKS, STATSMINES( true ), - + // A custom prison placeholder is one that starts with `prison:` and it cannot have any + // placeholder attributes. Basically, it's a substitution of the custom placeholder + // with whatever has been paired to it within the config.yml file. The mappings can + // be as long as needed and contain any other combination of other placeholders. + CUSTOM, SUPRESS, ALIAS, @@ -197,6 +203,10 @@ public enum PrisonPlaceHolders { no_match__(PlaceholderFlags.SUPRESS), + + custom_placeholder__(PlaceholderFlags.CUSTOM), + + // Rank aliases: prison_r(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), prison_rn(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), @@ -699,6 +709,9 @@ public boolean hasAlias() { public boolean isAlias() { return flags.contains( PlaceholderFlags.ALIAS ); } + public boolean isCustomPlaceholder() { + return flags.contains( PlaceholderFlags.CUSTOM ); + } public boolean isSuppressed() { return flags.contains( PlaceholderFlags.SUPRESS ); } @@ -737,16 +750,22 @@ public static PrisonPlaceHolders fromString( String placeHolder ) { if ( placeHolder != null && placeHolder.trim().length() > 0 ) { placeHolder = placeHolder.trim(); - // This allows us to get rid of suppressed placeholders that were used for - // internal matching when placeholder APIs strip off the prefix: - if ( !placeHolder.toLowerCase().startsWith( PRISON_PLACEHOLDER_PREFIX ) ) { - placeHolder = PRISON_PLACEHOLDER_PREFIX + "_" + placeHolder; + if ( placeHolder.startsWith(PRISON_PLACEHOLDER_CUSTOM_PREFIX_EXTENDED) ) { + result = custom_placeholder__; } - - for ( PrisonPlaceHolders ph : values() ) { - if ( ph.name().equalsIgnoreCase( placeHolder ) ) { - result = ph; - break; + else { + + // This allows us to get rid of suppressed placeholders that were used for + // internal matching when placeholder APIs strip off the prefix: + if ( !placeHolder.toLowerCase().startsWith( PRISON_PLACEHOLDER_PREFIX ) ) { + placeHolder = PRISON_PLACEHOLDER_PREFIX + "_" + placeHolder; + } + + for ( PrisonPlaceHolders ph : values() ) { + if ( ph.name().equalsIgnoreCase( placeHolder ) ) { + result = ph; + break; + } } } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/PrisonCustomPlaceholders.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/PrisonCustomPlaceholders.java new file mode 100644 index 000000000..fcc25833c --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/PrisonCustomPlaceholders.java @@ -0,0 +1,118 @@ +package tech.mcprison.prison.spigot.placeholder; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.UUID; + +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.FileConfiguration; + +import tech.mcprison.prison.placeholders.ManagerPlaceholders; +import tech.mcprison.prison.placeholders.PlaceHolderKey; +import tech.mcprison.prison.placeholders.PlaceholderIdentifier; +import tech.mcprison.prison.placeholders.PlaceholderManager.PrisonPlaceHolders; +import tech.mcprison.prison.spigot.SpigotPrison; + +public class PrisonCustomPlaceholders + implements ManagerPlaceholders { + + public static final String CUSTOM_PLACEHOLDER_CONFIG_PATH = "placeholder.custom-placeholders"; + + private List translatedPlaceHolderKeys; + + public PrisonCustomPlaceholders() { + + } + + + public String getTranslateCustomPlaceHolder( PlaceholderIdentifier identifier ) { + String results = null; + + List placeHolderKeys = getTranslatedPlaceHolderKeys(); + + for ( PlaceHolderKey placeHolderKey : placeHolderKeys ) { + + if ( identifier.checkPlaceholderKey(placeHolderKey) ) { + + results = placeHolderKey.getData(); + identifier.setText(results); + + break; + } + + } + + return results; + } + + + + public String getTranslateCustomPlaceHolder( UUID playerUuid, String playerName, String identifier ) { + String results = null; + + if ( playerUuid != null ) { + + List placeHolderKeys = getTranslatedPlaceHolderKeys(); + + + PlaceholderIdentifier phIdentifier = new PlaceholderIdentifier( identifier ); + phIdentifier.setPlayer(playerUuid, playerName); + + + for ( PlaceHolderKey placeHolderKey : placeHolderKeys ) { + + if ( phIdentifier.checkPlaceholderKey(placeHolderKey) ) { + + results = placeHolderKey.getData(); + + break; + } + + } + } + + return results; + } + + + @Override + public List getTranslatedPlaceHolderKeys() { + + if ( translatedPlaceHolderKeys == null ) { + translatedPlaceHolderKeys = new ArrayList<>(); + + FileConfiguration config = SpigotPrison.getInstance().getConfig(); + + if ( config.isConfigurationSection(CUSTOM_PLACEHOLDER_CONFIG_PATH) ) { + + PrisonPlaceHolders customPlaceholder = PrisonPlaceHolders.custom_placeholder__; + + ConfigurationSection cpConfigs = config.getConfigurationSection(CUSTOM_PLACEHOLDER_CONFIG_PATH); + + Set keys = cpConfigs.getKeys( false ); + + for (String key : keys) { + + String customPlaceholderStr = cpConfigs.getString( key ); + + PlaceHolderKey placeholder = new PlaceHolderKey(key, customPlaceholder, customPlaceholderStr ); + translatedPlaceHolderKeys.add(placeholder); + } + } + } + return translatedPlaceHolderKeys; + } + + @Override + public void reloadPlaceholders() { + + // clear the class variable so they will regenerate: + translatedPlaceHolderKeys = null; + + // Regenerate the translated placeholders: + getTranslatedPlaceHolderKeys(); + + } + +} 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 32f16f0c4..ec986614b 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 @@ -31,6 +31,8 @@ public class SpigotPlaceholders implements Placeholders { + private PrisonCustomPlaceholders cph = null; + private MineManager mm = null; private PlayerManager pm = null; private RankManager rm = null; @@ -60,6 +62,9 @@ public SpigotPlaceholders() { */ private void initializePlaceholderManagers() { + this.cph = new PrisonCustomPlaceholders(); + + if ( PrisonMines.getInstance() != null && PrisonMines.getInstance().isEnabled() ) { this.mm = PrisonMines.getInstance().getMineManager(); } @@ -111,6 +116,11 @@ public Map getPlaceholderDetailCounts() { List placeholders = new ArrayList<>(); + if ( cph != null ) { + placeholders.addAll( cph.getTranslatedPlaceHolderKeys() ); + } + + if ( pm != null ) { placeholders.addAll( pm.getTranslatedPlaceHolderKeys() ); } @@ -143,6 +153,12 @@ public Map getPlaceholderDetailCounts() { public int getPlaceholderCount() { int placeholdersRawCount = 0; + if ( cph != null ) { + List placeholderPlayerKeys = cph.getTranslatedPlaceHolderKeys(); + placeholdersRawCount += placeholderPlayerKeys.size(); + + } + if ( pm != null ) { List placeholderPlayerKeys = pm.getTranslatedPlaceHolderKeys(); placeholdersRawCount += placeholderPlayerKeys.size(); @@ -168,6 +184,16 @@ public int getPlaceholderCount() { public int getPlaceholderRegistrationCount() { int placeholdersRegistered = 0; + if ( cph != null ) { + List placeholderPlayerKeys = cph.getTranslatedPlaceHolderKeys(); + + for ( PlaceHolderKey placeHolderKey : placeholderPlayerKeys ) { + if ( !placeHolderKey.getPlaceholder().isSuppressed() ) { + placeholdersRegistered++; + } + } + } + if ( pm != null ) { List placeholderPlayerKeys = pm.getTranslatedPlaceHolderKeys(); @@ -287,6 +313,21 @@ private String processPlaceholderSearchForPlaceholderKey( PlaceholderIdentifier // String results = text; + if ( cph != null ) { + + List placeholderKeys = cph.getTranslatedPlaceHolderKeys(); + + for ( PlaceHolderKey placeHolderKey : placeholderKeys ) { + + if ( identifier.checkPlaceholderKey( placeHolderKey ) ) { + cph.getTranslateCustomPlaceHolder( identifier ); + break; + } + + } + } + + if ( mm != null ) { List placeholderKeys = mm.getTranslatedPlaceHolderKeys(); @@ -344,7 +385,15 @@ private String processPlaceholderHavePlaceholderKey( PlaceholderIdentifier ident if ( placeHolderKey != null && placeHolderKey.getPlaceholder() != null ) { - if ( mm != null && + + if ( cph != null && placeHolderKey.getPlaceholder().isCustomPlaceholder() ) { + if ( identifier.checkPlaceholderKey(placeHolderKey) ) { + + cph.getTranslateCustomPlaceHolder(identifier); + } + } + + else if ( mm != null && (placeHolderKey.getPlaceholder().hasFlag( PlaceholderFlags.MINES ) || placeHolderKey.getPlaceholder().hasFlag( PlaceholderFlags.STATSMINES ) || placeHolderKey.getPlaceholder().hasFlag( PlaceholderFlags.MINEPLAYERS ) || @@ -469,6 +518,7 @@ private String replaceAllPlaceholders(UUID playerUuid, String playerName, String results = results.replace( placeholderText, replacementText ); } + } return results; } @@ -489,10 +539,16 @@ public List placeholderSearch( UUID playerUuid, String playerName, Strin TreeMap placeholderKeys = new TreeMap<>(); + PrisonCustomPlaceholders cph = null; + PlayerManager pm = null; RankManager rm = null; MineManager mm = null; + cph = new PrisonCustomPlaceholders(); + addAllPlaceHolderKeys( placeholderKeys, cph.getTranslatedPlaceHolderKeys() ); + + if ( PrisonRanks.getInstance() != null && PrisonRanks.getInstance().isEnabled() ) { pm = PrisonRanks.getInstance().getPlayerManager(); addAllPlaceHolderKeys( placeholderKeys, pm.getTranslatedPlaceHolderKeys() ); @@ -524,6 +580,12 @@ public List placeholderSearch( UUID playerUuid, String playerName, Strin Player player = identifier.getPlayer(); + if ( placeHolderKey.getPlaceholder().isCustomPlaceholder() ) { + // Need to translate all placeholders within the custom placeholder: + + value = placeholderTranslateText( playerUuid, playerName, value ); + } + if ( player instanceof SpigotPlayer && ignorePlayerInDisabledWorlds( (SpigotPlayer) player )) { value = ""; @@ -631,9 +693,13 @@ public void reloadPlaceholders() { PlaceholderManagerUtils.getInstance().reloadPlaceholderBarConfig(); initializePlaceholderManagers(); + + if ( cph != null ) { + cph.reloadPlaceholders(); + } if ( PrisonRanks.getInstance() != null && PrisonRanks.getInstance().isEnabled() ) { - PlayerManager pm = PrisonRanks.getInstance().getPlayerManager(); +// PlayerManager pm = PrisonRanks.getInstance().getPlayerManager(); if ( pm != null ) { pm.reloadPlaceholders(); } @@ -644,7 +710,7 @@ public void reloadPlaceholders() { } if ( PrisonMines.getInstance() != null && PrisonMines.getInstance().isEnabled() ) { - MineManager mm = PrisonMines.getInstance().getMineManager(); +// MineManager mm = PrisonMines.getInstance().getMineManager(); if ( mm != null ) { mm.reloadPlaceholders(); } diff --git a/prison-spigot/src/main/resources/config.yml b/prison-spigot/src/main/resources/config.yml index 6b6a0c333..c592ab7a7 100644 --- a/prison-spigot/src/main/resources/config.yml +++ b/prison-spigot/src/main/resources/config.yml @@ -270,7 +270,14 @@ placeholder: bar-positive-segment: "|" bar-negative-color: "&4" bar-negative-segment: "=" - + + custom-placeholders: + prison__player_stats: "{prison_rank_tag_default} -> {prison_rankup_rank_tag_default} + {prison_rankup_cost_remaining_bar_default::bar:50:&a:|:&d:|} + {prison_rankup_cost_remaining_formatted_default} needed to rankup" + prison__branding: "&#e81416P&#ffa500r&#faeb36o + Oc314Mǧde7ib369dn𑋡de&#ac7ad1s" + # Default language that is used as the primary language. From a0dd24482ac9bbaa83857ce8f3dbaac75f78d92b Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 13 Sep 2024 04:54:20 -0400 Subject: [PATCH 184/323] Placeholders: Realized that the "uppercase" integration hook for placeholder API is not used. Realized that placeholder registration is done without sensitivity to the case used. --- docs/changelog_v3.3.x.md | 4 ++++ .../spigot/placeholder/PlaceHolderAPIIntegration.java | 8 +++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index fff352e04..e56a580cd 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.19b 2024-09-13 +* **Placeholders: Realized that the "uppercase" integration hook for placeholder API is not used.** +Realized that placeholder registration is done without sensitivity to the case used. + + * **Custom Placeholders: Created support for custom placeholders that are defined in the config.yml file, and one simple short custom placeholder will be replaced by any combination of text and other placeholders.** This way you can define complex placeholders within prison, and then use the short custom placeholders in other config files, which will help a lot if you are limited by characters. diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/PlaceHolderAPIIntegration.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/PlaceHolderAPIIntegration.java index 786643943..e5721e426 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/PlaceHolderAPIIntegration.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/PlaceHolderAPIIntegration.java @@ -11,7 +11,7 @@ public class PlaceHolderAPIIntegration extends PlaceholderIntegration { private PlaceHolderAPIIntegrationWrapper placeHolderWrapper; - private PlaceHolderAPIIntegrationUppercaseWrapper placeHolderUppercaseWrapper; +// private PlaceHolderAPIIntegrationUppercaseWrapper placeHolderUppercaseWrapper; public PlaceHolderAPIIntegration() { super( "PlaceholderAPI", "PlaceholderAPI" ); @@ -25,8 +25,10 @@ public void integrate() { this.placeHolderWrapper = new PlaceHolderAPIIntegrationWrapper(); this.placeHolderWrapper.register(); - this.placeHolderUppercaseWrapper = new PlaceHolderAPIIntegrationUppercaseWrapper(); - this.placeHolderUppercaseWrapper.register(); + // NOTE: the registration of the placeholders and their usage is + // case insensitive, so this is not needed: +// this.placeHolderUppercaseWrapper = new PlaceHolderAPIIntegrationUppercaseWrapper(); +// this.placeHolderUppercaseWrapper.register(); } } catch ( NoClassDefFoundError | IllegalStateException e ) { From 8b750f53206308847e9cd8dd2f4696d80de9b241 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 14 Sep 2024 13:36:45 -0400 Subject: [PATCH 185/323] Mine bombs: Not a significant change. Allowed the mine bomb data to be part of the event that is being passed along so it can be used in later updates and future features. --- docs/changelog_v3.3.x.md | 3 +++ .../api/PrisonMinesBlockBreakEvent.java | 17 +++++++++++++++- ...nagerPrisonsExplosiveBlockBreakEvents.java | 12 ++++++++--- .../spigot/block/OnBlockBreakEventCore.java | 20 +++++++++++++++++++ .../spigot/block/OnBlockBreakMines.java | 13 +++++++++--- 5 files changed, 58 insertions(+), 7 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index e56a580cd..8f4e7772a 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.19b 2024-09-13 +* **Mine bombs: Not a significant change. Allowed the mine bomb data to be part of the event that is being passed along so it can be used in later updates and future features.** + + * **Placeholders: Realized that the "uppercase" integration hook for placeholder API is not used.** Realized that placeholder registration is done without sensitivity to the case used. 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 c1f6d6a40..0106b7371 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 @@ -11,6 +11,7 @@ import org.bukkit.event.block.BlockBreakEvent; import tech.mcprison.prison.Prison; +import tech.mcprison.prison.bombs.MineBombData; import tech.mcprison.prison.internal.block.MineTargetPrisonBlock; import tech.mcprison.prison.internal.block.PrisonBlock.PrisonBlockType; import tech.mcprison.prison.mines.data.Mine; @@ -18,9 +19,9 @@ 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.OnBlockBreakMines.MinesEventResults; import tech.mcprison.prison.spigot.block.SpigotBlock; import tech.mcprison.prison.spigot.block.SpigotItemStack; -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; @@ -88,6 +89,9 @@ public class PrisonMinesBlockBreakEvent private String triggered; + private MineBombData mineBomb; + + // If this is set during the validation process, and the validation fails, then this it will // force the canceling of the original block event. private boolean cancelOriginalEvent = false; @@ -186,6 +190,8 @@ public PrisonMinesBlockBreakEvent( this.blockEventType = blockEventType; this.triggered = triggered; + this.mineBomb = null; + this.explodedBlocks = new ArrayList<>(); this.targetExplodedBlocks = new ArrayList<>(); @@ -229,6 +235,8 @@ public PrisonMinesBlockBreakEvent( Block theBlock, Player player, this.triggered = triggered; + this.mineBomb = null; + this.bukkitDrops = new ArrayList<>(); this.preventedDrops = 0; @@ -541,6 +549,13 @@ public HandlerList getHandlers() { public static HandlerList getHandlerList() { return handlers; } + + public MineBombData getMineBomb() { + return mineBomb; + } + public void setMineBomb( MineBombData mineBomb ) { + this.mineBomb = mineBomb; + } public StringBuilder getDebugInfo() { return debugInfo; 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 15a4b4c1c..8c76fd9ae 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 @@ -15,6 +15,7 @@ import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; import tech.mcprison.prison.autofeatures.AutoFeaturesWrapper; +import tech.mcprison.prison.bombs.MineBombData; import tech.mcprison.prison.mines.features.MineBlockEvent.BlockEventType; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.spigot.SpigotPrison; @@ -236,6 +237,8 @@ protected void handleExplosiveBlockBreakEvent( ExplosiveBlockBreakEvent e, PrisonMinesBlockBreakEvent pmEvent = null; long start = System.nanoTime(); + MineBombData mineBomb = e.getMineBomb(); + // 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 @@ -321,17 +324,20 @@ protected void handleExplosiveBlockBreakEvent( ExplosiveBlockBreakEvent e, // if the pseudo tool breaks, it will clear the player's in-hand // inventory stack, which will be more mine bombs if they had more // than one. - if ( e.getMineBomb() != null ) { + if ( mineBomb != null ) { + + pmEvent.setMineBomb( mineBomb ); + pmEvent.setCalculateDurability( false ); // Set if forced autoSell: - pmEvent.setForceAutoSell( e.getMineBomb().isAutosell() ); + pmEvent.setForceAutoSell( mineBomb.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. + // removed, then it's removed within this function. 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 3c324bb24..9f71f2b5a 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 @@ -153,6 +153,26 @@ public enum ItemLoreEnablers { + /** + *

The purpose of this function is to "quickly" evaluate if this event should be used, + * canceled, or ignored. Ignoring the event will mean that other plugins, and the originator + * of the event, can process EVERYTHING normally. If the event is canceled, then some plugins + * may then ignore the whole event, but some may also process it in some way or another. Prison + * uses canceled events to track block breakage when other plugins are handling the breaks. + *

+ * + * @param event The event we're monitoring and processing + * @param player The player that caused the event by mining or breaking blocks + * @param block The "target" block that was initially broke by the player. Note that sometimes + * this is not the actual block, since the event does not preserve that information. + * @param bbPriority The priority that prison was listening at for this event. + * @param ignoreBlockReuse If set to true, then if the block was already counted, then prison + * will still process the blocks. Otherwise if the block has been already counted, then + * prison will ignore the event, which can have a huge impact if it's an explosion and + * there are many other blocks that "should" be processed, but ignoring the whole event + * would be skipping a lot of block processing. + * @return + */ protected MinesEventResults ignoreMinesBlockBreakEvent( Cancellable event, Player player, Block block, BlockBreakPriority bbPriority, boolean ignoreBlockReuse ) { 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 ae943bd69..92290583f 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 @@ -495,9 +495,16 @@ private List getAllMinesWithinTheRadialDistance( SpigotLocation location, * or if the targetBlock has been set to ignore all block events which * means the block has already been processed. *

- * - * @param player - * @param block + * + * @param player The player that caused the event by mining or breaking blocks + * @param block The "target" block that was initially broke by the player. Note that sometimes + * this is not the actual block, since the event does not preserve that information. + * @param bbPriority The priority that prison was listening at for this event. + * @param ignoreBlockReuse If set to true, then if the block was already counted, then prison + * will still process the blocks. Otherwise if the block has been already counted, then + * prison will ignore the event, which can have a huge impact if it's an explosion and + * there are many other blocks that "should" be processed, but ignoring the whole event + * would be skipping a lot of block processing. * @return */ protected MinesEventResults ignoreMinesBlockBreakEvent( Player player, From ee2e7fdfa7c1da37d7e3dd2009d8a9bf1542a819 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 20 Sep 2024 01:07:07 -0400 Subject: [PATCH 186/323] Bump version to v3.3.0-alpha.19c 2024-09-20 --- docs/changelog_v3.3.x.md | 10 +++++++++- gradle.properties | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 8f4e7772a..115e837f9 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,15 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.19b 2024-09-13 +# 3.3.0-alpha.19c 2024-09-20 + + +** 3.3.0-alpha.19c 2024-09-20 ** + + +* **Build automation: github has deprecated and disabled version 1 and 2 of the actions, and v3 is slated to be disabled in Nov/Dec of this year too.** +So moving on to v4 to allow for better future use. +This prison build script is very simple and therefore the newer issues related to v4 when upgrading from older versions, should not impact prison. Basically the largest change is that these artifacts are now immutable. * **Mine bombs: Not a significant change. Allowed the mine bomb data to be part of the event that is being passed along so it can be used in later updates and future features.** diff --git a/gradle.properties b/gradle.properties index f9e5af755..a056f7c57 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.19b +version=3.3.0-alpha.19c From 58de84a3862bd27a6c22c9566dd8e361302da763 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 20 Sep 2024 02:50:32 -0400 Subject: [PATCH 187/323] Custom Placeholders: A custom placeholder is identified with the prefix of 'prison__' but one of the functions that cleans the placeholder fragments sent to prison, was removing one of those underscore characters. This preserves the needed underscore and allows for proper matching and identification. --- .../tech/mcprison/prison/PrisonCommand.java | 28 +++++++++++++------ .../placeholders/PlaceholderManagerUtils.java | 2 +- prison-spigot/src/main/resources/config.yml | 3 ++ 3 files changed, 23 insertions(+), 10 deletions(-) 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 510b5b28b..bfa943c72 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java +++ b/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java @@ -826,21 +826,31 @@ public void placeholdersStatsCommand(CommandSender sender, display.send(sender); } - @Command(identifier = "prison reload placeholders", - description = "Placeholder reload: Regenerates all placeholders and reregisters them.", - onlyPlayers = false, permissions = "prison.placeholder") - public void placeholdersReloadCommandAlias(CommandSender sender ) { - placeholdersReloadCommand( sender ); - } +// @Command(identifier = "prison reload placeholders", +// description = "Placeholder reload: Regenerates all placeholders and reregisters them.", +// onlyPlayers = false, +// permissions = "prison.placeholder", +// aliases = { "prison reload configyml" }) +// public void placeholdersReloadCommandAlias(CommandSender sender ) { +// placeholdersReloadCommand( sender ); +// } @Command(identifier = "prison placeholders reload", - description = "Placeholder reload: Regenerates all placeholders and reregisters them.", - onlyPlayers = false, permissions = "prison.placeholder") + description = "Placeholder reload: Regenerates all placeholders and reregisters them. " + + "&dThis also forces the config.yml properties to be reloaded too, but be warned, " + + "it will not force anything that uses config.yml to be reloaded and you may " + + "still have to restart the server.", + onlyPlayers = false, + permissions = "prison.placeholder", + aliases = { + "prison reload configyml", + "prison reload placeholders" + } ) public void placeholdersReloadCommand(CommandSender sender ) { Prison.get().getPlatform().getPlaceholders().reloadPlaceholders(); - String message = "Placeholder reload was attempted. " + + String message = "Placeholder and config.yml reload was attempted. " + "No guarentees that it worked 100%. Restart server if any doubts."; sender.sendMessage( message ); 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 6b7ff9aec..e48f2f327 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 @@ -373,7 +373,7 @@ else if ( pIdentifier.getIdentifierRaw().startsWith( "{" ) ) { } } - else { + else if ( !pIdentifier.getIdentifierRaw().startsWith( "_" ) ) { Matcher matcher = PlaceholderManager.PLACEHOLDER_ESCAPE_CHARACTER_LEFT_PATTERN.matcher( pIdentifier.getIdentifierRaw() ); if ( matcher.find() ) { diff --git a/prison-spigot/src/main/resources/config.yml b/prison-spigot/src/main/resources/config.yml index c592ab7a7..0e92d4ebd 100644 --- a/prison-spigot/src/main/resources/config.yml +++ b/prison-spigot/src/main/resources/config.yml @@ -275,6 +275,9 @@ placeholder: prison__player_stats: "{prison_rank_tag_default} -> {prison_rankup_rank_tag_default} {prison_rankup_cost_remaining_bar_default::bar:50:&a:|:&d:|} {prison_rankup_cost_remaining_formatted_default} needed to rankup" + +# Pre-spigot 1.14: Cannot do RGB colors: +# prison__branding: "&2P&3r&4o &5M&6i&an&be&cs" prison__branding: "&#e81416P&#ffa500r&#faeb36o Oc314Mǧde7ib369dn𑋡de&#ac7ad1s" From 1fbaab5ab25664a61a8f7536e0756142aa4e19a8 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 21 Sep 2024 01:25:09 -0400 Subject: [PATCH 188/323] Added a new function to the platform to check to see if there is a specific configuration section. --- docs/changelog_v3.3.x.md | 9 ++++++++- .../mcprison/prison/internal/platform/Platform.java | 10 ++++++++++ .../test/java/tech/mcprison/prison/TestPlatform.java | 6 ++++++ .../tech/mcprison/prison/spigot/SpigotPlatform.java | 11 +++++++++++ 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 115e837f9..39662fd28 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.19c 2024-09-20 +# 3.3.0-alpha.19c 2024-09-21 + + +* **Added a new function to the platform to check to see if there is a specific configuration section.** + + +* **Custom Placeholders: A custom placeholder is identified with the prefix of 'prison__' but one of the functions that cleans the placeholder fragments sent to prison, was removing one of those underscore characters.** +This preserves the needed underscore and allows for proper matching and identification. ** 3.3.0-alpha.19c 2024-09-20 ** 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 a0adfb5f1..d1735735b 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 @@ -320,6 +320,16 @@ public default Optional getCommand(String label) { public List getConfigHashKeys(String hashPrefix); + /** + *

This returns a value of true if the given config path exists. + *

+ * + * @param section + * @return + */ + public boolean isConfigSection( String section ); + + 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 07a51cdab..f54eb54e9 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/TestPlatform.java +++ b/prison-core/src/test/java/tech/mcprison/prison/TestPlatform.java @@ -322,6 +322,11 @@ public List getConfigHashKeys(String hashPrefix) { return new ArrayList(); } + @Override + public boolean isConfigSection(String section) { + return false; + } + @Override public boolean isWorldExcluded( String worldName ) { @@ -602,4 +607,5 @@ public String dumpEventListenersPlayerPickupItemEvents() { public MineBombEffectsData validateMineBombEffect(MineBombEffectsData mineBombEffectsData) { return mineBombEffectsData; } + } 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 2349e555e..b4d3b033e 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 @@ -1140,6 +1140,17 @@ public List getConfigHashKeys( String hashPrefix ) { return keys; } + + @Override + public boolean isConfigSection( String section ) { + boolean results = false; + + results = SpigotPrison.getInstance().getConfig().isConfigurationSection( section ); + + return results; + } + + @Override public boolean isWorldExcluded( String worldName ) { boolean exclude = false; From a7694782f341b16667a87ebf90e6d5d38136be6d Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 21 Sep 2024 01:30:00 -0400 Subject: [PATCH 189/323] Custom Placeholders: Added support for a more complex custom placeholder where the default is an abbreviated placeholder (simple) and a more complex expanded placeholder where you can set various options such as enable PAPI expansions and adding descriptions. Added custom placeholders to be included in the `/prison placeholders list`. To view all custom placeholders, as translated, search for the custom placeholder prefix: `/prison placeholder search prison__` --- docs/changelog_v3.3.x.md | 7 ++ .../prison/placeholders/PlaceHolderKey.java | 17 +++++ .../placeholders/PlaceholderManager.java | 72 ++++++++++++++----- .../PrisonCustomPlaceholders.java | 69 +++++++++++++----- .../placeholder/SpigotPlaceholders.java | 20 ++++++ prison-spigot/src/main/resources/config.yml | 15 ++++ 6 files changed, 166 insertions(+), 34 deletions(-) rename {prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder => prison-core/src/main/java/tech/mcprison/prison/placeholders}/PrisonCustomPlaceholders.java (53%) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 39662fd28..00fe8ff1a 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.19c 2024-09-21 +* **Custom Placeholders: Added support for a more complex custom placeholder where the default is an abbreviated placeholder (simple) and a more complex expanded placeholder where you can set various options such as enable PAPI expansions and adding descriptions.** +Added custom placeholders to be included in the `/prison placeholders list`. +To view all custom placeholders, as translated, search for the custom placeholder prefix: +`/prison placeholder search prison__` + + + * **Added a new function to the platform to check to see if there is a specific configuration section.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceHolderKey.java b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceHolderKey.java index 8215c6e73..d0bdfeb25 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceHolderKey.java +++ b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceHolderKey.java @@ -10,6 +10,9 @@ public class PlaceHolderKey { private boolean primary = true; private String aliasName; + private boolean papiExpansion = false; + private String description = null; + // // NOTE: Pattern is thread safe so make it static. Matcher is not thead safe. // public static Pattern PLACEHOLDER_SEQUENCE_PATTERN = Pattern.compile( "(\\_([0-9]+)\\_)" ); @@ -276,4 +279,18 @@ public String getAliasName() { public void setAliasName( String aliasName ) { this.aliasName = aliasName; } + + public boolean isPapiExpansion() { + return papiExpansion; + } + public void setPapiExpansion(boolean papiExpansion) { + this.papiExpansion = papiExpansion; + } + + public String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } } 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 96876ae24..f9e713dcd 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 @@ -59,7 +59,7 @@ public enum PlaceholderFlags { PLAYERBLOCKS, STATSMINES( true ), - // A custom prison placeholder is one that starts with `prison:` and it cannot have any + // A custom prison placeholder is one that starts with `prison__` and it cannot have any // placeholder attributes. Basically, it's a substitution of the custom placeholder // with whatever has been paired to it within the config.yml file. The mappings can // be as long as needed and contain any other combination of other placeholders. @@ -204,7 +204,7 @@ public enum PrisonPlaceHolders { no_match__(PlaceholderFlags.SUPRESS), - custom_placeholder__(PlaceholderFlags.CUSTOM), + custom_placeholder__(PlaceholderFlags.CUSTOM, PlaceholderFlags.SUPRESS), // Rank aliases: @@ -827,6 +827,7 @@ public static List getAllChatList( boolean omitSuppressable) { int totalCount = 0; + int totalAliases = 0; for ( PlaceholderFlags type : PlaceholderFlags.values() ) { if ( type == PlaceholderFlags.ALIAS || type == PlaceholderFlags.SUPRESS ) { @@ -885,30 +886,65 @@ else if ( type == PlaceholderFlags.STATSRANKS ) { int count = 0; + int aliases = 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() )) { + if ( ph.getFlags().contains( type ) ) { - if ( !hasDeprecated && ph.isSuppressed() ) { - hasDeprecated = true; + if ( !isRanksEnabled && ( + type == PlaceholderFlags.PLAYER && ph.name().toLowerCase().contains("rank") )) { + + // do nothing since ranks is not enabled: } - results.add( " " + ph.getChatText() ); - - count++; - totalCount++; + else if ( + !omitSuppressable || + omitSuppressable && !ph.isSuppressed() && !ph.isAlias() ) { + + if ( !hasDeprecated && ph.isSuppressed() ) { + hasDeprecated = true; + } + + results.add( " " + ph.getChatText() ); + + count++; + totalCount++; + if ( ph.isAlias() ) { + aliases++; + totalAliases++; + } + + } + else if ( ph == custom_placeholder__ ) { + // Get the list of custom placeholders: + PrisonCustomPlaceholders cp = new PrisonCustomPlaceholders(); + List phKeys = cp.getTranslatedPlaceHolderKeys(); + + for (PlaceHolderKey phKey : phKeys) { + + results.add( " &a" + phKey.getKey() + + (phKey.isPapiExpansion() ? " &d(papi_expansion)" : "") ); + + if ( phKey.getData() != null ) { + results.add( " \\Q" + phKey.getData() + "\\E" ); + } + + if ( phKey.getDescription() != null && phKey.getDescription().trim().length() > 0 ) { + results.add( " &b" + phKey.getDescription() ); + } + + + count++; + totalCount++; + } + } } + + } results.set( pos, results.get( pos ) + - " (" + (count * 2) + ", " + count + " aliases):"); + " (" + (count + aliases) + ", " + aliases + " aliases):"); } @@ -917,7 +953,7 @@ else if ( type == PlaceholderFlags.STATSRANKS ) { } results.add( 0, "&7Available PlaceHolders" + - " (" + (totalCount * 2) + ", " + totalCount + " aliases):"); + " (" + (totalCount + totalAliases) + ", " + totalAliases + " aliases):"); return results; } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/PrisonCustomPlaceholders.java b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PrisonCustomPlaceholders.java similarity index 53% rename from prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/PrisonCustomPlaceholders.java rename to prison-core/src/main/java/tech/mcprison/prison/placeholders/PrisonCustomPlaceholders.java index fcc25833c..b4216dca1 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/PrisonCustomPlaceholders.java +++ b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PrisonCustomPlaceholders.java @@ -1,18 +1,12 @@ -package tech.mcprison.prison.spigot.placeholder; +package tech.mcprison.prison.placeholders; import java.util.ArrayList; import java.util.List; -import java.util.Set; import java.util.UUID; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.file.FileConfiguration; - -import tech.mcprison.prison.placeholders.ManagerPlaceholders; -import tech.mcprison.prison.placeholders.PlaceHolderKey; -import tech.mcprison.prison.placeholders.PlaceholderIdentifier; +import tech.mcprison.prison.Prison; +import tech.mcprison.prison.internal.platform.Platform; import tech.mcprison.prison.placeholders.PlaceholderManager.PrisonPlaceHolders; -import tech.mcprison.prison.spigot.SpigotPrison; public class PrisonCustomPlaceholders implements ManagerPlaceholders { @@ -75,28 +69,71 @@ public String getTranslateCustomPlaceHolder( UUID playerUuid, String playerName, return results; } - + /** + *

This checks for custom placeholders and gets their values. + * A custom placeholder can be abbreviated, or expanded. + *

+ * + *

An abbreviated placeholder only has the text with no other settings: + *

+ *
+     *   
+  custom-placeholders:
+    prison__chat_prefix: "{prison_rank_tag_default}{prison_rank_tag_prestiges}"
+     * 
+ * + *

An extended placeholder has more details and settings: + *

+ *
+  custom-placeholders:
+    prison__chat_prefix: 
+      placeholder: "{prison_rank_tag_default}{prison_rank_tag_prestiges}"
+      papi_expansion: false
+      
+ */ @Override public List getTranslatedPlaceHolderKeys() { if ( translatedPlaceHolderKeys == null ) { translatedPlaceHolderKeys = new ArrayList<>(); - FileConfiguration config = SpigotPrison.getInstance().getConfig(); - - if ( config.isConfigurationSection(CUSTOM_PLACEHOLDER_CONFIG_PATH) ) { +// FileConfiguration config = SpigotPrison.getInstance().getConfig(); + + Platform pf = Prison.get().getPlatform(); + + if ( pf.isConfigSection(CUSTOM_PLACEHOLDER_CONFIG_PATH) ) { + + PrisonPlaceHolders customPlaceholder = PrisonPlaceHolders.custom_placeholder__; - ConfigurationSection cpConfigs = config.getConfigurationSection(CUSTOM_PLACEHOLDER_CONFIG_PATH); - Set keys = cpConfigs.getKeys( false ); + List keys = pf.getConfigHashKeys(CUSTOM_PLACEHOLDER_CONFIG_PATH); + +// ConfigurationSection cpConfigs = config.getConfigurationSection(CUSTOM_PLACEHOLDER_CONFIG_PATH); +// +// Set keys = cpConfigs.getKeys( false ); for (String key : keys) { - String customPlaceholderStr = cpConfigs.getString( key ); + String keyPath = CUSTOM_PLACEHOLDER_CONFIG_PATH + "." + key; + + String custExpandedPlaceholderKey = keyPath + ".placeholder"; + String custExpandedPapiExpansionKey = keyPath + ".papi_expansion"; + String custExpandedDescriptionKey = keyPath + ".description"; + + String cePlaceholder = pf.getConfigString( custExpandedPlaceholderKey ); + boolean cePapiExpansion = pf.getConfigBooleanFalse( custExpandedPapiExpansionKey ); + String ceDescription = pf.getConfigString( custExpandedDescriptionKey ); + + String customPlaceholderStr = + cePlaceholder != null ? + cePlaceholder : pf.getConfigString( keyPath ); PlaceHolderKey placeholder = new PlaceHolderKey(key, customPlaceholder, customPlaceholderStr ); + placeholder.setPapiExpansion( cePapiExpansion ); + placeholder.setDescription( ceDescription ); + translatedPlaceHolderKeys.add(placeholder); } } 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 ec986614b..0eb1ada54 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 @@ -9,6 +9,9 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.bukkit.Bukkit; + +import me.clip.placeholderapi.PlaceholderAPI; import tech.mcprison.prison.Prison; import tech.mcprison.prison.internal.Player; import tech.mcprison.prison.mines.PrisonMines; @@ -22,6 +25,7 @@ import tech.mcprison.prison.placeholders.PlaceholderStatsData; import tech.mcprison.prison.placeholders.Placeholders; import tech.mcprison.prison.placeholders.PlaceholdersStats; +import tech.mcprison.prison.placeholders.PrisonCustomPlaceholders; import tech.mcprison.prison.ranks.PrisonRanks; import tech.mcprison.prison.ranks.managers.PlayerManager; import tech.mcprison.prison.ranks.managers.RankManager; @@ -48,6 +52,10 @@ public class SpigotPlaceholders // private static final Pattern PLACEHOLDER_PATTERN = Pattern.compile("[%]([^%]+)[%]"); // private static final Pattern BRACKET_PLACEHOLDER_PATTERN = Pattern.compile("[{]([^{}]+)[}]"); + private final boolean placeholderAPINotNull = + Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null || + Bukkit.getPluginManager().getPlugin("PlaceholdersAPI") != null; + public SpigotPlaceholders() { super(); @@ -580,10 +588,22 @@ public List placeholderSearch( UUID playerUuid, String playerName, Strin Player player = identifier.getPlayer(); + + // Process custom placeholders... after expanding all prison placeholders, then + // call PAPI so it can expand non-prison placeholders: if ( placeHolderKey.getPlaceholder().isCustomPlaceholder() ) { // Need to translate all placeholders within the custom placeholder: value = placeholderTranslateText( playerUuid, playerName, value ); + + if ( value != null && value.trim().length() > 0 && + placeHolderKey.isPapiExpansion() && + placeholderAPINotNull ) { + + value = PlaceholderAPI.setPlaceholders( + Bukkit.getOfflinePlayer( playerUuid), value ); + + } } if ( player instanceof SpigotPlayer && diff --git a/prison-spigot/src/main/resources/config.yml b/prison-spigot/src/main/resources/config.yml index 0e92d4ebd..61a72fbfc 100644 --- a/prison-spigot/src/main/resources/config.yml +++ b/prison-spigot/src/main/resources/config.yml @@ -271,7 +271,22 @@ placeholder: bar-negative-color: "&4" bar-negative-segment: "=" + # Custom Placeholders: + # They MUST begin with 'prison__', which has two underscores, or they will not work. + # Custom placeholders can have an abbreviated format where it is the placeholder + # with the quoted value, which can be multi-lined. + # The extended format can have additonal settings. The actual placeholder is + # paired with 'placeholder'. + # If the custom placeholder contains non-prison placeholders, then you can set + # the 'papi_expansion' to true. + # If a description is provided, it will be shown within the placeholder listing. + # Note that the use of hex colors will not work with bukkit versions prior to + # spigot 1.14. custom-placeholders: + prison__chat_prefix: + placeholder: "{prison_rank_tag_default}{prison_rank_tag_prestiges}" + papi_expansion: false + description: "Can use this in your chat prefix. May have to use %% instead of {}." prison__player_stats: "{prison_rank_tag_default} -> {prison_rankup_rank_tag_default} {prison_rankup_cost_remaining_bar_default::bar:50:&a:|:&d:|} {prison_rankup_cost_remaining_formatted_default} needed to rankup" From f542dd565e5219946f22a21d416d6b45e3331a41 Mon Sep 17 00:00:00 2001 From: SnowCutieOwO <89032291+SnowCutieOwO@users.noreply.github.com> Date: Sat, 21 Sep 2024 19:58:15 +0800 Subject: [PATCH 190/323] Fixed code and renamed file for format Moved changes from main branch to develop branch as the developer said. :) * Renamed `zh-CN` -> `zh_CN` * Fixed encode problem --- .../{zh-CN.properties => zh_CN.properties} | 161 +++++++++--------- 1 file changed, 79 insertions(+), 82 deletions(-) rename prison-core/src/main/resources/lang/core/{zh-CN.properties => zh_CN.properties} (60%) diff --git a/prison-core/src/main/resources/lang/core/zh-CN.properties b/prison-core/src/main/resources/lang/core/zh_CN.properties similarity index 60% rename from prison-core/src/main/resources/lang/core/zh-CN.properties rename to prison-core/src/main/resources/lang/core/zh_CN.properties index 6a036fd92..3a55dba0a 100644 --- a/prison-core/src/main/resources/lang/core/zh-CN.properties +++ b/prison-core/src/main/resources/lang/core/zh_CN.properties @@ -76,7 +76,7 @@ # like to share, please contact a staff member on our Discord server. #Thanks for your contributions! # -messages__version=9 +messages__version=11 messages__auto_refresh=true @@ -85,124 +85,124 @@ core_output__prefix_template_prison=监狱 core_output__prefix_template_info=ä¿¡æ¯ core_output__prefix_template_warning=警告 core_output__prefix_template_error=错误 -core_output__prefix_template_debug=Debug +core_output__prefix_template_debug=调试 core_output__color_code_info=&3 core_output__color_code_warning=&c core_output__color_code_error=&c 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 +core_output__error_startup_failure=监狱: (使用 System.err å‘é€, å›  Output.log 记录出现问题): +core_output__error_incorrect_number_of_parameters=日志记录失败 (%1): 字段数é‡ä¸æ­£ç¡®: [%2] 原信æ¯: [%3] 傿•°: %4 core_text__prefix=&3 core_text__just_now=现在 -core_text__ago=ä»¥å‰ -core_text__from_now=åŽ -core_text__and=å -core_text__time_units_prefix_spacer= ’Œ -core_text__time_units_singular=å¹´ã€æœˆã€å‘¨ã€æ—¥ã€æ—¶ã€åˆ†ã€ç§’ -core_text__time_units_plural=å¹´ã€æœˆã€å‘¨ã€æ—¥ã€æ—¶ã€åˆ†ã€ç§’ -core_text__time_units_short=å¹´ã€æœˆã€å‘¨ã€æ—¥ã€æ—¶ã€åˆ†ã€ç§’ +core_text__ago=å‰ +core_text__from_now=现在 +core_text__and=与 +core_text__time_units_prefix_spacer= +core_text__time_units_singular=å¹´,月,周,æ—¥,æ—¶,分,ç§’ +core_text__time_units_plural=å¹´,月,周,æ—¥,æ—¶,分,ç§’ +core_text__time_units_short=y,m,w,d,h,m,s -core_tokens__name_required=Prison Tokens=A player's name is required when used from console. -core_tokens__cannot_view_others_balances=Prison Tokens: You do not have permission to view other player's balances. -core_tokens__view_balance=&3%1 has %2 tokens. -core_tokens__add_invalid_amount=Prison Tokens: Invalid amount: '%1'. Must be greater than zero. -core_tokens__added_amount=&3%1 now has &7%2 &3tokens after adding &7%3&3. -core_tokens__removed_amount=&3%1 now has &7%2 &3tokens after removing &7%3&3. -core_tokens__set_amount=&3%1 now has &7%2 &3tokens. +core_tokens__name_required=Prison Tokens=åœ¨æŽ§åˆ¶å°æ‰§è¡Œè¯¥å‘½ä»¤æ—¶å¿…须输入玩家åç§°. +core_tokens__cannot_view_others_balances=监狱代å¸: 你没有æƒé™æŸ¥çœ‹å…¶ä»–玩家的余é¢. +core_tokens__view_balance=&3%1 拥有 %2 枚代å¸. +core_tokens__add_invalid_amount=监狱代å¸: æ•°é‡æ— æ•ˆ: '%1'. 需大于零. +core_tokens__added_amount=&3%1 获得了 &7%3&3 枚代å¸, 现在拥有 &7%2 &3枚代å¸. +core_tokens__removed_amount=&3%1 失去了 &7%3&3 枚代å¸, 现在拥有 &7%2 &3枚代å¸. +core_tokens__set_amount=&3%1 现在拥有 &7%2 &3枚代å¸. -core_runCmd__name_required=A valid player name is required. -core_runCmd__command_required=A command is required. +core_runCmd__name_required=请输入有效玩家åç§°. +core_runCmd__command_required=请输入有效命令. -core_prison_utf8_test=\u041F\u0440\u0438\u0432\u0435\u0442! \u0414\u0430\u0432\u0430\u0439 \u043F\u043E\u0441\u043C\u043E\u0442\u0440\u0438\u043C, \u0440\u0430\u0431\u043E\u0442\u0430\u0435\u0442 \u043B\u0438? Test 01 +core_prison_utf8_test=正在测试 UTF-8 ç¼–ç å…¼å®¹æ€§... 测试 01 # The following are the original messages and they will eventually be replaced. -includeError=[%1] 具有无效值 -excludeError=[%1] 具有无效值 -cantAsConsole=您ä¸èƒ½åœ¨æŽ§åˆ¶å°æ‰§è¡Œæ­¤æ“作 -missingArgument=æœªå®šä¹‰å‚æ•°[%1](它没有默认值) -missingFlagArgument=标志-%1æ²¡æœ‰æ‰€éœ€çš„å‚æ•° -undefinedFlagArgument=未定义标志-%2çš„å‚æ•°[%1] -internalErrorOccurred=å°è¯•执行此命令时å‘生内部错误 -noPermission=你缺少执行该命令的æƒé™ -blockParseError=傿•°[%1]䏿˜¯æœ‰æ•ˆçš„æ–¹å— -numberParseError=傿•°[%1]䏿˜¯æ•°å­— -numberTooLow=傿•°[%1]必须等于或大于%2 -numberTooHigh=傿•°[%1]必须等于或å°äºŽ%2 -numberRangeError=傿•°[%1]必须等于或大于%2且å°äºŽæˆ–等于%3 -tooFewCharacters=傿•°[%1]必须等于或大于%2 -tooManyCharacters=傿•°[%1]必须等于或å°äºŽ%2 -playerNotOnline=玩家%1ä¸åœ¨çº¿ -worldNotFound=找ä¸åˆ°ä¸–界%1 +includeError=[%1] 为无效值. +excludeError=[%1] 为无效值. +cantAsConsole=控制å°ä¸­ä¸èƒ½è¿™ä¹ˆåš. +missingArgument=傿•° [%1] 未定义 (无默认值). +missingFlagArgument=标志 -%1 缺少指定字段. +undefinedFlagArgument=标志 -%2 ç¼ºå°‘å‚æ•° [%1]. +internalErrorOccurred=执行命令时出现内部错误. +noPermission=你没有æƒé™æ‰§è¡Œè¿™ä¸ªå‘½ä»¤. +blockParseError=æ‰€ç»™å‚æ•° [%1] 䏿˜¯æœ‰æ•ˆæ–¹å—. +numberParseError=æ‰€ç»™å‚æ•° [%1] 䏿˜¯æœ‰æ•ˆæ•°å­—. +numberTooLow=æ‰€ç»™å‚æ•° [%1] å¿…é¡»ä¸å°äºŽ %2. +numberTooHigh=æ‰€ç»™å‚æ•° [%1] å¿…é¡»ä¸å¤§äºŽ %2. +numberRangeError=æ‰€ç»™å‚æ•° [%1] å¿…é¡»ä¸å°äºŽ %2 且ä¸å¤§äºŽ %3. +tooFewCharacters=æ‰€ç»™å‚æ•° [%1] å¿…é¡»ä¸å°äºŽ %2 个字符. +tooManyCharacters=æ‰€ç»™å‚æ•° [%1] å¿…é¡»ä¸å¤§äºŽ %2 个字符. +playerNotOnline=玩家 %1 ä¸åœ¨çº¿. +worldNotFound=世界 %1 ä¸å­˜åœ¨. -core_gui__click_to_decrease=&3点击å‡å°‘ -core_gui__click_to_increase=&3点击增加 +core_gui__click_to_decrease=&3点击å‡å°‘. +core_gui__click_to_increase=&3点击增加. -core_gui__click_to_cancel=&3å•击以喿¶ˆã€‚ -core_gui__click_to_close=&3å•击以关闭 -core_gui__click_to_confirm=&3点击确认 -core_gui__click_to_delete=&3å•击以删除 -core_gui__click_to_disable=&3å•击以ç¦ç”¨ -core_gui__click_to_edit=&3点击编辑 -core_gui__click_to_enable=&3å•击以å¯ç”¨ -core_gui__click_to_open=&3å•击打开 +core_gui__click_to_cancel=&3ç‚¹å‡»å–æ¶ˆ. +core_gui__click_to_close=&3点击关闭. +core_gui__click_to_confirm=&3点击确认. +core_gui__click_to_delete=&3点击删除. +core_gui__click_to_disable=&3点击ç¦ç”¨. +core_gui__click_to_edit=&3点击编辑. +core_gui__click_to_enable=&3点击å¯ç”¨. +core_gui__click_to_open=&3点击打开. -core_gui__left_click_to_confirm=&3左键å•击确认 -core_gui__left_click_to_reset=&3左键å•击以é‡ç½® -core_gui__left_click_to_open=&3左键å•击打开 -core_gui__left_click_to_edit=&3左键å•击进行编辑 +core_gui__left_click_to_confirm=&3左键点击确认. +core_gui__left_click_to_reset=&3左键点击é‡ç½®. +core_gui__left_click_to_open=&3左键点击打开. +core_gui__left_click_to_edit=&3左键点击编辑. -core_gui__right_click_to_cancel=&3å³é”®å•击以喿¶ˆ -core_gui__right_click_to_delete=&3å³é”®å•击以删除 -core_gui__right_click_to_disable=&3å³é”®å•击以ç¦ç”¨ -core_gui__right_click_to_enable=&3å³é”®å•击以å¯ç”¨ -core_gui__right_click_to_toggle=&3å³é”®å•å‡»ä»¥åˆ‡æ¢ +core_gui__right_click_to_cancel=&3å³é”®ç‚¹å‡»å–消. +core_gui__right_click_to_delete=&3å³é”®ç‚¹å‡»åˆ é™¤. +core_gui__right_click_to_disable=&3å³é”®ç‚¹å‡»ç¦ç”¨. +core_gui__right_click_to_enable=&3å³é”®ç‚¹å‡»å¯ç”¨. +core_gui__right_click_to_toggle=&3å³é”®ç‚¹å‡»åˆ‡æ¢. -core_gui__right_click_and_shift_to_delete=&3å³é”®å•击并按ä½shift键以删除 -core_gui__right_click_and_shift_to_disable=&3å³é”®å•击并按ä½shift键以ç¦ç”¨ -core_gui__right_click_and_shift_to_toggle=&3å³é”®å•击并按ä½shifté”®åˆ‡æ¢ +core_gui__right_click_and_shift_to_delete=&3Shift+å³é”®ç‚¹å‡»åˆ é™¤. +core_gui__right_click_and_shift_to_disable=&3Shift+å³é”®ç‚¹å‡»ç¦ç”¨. +core_gui__right_click_and_shift_to_toggle=&3Shift+å³é”®ç‚¹å‡»åˆ‡æ¢. -core_gui__page_next=&3下一页 -core_gui__page_prior=&3上一页 +core_gui__page_next=&3下一页. +core_gui__page_prior=&3上一页. # Note: The core_gui__page_tools_ messages all use the following placeholders # so you can structure them any way you need to. You not no have to use # any of them, but you can also use all of them. # {first_page} {prior_page} {current_page} {next_page} {last_page} -core_gui__page_tools_close=&3Close -core_gui__page_tools_go_back=&3Go Back -core_gui__page_tools_first_page=&3Prior page: {first_page} of {last_page} -core_gui__page_tools_prior_page=&3Prior page: {prior_page} of {last_page} -core_gui__page_tools_current_page=&3Current page: {current_page} of {last_page} -core_gui__page_tools_next_page=&3Next page: {next_page} of {last_page} -core_gui__page_tools_last_page=&3Last page: {last_page} of {last_page} +core_gui__page_tools_close=&3关闭 +core_gui__page_tools_go_back=&3返回 +core_gui__page_tools_first_page=&3已是首页: 第 {first_page} 页, å…± {last_page} 页 +core_gui__page_tools_prior_page=&3上一页: 第 {prior_page} 页, å…± {last_page} 页 +core_gui__page_tools_current_page=&3当å‰é¡µ: 第 {current_page} 页, å…± {last_page} 页 +core_gui__page_tools_next_page=&3下一页: 第 {next_page} 页, å…± {last_page} 页 +core_gui__page_tools_last_page=&3已是末页: 第 {last_page} 页, å…± {last_page} 页 -core_gui__money_earned=&3You earned &a$%1 -core_gui__price=&3价格:%1 -core_gui__confirm=&3确认:%1%2 -core_gui__delay=&3延迟:%1ç§’ -core_gui__multiplier=&3倿•°ï¼šx%1 -core_gui__value=&3值:%1 -core_gui__permission=&3æƒé™ï¼š&7%1 -core_gui__prestige_name=&3声望å称:%1 +core_gui__money_earned=&3你获得了 &a$%1 +core_gui__price=&3ä»·æ ¼: %1 +core_gui__confirm=&3确认: %1 %2 +core_gui__delay=&3延迟: %1 ç§’ +core_gui__multiplier=&3å€çއ: x %1 +core_gui__value=&3值: %1 +core_gui__permission=&3æƒé™: &7%1 +core_gui__prestige_name=&3特æƒå: %1 @@ -215,9 +215,9 @@ core_gui__prestige_name=&3声望å称:%1 # Important: Every [] must be paired with a value or it will produce a runtime error: # 'Incorrect number of parameters: [Format specifier %s] core_ranks_topn__player_line_1_header_format=[4] [-18] [-10] [11] [-8] [-12] -core_ranks_topn__player_line_1_header_values=Rank, Player, PreDefRanks, Balance, r-Score, Penalty +core_ranks_topn__player_line_1_header_values=等级, 玩家, 等级, ä½™é¢, 分数, 惩罚 core_ranks_topn__player_line_2_header_format=[4] [-10] [7] [-18] [9] -core_ranks_topn__player_line_2_header_values=Rank, Ranks, r-Score, Player, Balance +core_ranks_topn__player_line_2_header_values=等级, 等级, 分数, 玩家, ä½™é¢ # For detail_values you can use any of the following placeholders, but they must pair up # with the detail_format's []. @@ -230,6 +230,3 @@ core_ranks_topn__player_line_1_detail_format= [-4] [-18] [-12] [10] [7] [10] core_ranks_topn__player_line_1_detail_values={rankPosition}, {playerName}, {prestigeDefaultRankTagNoColor}, {balanceKmbt}, {rankScore}, {rankScorePenalty} core_ranks_topn__player_line_2_detail_format= [-3] [-10] [7] [-18] [9] core_ranks_topn__player_line_2_detail_values={rankPosition}, {prestigeDefaultRankTagNoColor}, {rankScore}, {playerName}, {balanceKmbt} - - - From a59ced4b37ad8d8c38695bc10a3e5df56c665351 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 21 Sep 2024 14:49:12 -0400 Subject: [PATCH 191/323] Doc updates: WorldGuard support --- ...docs_626_configuring_worldguard_regions.md | 175 +++++++++++++++++- 1 file changed, 168 insertions(+), 7 deletions(-) diff --git a/docs/prison_docs_626_configuring_worldguard_regions.md b/docs/prison_docs_626_configuring_worldguard_regions.md index 5eb5c9347..4afa7b8ea 100644 --- a/docs/prison_docs_626_configuring_worldguard_regions.md +++ b/docs/prison_docs_626_configuring_worldguard_regions.md @@ -10,9 +10,170 @@ This document explains how to setup WorldGuard to protect your mines and how to The preferred way is with using **Access by Ranks**, but other alternative techniques are also included in this document, but some may not be supported (read carefully). It also explains how to setup the permissions in the Prison's **/ranks command add +# WorldGuard Regions, WorldEdit, Permission PLugins, and Prison + +Initially, Prison did not have any direct support for WorldGuard, but it used WorldGuard regions to control access to the mines. Getting WorldGuard properly configured was the admin's responsibility, but yet we would spend a huge number of hours trying to help many people new to WorldGuard try to figure out how to get everything working properly. This also included having to have a working understanding of a few WorldEdit selection commands, and a moderate understanding of how permissions worked, including a good understanding of your perms plugin. All of these plugins, and their related commands, had to be crafted in Prison rankup commands to provide a controlled adjustments when a player is ranking up. All of this was complex with way too many moving parts. Of course, with many new people exploring setting up their first minecraft server, there was a large learning curve, and we helped many people figure it out. + +Helping with WorldGuard, or a perms plugin, was not ideal, because that prevented us from working on prison to allow it to grow and become a more enhanced plugin. So we had to find a way to move on from a harsh dependency upon WorldGuard. + +Enter Prison's **Access by Ranks**. This shift the focus from WorldGuard to allowing Prison to self-manage access to the mines through a player's ranks. On the surface, this simplified a lot of things because Prison no longer had to depend upon WorldGuard regions. This holds true for today even, but it's not that simple when you start to try to add enchantment plugins, because they still rely on WorldGuard regions. + +This document was initially created when WorldGuard Regions were the only way to control access. As things evolved, this document really only provided "hints" to working with WorldGuard for the sake of other plugins. Prison still needs to provide hooks to help with ranking up, but with LuckPerm tracks, the complexity within prison has greatly been reduced. + +There is a dedicated document related to [LuckPerms Groups & Tracks](prison_docs_030_LuckPerms_Groups_Tracks.md) (*[prison_docs_030_LuckPerms_Groups_Tracks.md](prison_docs_030_LuckPerms_Groups_Tracks.md)*), and how to set them up to work with prison. Please review that document if needed. + + +# Prison's New Support for WorldGuard Regions + +This support is a new work in progress. Some features may not fully work, or may not be well documented. These features were initially introduced with version *3.3.0-alpha.19c*. + +WorldGuard region support, within Prison, is through the mines commands, since they are physically associated with mines and their physical locations in the worlds. + +Prison does not understand WorldGuard Regions and there is no way to teach it either. This is true because everyone may want to use regions in a different way, with different setup of perms, groups, and flags. So Prison cannot force our limited experience upon everyone else. Trust me on this, we know Prison, but may not know anything about the other plugins that you are trying to use. + +To provide you with the ultimate control for Prison's use of WorldGuard regions, we will allow the best expert to control everything. Who is that expert? It's you! Yes... You. + +This way, if prison is not configured properly with it's use of WorldGuard regions, you can customize any way you want, and Prison will obey. If you're new to WorldGuard regions, then we have you covered because we provide a simplified way we would use WorldGuard to interact with just Prison. As you learn more, or encounter more complex needs, then you can customize everything to suite your needs. + +But the important thing to realize, is that you're in control, and you can customize anything you want. + + +How is this possible? + +It's easy... In the file `plugins/Prison/config.yml` are various WorldEdit and WorldGuard scripts setup under different commands. So when a prison command is ran, prison takes those scripts and replaces the provided placeholders and then displays the commands in the console. You can do whatever you want with them at that point, such as **view**ing them or copying a pasting them in to your game's console so they can be applied. + +Prison also has the feature where you can **run** them through a player that is online. The way that works, is that the player must be in game, and then prison will teleport them to the mine to ensure they are in the correct world. Then prison will run the specified commands as that player. Therefore, the commands use the implied world and Prison injects all of the mine specific settings. + +This makes it simple. But yet there is still a lot of lack of automation because this requires a player to be online in the game. Why does the player have to be in the game? WorldEdit. Because WorldEdit does not provide a way to specify a target world on some of their commands, such as `//pos1` and `//pos2`, which is the primary way to set a regions area through the use of x,y,z coordinates. Sucks doesn't it? If this was not a limitation, then it would be trivial to script everything. + +# Running the Prison Mines WorldGuard Region commands + +These new commands are located under this command, which will list all available commands: +`/mines worldGuard region` + +``` +>mines worldguard region +[INFO]: ----- < Cmd: /mines worldguard region > ------- (3.3.0-alpha.19c) +[INFO]: /mines worldguard region +[INFO]: Subcommands: +[INFO]: /mines worldguard region globalDefine [playerName] [options] +[INFO]: /mines worldguard region globalInfo [playerName] [options] +[INFO]: /mines worldguard region globalMobSpawningDeny [playerName] [options] +[INFO]: /mines worldguard region mineAreaDefine [mineName] [playerName] [options] +[INFO]: /mines worldguard region mineAreaInfo [mineName] [playerName] [options] +[INFO]: /mines worldguard region mineAreaRedefine [mineName] [playerName] [options] +[INFO]: /mines worldguard region mineAreaSelect [mineName] [playerName] [options] +[INFO]: /mines worldguard region mineDefine [mineName] [playerName] [options] +[INFO]: /mines worldguard region mineInfo [mineName] [playerName] [options] +[INFO]: /mines worldguard region mineRedefine [mineName] [playerName] [options] +[INFO]: /mines worldguard region mineSelect [mineName] [playerName] [options] +``` + + +# Prison's config.yml settings + +In the file `plugins/Prison/config.yml`, under the settings of `prison-mines.world-guard` are the configs. They are numerous. They will be listed at the end of this section. But first let me explain a few things. + +All of the scripts are grouped under a command header. This allows full customization and helps organize each command. + +The scripts are stored in an array of Strings, so they must be quoted (yaml actually will allow you not to quote them, but we advise you use quotes). And you can have as many as you want for each command. We do not impose limitations. + +Prison uses placeholders in these commands, so some commands have placeholders that will be removed and nothing will be inserted in their place. This is how it's designed to work. And that is also why it is important to understand why the placeholders are used, what they do, and why you need to use them. At this time, mine areas are not supported, but they have been added so as to be ready for this support when they are added. + + +| Placeholder | Description | Notes | +| :--- | :--- | ------------------- | +| {world} | Inserts the world name | When ran from the console, many commands must include `-w worldName`. Prison will inject this as needed, and only when the commands are viewed or ran from the console. | +| {mine-pos1} | One corner of the mine | Prison inserts the `x,y,z` coordinates for the first position. | +| {mine-pos2} | The other corner of the mine | Prison inserts the `x,y,z` coordinates for the second position.| +| {region-mine-name} | The generated region name to use | This is configured under `prison-mines.world-guard.region-mine.region-mine-name`. | +| {region-group-permission} | The generated group permission name to use | This is configured under `prison-mines.world-guard.region-mine.region-group-permission`. | +| {mine-area-pos1} | One corner of the mine area | Prison inserts the `x,y,z` coordinates for the first position. | +| {mine-area-pos2} | The other corner of the mine area | Prison inserts the `x,y,z` coordinates for the second position.| +| {region-mine-area-name} | The generated region name to use | This is configured under `prison-mines.world-guard.region-mine-area.region-mine-name`. | + + +## WorldGuard Region Scripts - Examples + +If your `config.yml` file does not contain these entries, you can copy and paste them from this document. + +But the actual preferred method would be to allow prison to regenerate the `config.yml` file. This can be achieved by renaming config.yml to something else, restart the server, then prison will generate one, and then you can shut down the server, rename the original and copy and paste what you need. Yeah this is a bit of a messy way of doing it, but this ensures you have the latest published version of these settings. + + +```yaml +prison-mines: + + world-guard: + WARNING: WorldGuard may not be fully supported yet. + + global-region-commands: + info: + - '/rg list {world}' + - '/rg info {world} __global__' + define: + - '/rg flag {world} __global__ passthrough deny' + deny-mob-spawning: + - 'rg flag {world} __global__ mob-spawning deny' + - '/gamerule doMobSpawning false' + mine-region-commands: + info: + - '/rg list {world}' + - '/rg info {world} {region-mine-name}' + redefine: + - '//pos1 {mine-pos1}' + - '//pos2 {mine-pos2}' + - '//region redefine {world} {region-mine-name}' + define: + - '/region define {world} {region-mine-name}' + - '/region addmember {world} {region-mine-name} {region-group-permission}' + - '/region setpriority {world} {region-mine-name} 20' + - '/region flag {world} {region-mine-name} block-break allow' + - '/region flag {world} {region-mine-name} item-pickup allow' + - '/region flag {world} {region-mine-name} exp-drops allow' + - '/region flag {world} {region-mine-name} item-drop allow' + select: + - '/region select {world} {region-mine-name}' + + mine-area-region-commands: + info: + - '/rg list {world}' + - '/rg info {world} {region-mine-area-name}' + redefine: + - '//pos1 {mine-area-pos1}' + - '//pos2 {mine-area-pos2}' + - '/region redefine {world} {region-mine-area-name}' + define: + - '/region define {world} {region-mine-area-name}' + - '/region addmember {world} {region-mine-area-name} {region-group-permission}' + - '/region setpriority {world} {region-mine-area-name} 10' + - '/region flag {world} {region-mine-area-name} block-break deny' + - '/region flag {world} {region-mine-area-name} item-pickup allow' + - '/region flag {world} {region-mine-area-name} exp-drops allow' + - '/region flag {world} {region-mine-area-name} item-drop allow' + select: + - '/region select {world} {region-mine-area-name}' + + region-mine: + enable: true + region-mine-name: 'prison_mine_{mine}' + region-group-permission: 'g:prison.mines.{mine}' + region-mine-area: + enable: false + region-mine-area-name: 'prison_mine_area_{mine}' + increase-x: 15 + increase-z: 15 + increase-y: 9999 + +``` + +Please note that `mine-area-region-commands`, `region-mine-area`, and mine areas in general, are not yet implemented in prison, and are not currently used. # Please READ This First - Using Access by Ranks to Simplify Many Things @@ -187,7 +348,7 @@ Then **in game**, give yourself a WorldEdit wand: **Purpose:** This prevents players from breaking any blocks in the world. It also prevents mobs from spawning. -As op, protect the whole world with a passthrough flag set to deny. This will prevent building, PVP, and everything else. Basically, any action that “passthrough†all over defined regions, will be denied. The command with the **-w world** parameter has been added to the following list too. Use that version from console, the other without **-w world** in game. And where the name **world** is the actual name of your world. +As op, protect the whole world with a passthrough flag set to deny. This will prevent building, PVP, and everything else. Basically, any action that “passthrough� all over defined regions, will be denied. The command with the **-w world** parameter has been added to the following list too. Use that version from console, the other without **-w world** in game. And where the name **world** is the actual name of your world. Note: the minimum you will need is the first line. The other two shuts down mob spawning, which is optional. @@ -282,7 +443,7 @@ And to now hook this up to prison, you do same command, dropping the leading sla This defines a WorldGuard region, and needs to be applied to all mines, unless the Mine Access Permissions are used. -Select the same area of the mine with the WorldEdit **wand**, then use the following commands to define a mine. It will define a region with the mine’s name, and set the parent to mine_template, with the only member ever being the permission group **prison.mines.**. Never add a player to a WorldGuard region since it will get messy. Always use permission based groups and then add the player to that group. +Select the same area of the mine with the WorldEdit **wand**, then use the following commands to define a mine. It will define a region with the mine’s name, and set the parent to mine_template, with the only member ever being the permission group **prison.mines.**. Never add a player to a WorldGuard region since it will get messy. Always use permission based groups and then add the player to that group. This example includes an owner of this mine which is the group owner. And added the group admin as a member so the admins will have full access to this mine, even if they do not personally have the player's rank to access this mine. The actual members you add are up to you, but these are just two examples that you should consider. @@ -321,7 +482,7 @@ The following region setting for access and deny may *appear* to be useful, but **NOTE:** -It’s a bad idea to deny access to the mines through these regions. Such as with **-g nonmembers deny** on the **prison_mine_** regions. If the players doesn't have access to the mines, and they try to enter from the top, WorldGuard will continually prevent them from entering, or more specifically it will prevent them from falling in to the mine. This will basically keep them floating in the air which will trigger a fly event within anti-hacking tools. It will be far more professional to protect the area that contains the mine, thus you can protect it over the whole y-axis too. Players can also get caught in a rapid loop where WorldGuard is trying to kick them out of the mine when restricting just the mine; could possibly cause a lot of lag, depending upon how many event’s are being triggered. +It’s a bad idea to deny access to the mines through these regions. Such as with **-g nonmembers deny** on the **prison_mine_** regions. If the players doesn't have access to the mines, and they try to enter from the top, WorldGuard will continually prevent them from entering, or more specifically it will prevent them from falling in to the mine. This will basically keep them floating in the air which will trigger a fly event within anti-hacking tools. It will be far more professional to protect the area that contains the mine, thus you can protect it over the whole y-axis too. Players can also get caught in a rapid loop where WorldGuard is trying to kick them out of the mine when restricting just the mine; could possibly cause a lot of lag, depending upon how many event’s are being triggered.
@@ -341,17 +502,17 @@ It’s a bad idea to deny access to the mines through these regions. Such as wit **Important:** You don't need to define mine-area regions if your mines are geographically isolated, such as islands in a void world. -In general, it may be tempting to restrict access to the mine itself so non-members cannot mine it. But there is a serious problem with just protecting the mine, and that’s when non-members walk on top of the mine. They will fall in to the mine, as expected, but WorldGuard will try to keep them out, so they will be bumped back above the mine, thus triggering a “fly†event, or a “hover†event. This action may trigger anti-hacking software to auto kick them, or auto ban the players, or the players could get stuck, and it may even cause a lot of lag on the server too. +In general, it may be tempting to restrict access to the mine itself so non-members cannot mine it. But there is a serious problem with just protecting the mine, and that’s when non-members walk on top of the mine. They will fall in to the mine, as expected, but WorldGuard will try to keep them out, so they will be bumped back above the mine, thus triggering a “flyâ€� event, or a “hoverâ€� event. This action may trigger anti-hacking software to auto kick them, or auto ban the players, or the players could get stuck, and it may even cause a lot of lag on the server too. This also happens really fast, in a very repeated action, so it could lock up the player so they cannot jump back out before they get banned. I do not know if this could contribute to server lag, but a lot of processing appears to be happening so it is possible. -The suggested action is to create a new region around the mine and protect that from entry from non-members. This region can then be extended from y=0 to y=255 with the WorldEdit command `//expand vert``. If anyone does get past it, they still won’t be able to mine. +The suggested action is to create a new region around the mine and protect that from entry from non-members. This region can then be extended from y=0 to y=255 with the WorldEdit command `//expand vert``. If anyone does get past it, they still won’t be able to mine. The primary purpose is to keep non-members out of the region. It will also prevent non-members from TP'ing in to the area too. It will also supply the player with an error message to inform them they don't have the rn -Select the an area around the mine with the WorldEdit **wand**. Only select a rectangle area around the mine, ignoring the **y** axis. Then use the following commands to define a mine. It will define a region with the mine’s name, and set the parent to mine_template, with the only member ever being the permission **g:prison.mines.**: +Select the an area around the mine with the WorldEdit **wand**. Only select a rectangle area around the mine, ignoring the **y** axis. Then use the following commands to define a mine. It will define a region with the mine’s name, and set the parent to mine_template, with the only member ever being the permission **g:prison.mines.**: The command **//expand vert** will take your selection and extend the **y** to cover the whole vertical range in your region. This is why you don't have to be concerned with the *y* axis when defining your mine area regions. @@ -563,7 +724,7 @@ One of the primary focuses for this document has been protecting the area around -Set’s the WorldEdit selection to the dimensions of the given mine: +Set’s the WorldEdit selection to the dimensions of the given mine: /region select prison_mine_ /region select prison_mine_area_ From 9682c9cc2cefc003b490b1f47d53e075f41d14de Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 21 Sep 2024 15:22:12 -0400 Subject: [PATCH 192/323] Doc updates: WorldGuard support --- ...docs_626_configuring_worldguard_regions.md | 136 +++++++++++++++++- 1 file changed, 135 insertions(+), 1 deletion(-) diff --git a/docs/prison_docs_626_configuring_worldguard_regions.md b/docs/prison_docs_626_configuring_worldguard_regions.md index 4afa7b8ea..fa5f91381 100644 --- a/docs/prison_docs_626_configuring_worldguard_regions.md +++ b/docs/prison_docs_626_configuring_worldguard_regions.md @@ -30,6 +30,8 @@ This document was initially created when WorldGuard Regions were the only way to There is a dedicated document related to [LuckPerms Groups & Tracks](prison_docs_030_LuckPerms_Groups_Tracks.md) (*[prison_docs_030_LuckPerms_Groups_Tracks.md](prison_docs_030_LuckPerms_Groups_Tracks.md)*), and how to set them up to work with prison. Please review that document if needed. +
+ # Prison's New Support for WorldGuard Regions This support is a new work in progress. Some features may not fully work, or may not be well documented. These features were initially introduced with version *3.3.0-alpha.19c*. @@ -53,6 +55,9 @@ Prison also has the feature where you can **run** them through a player that is This makes it simple. But yet there is still a lot of lack of automation because this requires a player to be online in the game. Why does the player have to be in the game? WorldEdit. Because WorldEdit does not provide a way to specify a target world on some of their commands, such as `//pos1` and `//pos2`, which is the primary way to set a regions area through the use of x,y,z coordinates. Sucks doesn't it? If this was not a limitation, then it would be trivial to script everything. +
+ + # Running the Prison Mines WorldGuard Region commands These new commands are located under this command, which will list all available commands: @@ -76,6 +81,7 @@ These new commands are located under this command, which will list all available [INFO]: /mines worldguard region mineSelect [mineName] [playerName] [options] ``` +
# Prison's config.yml settings @@ -100,6 +106,9 @@ Prison uses placeholders in these commands, so some commands have placeholders t | {region-mine-area-name} | The generated region name to use | This is configured under `prison-mines.world-guard.region-mine-area.region-mine-name`. | + +
+ ## WorldGuard Region Scripts - Examples If your `config.yml` file does not contain these entries, you can copy and paste them from this document. @@ -176,8 +185,116 @@ prison-mines: Please note that `mine-area-region-commands`, `region-mine-area`, and mine areas in general, are not yet implemented in prison, and are not currently used. +
+ +# WorldGuard Help + +Let's be honest, it's not always easy to get all plugins properly configured and working with each other as we may envision our servers. Plus, when access is being controlled by another plugin, such as WorldGuard and LuckPerms, it makes things even more complicated, especially when it's your first time working with these tools and plugins. + +Generally, googling with specific problems helps, but since Spigot, WorldGuard, and LuckPerms has been out for so many years, sometimes the suggested search results are not exactly what your plugin versions need, or they can be just flat-out bad advice. So as a suggestion, look at when your version of plugins were released and then compare those release dates to the time stamps that google sometimes provides (they don't always tell you how old a post is). This is important if you're running Spigot 1.8.8 and using WG v6.x. That old version is not supported by WG support anymore, so you won't get live help from them. But don't give up, solutions usually exist and you will find them if you keep looking. + +One general challenge to getting Prison to work with WorldGuard when using it with BlockBreakEvents, are the priorities of the event listeners. To help with these kind of issues of who is canceling, or denying access to my mines!? Prison has some tools you can use to help debug which plugin is doing what to the BlockBreakEvents. + +`/prison support listeners blockBreak` + +This lists all block-break events that Prison is enabled to listen for (see the `autoFeaturesConfig.yml` file for enabling others if needed). And it shows their priorities. This alone can be very helpful in understanding which plugins before Prison my be denying the access to a mine (canceling the event). + +These reports can become pretty complex, especially if there are many events that prison has been setup to listen to. + +``` +> prison support listeners blockbreak +[INFO]: PEExplosionEvent: org.bukkit.event.HandlerList +[INFO]: ||Listeners blockBreak||-- < Event Dump: BlockBreakEvent (LOW) > ---- (3.3.0-alpha.19c) +[INFO]: All registered EventListeners (15): +[INFO]: . Plugin: ExcellentEnchants LOWEST (su.nightexpress.excellentenchants.registry.wrapper.WrappedEvent) +[INFO]: . Plugin: FastAsyncWorldEdit LOWEST (com.fastasyncworldedit.bukkit.listener.ChunkListener9) +[INFO]: . Plugin: ExcellentEnchants LOW (su.nightexpress.excellentenchants.registry.wrapper.WrappedEvent) +[INFO]: . Plugin: Prison LOW (tmps.ae.AutoManagerBlockBreakEvents$AutoManagerBlockBreakEventListener) +[INFO]: . Plugin: ExcellentEnchants NORMAL (su.nightexpress.excellentenchants.registry.wrapper.WrappedEvent) +[INFO]: . Plugin: WorldGuard NORMAL (com.sk89q.worldguard.bukkit.listener.EventAbstractionListener) +[INFO]: . Plugin: WorldGuard NORMAL (com.sk89q.worldguard.bukkit.listener.EventAbstractionListener) +[INFO]: . Plugin: PrisonEnchants NORMAL (me.pulsi_.prisonenchants.listeners.customEnchantListener.CustomEnchantListenerNormal) +[INFO]: . Plugin: Prison NORMAL (tmps.SpigotListener) +[INFO]: . Plugin: ExcellentEnchants HIGH (su.nightexpress.excellentenchants.registry.wrapper.WrappedEvent) +[INFO]: . Plugin: WorldGuard HIGH (com.sk89q.worldguard.bukkit.listener.WorldGuardBlockListener) +[INFO]: . Plugin: ExcellentEnchants HIGHEST (su.nightexpress.excellentenchants.registry.wrapper.WrappedEvent) +[INFO]: . Plugin: ExcellentEnchants HIGHEST (su.nightexpress.excellentenchants.enchantment.impl.armor.FlameWalkerEnchant) +[INFO]: . Plugin: Essentials HIGHEST (com.earth2me.essentials.signs.SignBlockListener) +[INFO]: . Plugin: ExcellentEnchants MONITOR (su.nightexpress.excellentenchants.registry.wrapper.WrappedEvent) +[INFO]: NOTE: Prison's Block-Event Listeners: +[INFO]: . . Prison Internal BlockBreakEvents (non-auto features): tmps.SpigotListener +[INFO]: . . Auto Features: tmps.ae.AutoManagerBlockBreakEvents$*] +[INFO]: . . Prison Abbrv: 'tmps.' = 'tech.mcprison.prison.spigot.' & 'tmps.ae.' = 'tmps.autofeatures.events.' +[INFO]: < Event Dump: Pulsi_'s PEExplosionEvent (NORMAL) > (3.3.0-alpha.19c) +[INFO]: All registered EventListeners (1): +[INFO]: . Plugin: Prison NORMAL (tmps.ae.AutoManagerPrisonEnchants$AutoManagerPEExplosiveEventListener) +[INFO]: < Event Dump: ExplosiveBlockBreakEvent (LOW) > (3.3.0-alpha.19c) +[INFO]: All registered EventListeners (1): +[INFO]: . Plugin: Prison LOW (tmps.ae.AutoManagerPrisonsExplosiveBlockBreakEvents$AutoManagerExplosiveBlockBreakEventListener) +[INFO]: < Event Dump: EntityExplodeEvent (LOW) > (3.3.0-alpha.19c) +[INFO]: All registered EventListeners (8): +[INFO]: . Plugin: Essentials LOW (com.earth2me.essentials.signs.SignEntityListener) +[INFO]: . Plugin: Essentials LOW (com.earth2me.essentials.TNTExplodeListener) +[INFO]: . Plugin: Prison LOW (tmps.ae.AutoManagerEntityExplodeEvents$AutoManagerEntityExplodeEventListener) +[INFO]: . Plugin: ExcellentEnchants NORMAL (su.nightexpress.excellentenchants.enchantment.impl.tool.BlastMiningEnchant) +[INFO]: . Plugin: ExcellentEnchants NORMAL (su.nightexpress.excellentenchants.enchantment.impl.armor.FlameWalkerEnchant) +[INFO]: . Plugin: WorldGuard NORMAL (com.sk89q.worldguard.bukkit.listener.EventAbstractionListener) +[INFO]: . Plugin: PrisonEnchants NORMAL (me.pulsi_.prisonenchants.listeners.EntityListener) +[INFO]: . Plugin: WorldGuard HIGH (com.sk89q.worldguard.bukkit.listener.WorldGuardEntityListener) +> +``` + +Prison also has a debug mode that allows debugging of an actual block breakage event, and inspects what each plugin does with that event. + +You can enable it with: +`/prison debug` (run in console: enables debug mode in prison) +`/mines wand` (run in game: gives your admin charater a mine wand) + on a block (sneak click with your right mouse button to trigger the event) + +The details will be printed to the console. To turn off Prison's debug mode: `/prison debug` + + +``` +[INFO]: Transaction log: RoyalBlueRanger multiplier: 1.00 ItemStacks: 1 ItemCount: 1 TotalAmount: 45.00 [raw_gold:1:45.00] +[INFO]: ### ** handleBlockBreakEvent ** ### (event: BlockBreakEvent, config: LOW, priority: LOW, canceled: FALSE) EventInfo: results_passed RoyalBlueRanger Mine: blue_a GOLD_ORE (world,365,82,226) +[INFO]: || validateEvent:: itemInHand=[Diamond pickaxe ] blocks(1+0) (PassedValidation) (Fire pmEvent *start*) +[INFO]: || (applyAutoEvents: GOLD_ORE Pickup [disabled:mines] Smelt [disabled:mines] Block [disabled:mines] )(NormalDrop handling enabled: normalDropSmelt[disabled:] normalDropBlock[disabled:] normalDropCheckForFullInventory[disabled:] ) +[INFO]: || [normalDrops:: Raw gold:1] (getToolFort: fort=0) (dropping: Raw gold qty: 1 value: 45.0) +[INFO]: || [normalDrops total: qty: 1 value: 45.0] (autoEvents totalDrops: 1) (applyDropsBlockBreakage multi-blocks: 0) (breakBlocks:submitTask:1)(Fire pmEvent *completed*) (sellallEnabled:userToggleable)(autosellPlayerToggled: enabled) +[INFO]: || ### ** End Event Debug Info ** ### [50.996 ms] +[INFO]: DebugBlockInfo: Mine blue_a Rank: --- GOLD_ORE (world,365,82,226) +[INFO]: TargetBlock: gold_ore Mined: false Broke: false Counted: false +[INFO]: isEdge: false Exploded: false IgnoreAllEvents: false +[INFO]: BlockBreakEvent Dump: GOLD_ORE (365, 82, 226) +[INFO]: Tool Used for drops: Diamond pickaxe +[INFO]: Legend: EP: EventPriority EC: EventCanceled DC: DropsCanceled EB: EventBlock Ds: Drops ms: dur ms +[INFO]: Plugin: -initial- EP: EC: false DC: normal EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: --- +[INFO]: Plugin: ExcellentEnchants EP: LOWEST EC: false DC: normal EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 0.059400 +[INFO]: Plugin: FastAsyncWorldEdit EP: LOWEST EC: false DC: normal EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 0.020100 +[INFO]: Plugin: ExcellentEnchants EP: LOW EC: false DC: normal EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 0.022800 +[INFO]: Plugin: Prison EP: LOW EC: false DC: canceled EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 51.845600 +[INFO]: Plugin: ExcellentEnchants EP: NORMAL EC: false DC: canceled EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 0.048900 +[INFO]: Plugin: WorldGuard EP: NORMAL EC: false DC: canceled EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 10.979900 +[INFO]: Plugin: WorldGuard EP: NORMAL EC: false DC: canceled EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 0.053500 +[INFO]: Plugin: PrisonEnchants EP: NORMAL EC: false DC: canceled EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 10.162000 +[INFO]: Plugin: Prison EP: NORMAL EC: false DC: canceled EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 1.030600 +[INFO]: Plugin: ExcellentEnchants EP: HIGH EC: false DC: canceled EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 0.023500 +[INFO]: Plugin: WorldGuard EP: HIGH EC: false DC: canceled EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 0.033300 +[INFO]: Plugin: ExcellentEnchants EP: HIGHEST EC: false DC: canceled EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 0.007500 +[INFO]: Plugin: ExcellentEnchants EP: HIGHEST EC: false DC: canceled EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 0.041100 +[INFO]: Plugin: Essentials EP: HIGHEST EC: false DC: canceled EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 0.178200 +[INFO]: Plugin: ExcellentEnchants EP: MONITOR EC: false DC: canceled EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 0.075300 +[INFO]: - - End DebugBlockInfo - - +> +``` + + +
+ + # Please READ This First - Using Access by Ranks to Simplify Many Things +*Note: This part of the document, through to the end, represents older notes. These may still be useful.* The latest versions of Prison has a new feature called **Access by Ranks** where a player, based upon their rank, is able to access a mine (break blocks within a mine) and also they can use the `/mtp` feature (mines teleport). By using **Access by Ranks** you do not have to setup any WorldGuard regions to allow players to break blocks within the mines, and you don't have to setup any permissions. @@ -208,6 +325,7 @@ If you need to manually setup Access By Ranks: # Prison's Event Priorities and WorldGuard Regions +*Note: This represents older notes. These may still be useful.* **NOTE:** You can also grant access through WorldGuard regions, and then prison will allow anyone to break blocks in the mines. The catch is that you must ensure WorldGuard checks access prior to Prison getting control of the BlockBreakEvents. This requires setting up WorldGuard regions and permissions. @@ -247,6 +365,8 @@ You cannot set any of the above event priorities to MONITOR since that goes agai # Please READ This Next +*Note: This represents older notes. These may still be useful.* + This document is a work in progress. This is a complex topic and depending upon how your environment is setup, the actual configurations may need to vary from what's covered in this document. @@ -378,6 +498,8 @@ Note that the **/gamerule doMobSpawning false** may also help prevent mobs from # Various LuckPerm Commands for Templates and Mines +*Note: This represents older notes. These may still be useful.* + *Not supported - For informational purposes only* The WorldGuard regions are covered below, but first you need to setup the groups within LuckPerm. Failure to create the groups prior to using them with the regions and prison rank commands may result in failures to work properly. @@ -433,6 +555,8 @@ And to now hook this up to prison, you do same command, dropping the leading sla # Unprotecting a Mine for its members - Required for all Mines +*Note: This represents older notes. These may still be useful.* + *Not supported - For informational purposes only* @@ -493,6 +617,8 @@ It’s a bad idea to deny access to the mines through these regions. Such a # Protecting a Mine's Area - Required for all Mine Areas +*Note: This represents older notes. These may still be useful.* + *This kind of a region is partially supported. It is used to physically prevent a player from entering an a mine's area.** @@ -554,6 +680,8 @@ Of course, just like **prison_mine_** region, we also give `owner` an # Granting Access to a Mine and Removal of the access +*Note: This represents older notes. These may still be useful.* + **Purpose:** From either the console, or from within game, manually grant a player access to a mine. To add a player to the mine regions is as simple as giving the user the permission associated with the mine region. @@ -629,6 +757,8 @@ The following is an example of adding and removing a permission to a player. Th # Adding Rank Commands to run when /rankup is Performed +*Note: This represents older notes. These may still be useful.* + **Purpose:** Adds the permission to access the mine area and to mine within a mine, when a player successfully runs /rankup. @@ -664,6 +794,7 @@ So to recap, for every rank, ideally you should add the new perms for that rank, # Adding the Prison Rank Commands - Summary of Rank Commands +*Note: This represents older notes. These may still be useful.* This is an example of setting up Rank Commands for mines a and b, we now need to add the Rank Commands to active the permission for both. Also included in these commands are the permissions for the mines.tp command, where mines.tp. is a permission and not a group. @@ -697,6 +828,8 @@ And that's it! Just repeat for all your other mines. # Alternatives +*Note: This represents older notes. These may still be useful.* + There are many ways to accomplish the same goals and that's what makes Minecraft so versatile and interesting to play. The Prison Plugin does not want to impose a specific way to do most things, since it may not be the ideal way for your sever. One of the primary focuses for this document has been protecting the area around your mine to prevent players who should not access the mine, from enter that region. One alternative to needing to protect a mine, would be to limit the access to the mine so it does not have to be protected. One simple way of accomplishing that, is to have the mines in a void world, and then each mine would be a separate island. Then all that would need to be protected, or controlled, would be the warping to that location. @@ -715,6 +848,7 @@ One of the primary focuses for this document has been protecting the area around # Other Commands That May Be Important: +*Note: This represents older notes. These may still be useful.* /region redefine mine_ @@ -724,7 +858,7 @@ One of the primary focuses for this document has been protecting the area around -Set’s the WorldEdit selection to the dimensions of the given mine: +Set's the WorldEdit selection to the dimensions of the given mine: /region select prison_mine_ /region select prison_mine_area_ From 0ea7bc6e7c2dd4ab3e9a3077d6e445115eed064f Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 21 Sep 2024 15:30:34 -0400 Subject: [PATCH 193/323] Doc updates: WorldGuard support --- ...docs_626_configuring_worldguard_regions.md | 39 ++++++++++--------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/docs/prison_docs_626_configuring_worldguard_regions.md b/docs/prison_docs_626_configuring_worldguard_regions.md index fa5f91381..e2f4c368d 100644 --- a/docs/prison_docs_626_configuring_worldguard_regions.md +++ b/docs/prison_docs_626_configuring_worldguard_regions.md @@ -247,9 +247,9 @@ These reports can become pretty complex, especially if there are many events tha Prison also has a debug mode that allows debugging of an actual block breakage event, and inspects what each plugin does with that event. You can enable it with: -`/prison debug` (run in console: enables debug mode in prison) -`/mines wand` (run in game: gives your admin charater a mine wand) - on a block (sneak click with your right mouse button to trigger the event) + `/prison debug` (run in console: enables debug mode in prison) + `/mines wand` (run in game: gives your admin charater a mine wand) + `` on a block (sneak click with your right mouse button to trigger the event) The details will be printed to the console. To turn off Prison's debug mode: `/prison debug` @@ -268,22 +268,23 @@ The details will be printed to the console. To turn off Prison's debug mode: `/ [INFO]: BlockBreakEvent Dump: GOLD_ORE (365, 82, 226) [INFO]: Tool Used for drops: Diamond pickaxe [INFO]: Legend: EP: EventPriority EC: EventCanceled DC: DropsCanceled EB: EventBlock Ds: Drops ms: dur ms -[INFO]: Plugin: -initial- EP: EC: false DC: normal EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: --- -[INFO]: Plugin: ExcellentEnchants EP: LOWEST EC: false DC: normal EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 0.059400 -[INFO]: Plugin: FastAsyncWorldEdit EP: LOWEST EC: false DC: normal EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 0.020100 -[INFO]: Plugin: ExcellentEnchants EP: LOW EC: false DC: normal EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 0.022800 -[INFO]: Plugin: Prison EP: LOW EC: false DC: canceled EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 51.845600 -[INFO]: Plugin: ExcellentEnchants EP: NORMAL EC: false DC: canceled EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 0.048900 -[INFO]: Plugin: WorldGuard EP: NORMAL EC: false DC: canceled EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 10.979900 -[INFO]: Plugin: WorldGuard EP: NORMAL EC: false DC: canceled EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 0.053500 -[INFO]: Plugin: PrisonEnchants EP: NORMAL EC: false DC: canceled EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 10.162000 -[INFO]: Plugin: Prison EP: NORMAL EC: false DC: canceled EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 1.030600 -[INFO]: Plugin: ExcellentEnchants EP: HIGH EC: false DC: canceled EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 0.023500 -[INFO]: Plugin: WorldGuard EP: HIGH EC: false DC: canceled EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 0.033300 -[INFO]: Plugin: ExcellentEnchants EP: HIGHEST EC: false DC: canceled EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 0.007500 -[INFO]: Plugin: ExcellentEnchants EP: HIGHEST EC: false DC: canceled EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 0.041100 -[INFO]: Plugin: Essentials EP: HIGHEST EC: false DC: canceled EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 0.178200 -[INFO]: Plugin: ExcellentEnchants EP: MONITOR EC: false DC: canceled EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 0.075300 + +[INFO]: Plugin: -initial- EP: EC: false DC: normal EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: --- +[INFO]: Plugin: ExcellentEnchants EP: LOWEST EC: false DC: normal EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 0.059400 +[INFO]: Plugin: FastAsyncWorldEdit EP: LOWEST EC: false DC: normal EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 0.020100 +[INFO]: Plugin: ExcellentEnchants EP: LOW EC: false DC: normal EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 0.022800 +[INFO]: Plugin: Prison EP: LOW EC: false DC: canceled EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 51.845600 +[INFO]: Plugin: ExcellentEnchants EP: NORMAL EC: false DC: canceled EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 0.048900 +[INFO]: Plugin: WorldGuard EP: NORMAL EC: false DC: canceled EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 10.979900 +[INFO]: Plugin: WorldGuard EP: NORMAL EC: false DC: canceled EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 0.053500 +[INFO]: Plugin: PrisonEnchants EP: NORMAL EC: false DC: canceled EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 10.162000 +[INFO]: Plugin: Prison EP: NORMAL EC: false DC: canceled EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 1.030600 +[INFO]: Plugin: ExcellentEnchants EP: HIGH EC: false DC: canceled EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 0.023500 +[INFO]: Plugin: WorldGuard EP: HIGH EC: false DC: canceled EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 0.033300 +[INFO]: Plugin: ExcellentEnchants EP: HIGHEST EC: false DC: canceled EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 0.007500 +[INFO]: Plugin: ExcellentEnchants EP: HIGHEST EC: false DC: canceled EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 0.041100 +[INFO]: Plugin: Essentials EP: HIGHEST EC: false DC: canceled EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 0.178200 +[INFO]: Plugin: ExcellentEnchants EP: MONITOR EC: false DC: canceled EB: minecraft:GOLD_ORE Ds: Raw gold(1) ms: 0.075300 [INFO]: - - End DebugBlockInfo - - > ``` From 992b817c50a2ebd270394087588136a5d66b276f Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 22 Sep 2024 00:08:20 -0400 Subject: [PATCH 194/323] Doc updates: WorldGuard support & custom placeholders. --- docs/prison_docs_310_guide_placeholders.md | 1747 ++++++++++------- ...docs_626_configuring_worldguard_regions.md | 10 +- 2 files changed, 991 insertions(+), 766 deletions(-) diff --git a/docs/prison_docs_310_guide_placeholders.md b/docs/prison_docs_310_guide_placeholders.md index 0dd29d5ca..e17f9e1a7 100644 --- a/docs/prison_docs_310_guide_placeholders.md +++ b/docs/prison_docs_310_guide_placeholders.md @@ -1,762 +1,985 @@ - -### Prison Documentation -[Prison Documents - Table of Contents](prison_docs_000_toc.md) - -## Prison - Placeholder Guide - -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: 2023-10-01* - - -
- - -# Overview - -Placeholders allow the sharing of data from one plugin with another plugin, and without either plugin knowing anything about each other. - -On the surface they appear to be simple, but there are a lot of moving parts below the surface, and with Prison, there are even more complicated things going on. - -Add in to the mix, that different plugins deal with placeholders in slightly different ways, and you can wind up with a challenge to get them to work under different circumstances. - -
- - - - -# Placeholder Commands - - -*Since Prison v3.2.1-alpha.13* - - -There are a few useful commands within prison that will allow you list placeholders, search for placeholders, and to test random text that includes placeholders. - - -Sub-command listing of all placeholders commands: - -* **/prison placeholders** - -> Shows a list of all of the placeholder related commands. - - -* **/prison placeholders list** - -> Lists all placeholders that are available, including their aliases. Placeholders are grouped by their type, of which there are 10 different kinds. Some are player specific, rank or ladder specific, mine specific, or even hybrid combinations such as player-mine were the mine stats are based upon which mine the player is in. - - -* **/prison placeholders search** - -> Provides a simple search for placeholders, optionally using a player's name, and it shows the results with actual live placeholder values. Search values can be one or more word fragments. - - -* **/prison placeholders test** - -> Somewhat like search, but you have to provide the whole placeholder surrounded by escape characcters. Can provide more than one placeholder too. This is more like testing what you would place within a chat prefix or holographic sign. - - -* **/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 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** - -> Reloads and rebuilds all placeholders and then reregisters them. This is performed when adding or removing a new mine or rank. - - - -NOTE: the `/prison placeholders reload` command only reloads and registers the placeholders with the placeholder integrations. This would be required to enable placeholders when adding a new mine, a new rank, or a new ladder. If you reload another plugin, such as papi, you may need to reload the placeholders which will re-register them. Prison has been setup to survive a papi restart, but there could still be issues. - - -NOTE: Information on these command are provided in detail below. - - -
- - -# Placeholder Types and Counts - -Prison has numerous placeholders, with number of different types. Each of these types have different internal requirements and conditions of usage. This is a high overview of the various types and their counts. - - -* **Total Available Placeholders:** 294 including aliases - - -* **Player Related:** 110 including aliases - * **Rank Related:** 8 including aliases - * **Rankup Related:** 20 including aliases - * **Player Balance Related:** 8 including aliases - * **Player Token Balance Related:** 12 including aliases - * **Player Blocks Totals Related: 4 including aliases - * **Player Tool Related:** 34 including aliases - * **Player Health Related:** 14 including aliases - * **Player XP and Levels Related:** 6 including aliases - * **Player Walk Speed:** 2 including aliases - - -* **Ladders Related:** 32 including aliases **times** each ladder - -> A LADDERS placeholder must include the ladder's name in the placeholder and therefore is static. - -> The ladder based placeholders end with `_laddername`, but they include the following possible prefixes, which may not be exclusive to ladder based placeholders. - -> Ladder placeholder prefixes: - * `prison_rank_` - * `prison_rankup_` - * `prison_player_` - - - -* **Ranks Related:** 22 including aliases **times** each rank - -> A RANKS placeholder needs to specify the Rank name as part of the placeholder. Each placeholder must specify a Rank and is static. - -> The ranks based placeholders end with `_rankname` but do not require a player to work. They also have a prefix of `prison_rank__` but these prefixes and suffixes are also shared with **RankPlayers** placeholders. See them for specifics. - -> Ranks placeholder prefixes: - * `prison_rank__` - - -* **RankPlayers Related:** 12 including aliases **times** each rank - -> A RANKPLAYERS placeholder is one that will change based upon the player's own Rank. Each player could have a different rank. Because of this relationship, these can only be used with instances of players such as scoreboards and chat prefixes; they will not work in holographic displays or with signs. - -> RankPlayers placeholders are very similar to the Rank placeholders in respect to the prefixes and suffixes, but these placeholders MUST include a player or they cannot work. Without a player, they cannot return a valid value, and therefore will return either a blank or zero. - -> What makes these placeholders stand out from rank placeholders is the prefix includes `player_`. For example: - -> RankPlayers placeholder prefixes: - * `prison_rank__player_` - - -> **Performance Warning:** There is a high risk of performance issues when calculating a full GUI page of items that includes the use of placeholders that are based upon the placeholders: `prison_rank__player_cost_rankname`. The reason for this is related to a progressively great number of calculations required to calculate high ranked prestige ranks. The performance impact can include processing and memory usages. - -> For example, if there are 26 default ranks, and the player is at rank A with no prestiges, then to calculate rank P4 would include the following ranks: -b --> z + p1 + a --> z + p2 + a --> z + p3 + a --> z + p4. -This results in a total of 107 ranks that must be collected, then the player's cost for each rank will have to be calculated. Then all of these must be added together to get the player's cost on rank P4. - -> So if there are thousands of prestige ranks, then the calculations will be numerous for each placeholder. - - -* **Player Ladder Balance Related:** 32 including aliases **times** each Mine - - -* **Mines Related:** 32 including aliases **times** each ladder - -> A MINES placeholder must specify the Mine mine as part of the placeholder. - -> The Mines related placeholders have the following prefixes, but they are also shared with the MinePlayers placeholders. -* `prison_mines_` -* `prison_top_mine_` - - - -* **MinePlayers Related:** 32 including aliases - -> A MINEPLAYERS placholder is similar to a RankPlayers placeholder in that it is dynamic and you cannot specify a mine's name with it. How it works, is that it provides the related stats for the mine in which the player is standing in. When the player leaves the mine, then these placeholders returns an empty string value (a blank). - -> The MinePLayers placeholders includ the following prefixes, but they are also similar to the Mines related placeholder too: - * `prison_player_` - * `prison_mines_` - - -* **PLAYERBLOCKS:** 4 including aliases - -> Every block type that a player breaks within a mine is tracked. These provide the stats on those blocks. - - -* **STATSMINES Related:** 14 including aliases - -> These list the blocks within a mine. They are referred to with a `_nnn_` notation where "nnn" is the line number - - -* **STATSRANKS Related:** 6 including aliases - -> Top-n stats for each rank. The rank name must be specified on the placeholder. - - -* **STATSPLAYERS:** 30 including aliases - -> Various placeholders for the top-n ranked players. These are over all ranks. There are a couple of shortcut placehodlders where one placeholders contain multiple fileds for easier usage. - - - - - - - -
- - -# Requirements - -There is always more than one way to do things, and the same goes for having more than one way to use placeholders. This documentation, and our test servers, primarily rely on the use of PlaceholderAPI as the core component to making placeholders work. Depending upon other plugins that you may use, they may have other dependencies too. - -**PlaceholderAPI** - [Setting up PlaceholderAPI](prison_docs_0xx_setting_up_PlaceholderAPI.md) - Strongly Suggested if using placeholders. - - -**Holographs** - There are actual a couple of holograph display plugins. Most of the references in this document refer to Holographic Displays, but some of the newer plugins can provide the same functionality, plus many new features. - -
- - -# Placeholder Theory for Prison - -*(needs updating: Prison now has 10 types of placeholders including top-n variations)* - - -There are few major types of placeholders in prison: Player, Ranks, Ladders, Mines, and Stats based. With the most recent releases of prison, there have been hybrids added that are a combination of the player placeholders and with mines and ranks. For example there are now ladder based placeholder that allow targeting ranks on a specific ladder, instead of all ladders. Also there are player mine placeholders that report on the mine stats for the mine in which the player is physically located in. The player mine placeholders have no value when the player is not in a mine, and they will change as the player goes from mine to mine. - -There are also different types of data that are returned in placeholders. Text, numbers, formatted numbers, and bar graphs. - -The player based placeholders can only report on the player that is initiating the command, or request. These placeholders pertain to the player's attributes, such as rank, next rank, their balance, how more they need before reaching the next rank, and etc. Internally, all of these requests must include the player's UUID, which is why you cannot just add them to a sign, since the sign does not know any player's UUID. - -There are actually two major kinds of player based placeholders; a third type is "related" more to mines and not specifically to the player's ranks. Rank placeholders that returns all of the player's current attributes for all active ladders they are associated with. For example, if they are active on four ladders, then they will have four active ranks on four ladders with possible values. So it may look something like this: `[mod][Zeus][+2][B]`, of which the ladders could be mod, donor, prestige, and default. The thing to remember about player rank placeholders is that they may return more than one value, and you cannot control the order of the values. - -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. - -Prison has integrations for direct use of providing placeholder values to to the other plugins. Some of those other plugins request placeholder values using partial placeholder names. Therefore to improve performance and to prevent having to always reconstructing the full placeholder names, prison precomputes the fragments for all placeholders. Therefore, with our example of 40 mines and 10 placeholders, the actual internal number of placeholder combinations that prison will respond to is 800: 40 mines x 10 placeholders per mine x 2 for aliases = 800 placeholders for prison. - -Off hand this may sound bad, but Prison utilizes enumerations for identifying placeholders, so they may be objects, but they are lightweight and helps ensure placeholders align with the code at compile time. This not only provides better performance, and less memory consumption, but programming errors and typos are caught at compile time and not runtime, so they also provide for a more stable and reliable Prison environment. - -Internally, placeholders within Prison are case insensitive. But Prison uses lower cased placeholder names to register with any placeholder integration. Therefore, although prison may be case insensitive, the placeholder plugins may not recognize the placeholders unless you use them as all lower case names. - -Also, internally, prison only responds to the placeholder name without the escape characters. The escape characters are generally curly braces { }, or percents % %, but may be other characters. All placeholder plugins strip off the escape characters before passing anything to prison. So proper use of placeholders is dependent upon what is being required by your placeholder plugin and may require a mix of escape characters. - -
- - -# Placeholder Attributes - Customize almost any Prison Placeholder - -*Since Prison v3.2.4-alpha.2* - - -Placeholders within prison can now be dynamically customized without having to make any changes to any configurations. The same placeholder can be used in multiple place, each with different configurations. This is now possible through the use of placeholder attributes and offers a large degree of customization. - - -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=<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. - - - -The following shows how a few placeholder need to have the "minename" replaced with the actual mine's name. For these examples, we will use a mine named **temp5**. - -* **prison_mines_size_minename** - `{prison_mines_size_temp5}` -* **prison_mines_remaining_minename** - `{prison_mines_remaining_temp5}` -* **prison_mines_remaining_bar_minename** - `{prison_mines_remaining_bar_temp5}` -* **prison_mines_timeleft_bar_minename** - `{prison_mines_timeleft_bar_temp5}` - - - -A few Examples using Placeholder Attributes: - -* `{prison_mines_size_temp5::nFormat:#,##0}` - **654,321** -* `{prison_mines_size_temp5::nFormat:#,##0:0:none}` - **654,321** -* `{prison_mines_size_temp5::nFormat:#,##0.00:1:kmg}` - **654.32 k** -* `{prison_mines_size_temp5::nFormat:#,##0:0:kmg}` - **654k** - - -* `{prison_mines_remaining_bar_temp5}` - Normally displays as (no color) - * **>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<** -* `{prison_mines_remaining_bar_temp5::bar:10}` - Using default values, but change length to 10 - * **>>>>>>>>><** -* `{prison_mines_remaining_bar_temp5::bar:10:&2:#:&d:-}` - Change all settings - * **#######---** -* `{prison_mines_timeleft_bar_temp5::bar:40:&2:O:&d:x:debug}` - Enable debug mode for the attribute - * **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: - - -The placeholder: `{prison_mines_timeleft_bar_temp5::bar:40:&2:O:&d:x:debug}` - -The full command: -`/prison placeholders test {prison_mines_timeleft_bar_temp5::bar:40:&2:O:&d:x:debug}` - - -Example of an attribute with debug - -When debug mode is enabled, it will print to the console information about the placeholder attribute, as seen in the above screen print. This could be useful when testing the configuration of placeholder attributes - - -Using the command `/prison placeholders test` should be used to test and perfect the use of the placeholder attributes. - -
- - - -## Placeholder Attribute: nFormat - Numeric Formats - - -The Numeric Format attribute will only work on placeholders that return plain numbers. If there is a "_format" version of the placeholder, then an attribute will override the default formatting. - -Example of this attribute's usage is as follows, using descriptions for each parameter. - -`::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. Examples of - how the formatting can be used: - * #,### - * #,###.00 - * #,###.00000 - -- **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 the placeholder type that is used. - - * **none**: No display of units. No transformations. - * **kmg**: Uses one character units: kMGTPEZY. Transforms results by - dividing by 1000.0 until value is less than 1000.0, and - each time it increments the unit character. - k=1,000, M=1,000,000 and etc. These are metric SI codes. - * **kmbt**: Uses one character units: KMBTqQsS. Transforms results by - dividing by 1000.0 until value is less than 1000.0, and - each time it increments the unit character. - k=1,000, M=1,000,000 and etc. These are non-standard codes. - * **binary**: Uses a base-two divisor of 1024 along with the units: - KB, MB, GB, TB, PB, EB, ZB, and YB. - - * *Note:* Other unitTypes can be added along with different style of - 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 - 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. 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. - - - -The parameters that are optional do not have to be included, unless another parameter after the optional ones are needed. Then the optional parameter must be supplied and cannot be empty. - - -`{prison_mines_size_temp5::nFormat:#,##0.00:1:kmg}` - - - -Although it is not suggested to include color codes in the formatting of numbers, it may be possible with the addition of the quoting them with single quotes. The following use of **hex2** format works well with testing on a scoreboard that does not support hex colors, and is a way to inject the hex color when it cannot be used directly in the scoreboard configs. - -``` -{prison_mines_size_temp5::nFormat:'#af33ff'#,##0.00:1:kmg:hex} -{prison_mines_size_temp5::nFormat:'#af33ff'#,##0.00:1:kmg:hex2} -``` - - - -
- - - - -## Placeholder Attribute: bar - Bar Graphs - - -The bar placeholder attribute only works with placeholders with the word bar in them. - - -Example of this attribute's usage is as follows, using descriptions for each parameter. - -`::bar:size:posColor:posSeg:negColor:negSeg:reverse:hex:hex2:debug:player=` - - - -- **bar**: the keyword to identify this attribute. -- **size**: The number of segments to generate. -- **Positive Color**: The color code to use for the positive segments. - Color codes should start with an &. -- **Positive Segment**: The value that will be used for the positive - segment. -- **Negative Color**: The color code to use for the negative segments. - Color codes should start with an &. -- **Negative Segment**: The value that will be used for the negative - segment. - - -- **reverse**: **Optional.** Case sensitive. Non-positional; can be placed anywhere. - When enabled, this will reverse the bar graph. - - -- **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. 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. - - - -The parameters are all optional and if they are not supplied then the default values for the bar graph will be used instead. - -`{prison_mines_remaining_bar_temp5::bar:10}` - -`{prison_mines_remaining_bar_temp5::bar:10:&2:#:&d:-}` - -`{prison_mines_timeleft_bar_temp5::bar:40:&2:O:&d:x:debug}` - - -To use hex color codes within the bar graphs, the plugins that are requesting them, may not always support hex colors. So the options of **hex** and **hex2** are options to provide pre-formatting of the hex colors so that way the hex colors could work with plugins that do not support them. If the use of **hex** does not work, then **hex2** may. - - -Examples of using hex color codes in a bar graph placeholder. Try it first with **hex**, and if that does not work, then try **hex2**. - -``` -{prison_mines_timeleft_bar_a::bar:15:#abcdef:O:#5a3c7f:x:hex} -{prison_mines_timeleft_bar_a::bar:15:#abcdef:O:#5a3c7f:x:hex2} -``` - - - -
- - - - -## Placeholder Attribute: text - Text - - -This placeholder attribute is for text formatting the placeholder results. The only thing it does is to process the hex, hex2, and debug options. - - -This placeholder attribute can be used with any placeholder, even for placeholders -that have other attributes to format their content. Since this is strictly processing -the hex color codes, it will operate upon the final text output from the other -placeholders. - - - -Example of this attribute's usage is as follows, using descriptions for each parameter. - -`::text:hex:hex2:debug:player=` - - - -- **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. 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. - - - - -
- - - -# Rank Command Placeholders - - -The Rank Commands recognize only two placeholders, but they are not considered part of the standard placeholders. There are also only two placeholders that are recognized and both are case sensitive (must be lower case), and must also include curly braces too. - - -* {player} -* {player_uid} - - -This is mentioned here since these rank command placeholders are not part of all the other placeholders, so as such, it may be difficult to find information for these items. - - - -
- - - - -

Prison Placeholder Command Listing

- -Prison Placeholder Commands - -Example of placeholder command listings - - -

Prison Placeholder Listings

- -Prison Placeholder Listing -Prison Placeholder Listing - -Example of the list of placeholders that is available through **/prison placeholders list**. Please note that this list may evolve as new placeholders are added. Use these commands to get the current listing that is available on your server. - - -

Prison Placeholder Search with Two Search Patterns

- - -Prison Placeholder Search - -This is an example of searching for placeholders using a player's name plus two search patterns: *temp5* and *format*. The term temp5 is the name of a mine and is an example of a the dynamic construction of placeholders, and that you can still perform a search with them. The search patterns can be any String fragment found in either the placeholder, or it's alias. - -If more than one search pattern is provided, then all patters must hit on the same placeholder to be included in the results. They behave as a logical AND relationship. - -A player's is provided, but results do not include any player, rank, or ladder entries. This shows that if a player's name is provide, it is recognized as a player and will not prevent valid hits. - - -The following example shows what the command is like when specifying the player's name, a page numer for the results, and three search parameters: - -``` -/prison placeholders search RoyalCoffeeBeans 1 rankup cost default -``` - -This example shows the current placeholder values for that player, including an example of a bar graph. - -Prison Placeholder Search - - -

Prison Placeholder Listings - All Placeholders

- -Prison Placeholder Listing - -In this contrived example, since all placeholders begin with "prison", this search returns a listing of all placeholders. In this example, using the current Prison v3.2.1-alpha.13 release, it has generated 65 pages of results, at 6 placeholders per page which includes the alias. - -The following shows an example of all placeholders that are active with Prison_v3.2.2-alpha.10.jar. It includes a total of 1,294 placeholders, on 108 pages. This is based upon 4 ladders, 13 ranks, and 41 mines. - - -Prison Placeholder Listing - - - - -

Prison Placeholder Listings

- -Prison Placeholder Listing - - - -
- - -# Chat Placeholders - -There are two major ways a placeholder can be resolved within Prison: through chat or through a placeholder integration. - -Chat based placeholders do not rely on other plugins for them to work. Instead they use the org.bukkit.event.player.AsyncPlayerChatEvent, of which Prison will respond and provide translations to prison related placeholders that it find with the chat message. - -Although no plugin is required for Prison to properly handle chat based placeholders, other plugins may be required to generate their use. Such as EssentialsX's Chat plugin. It provides a way to prefix chat messages with placeholders. - - - -
- - - -# Enabling EssentialX's Chat Placeholders - -Set up the EssentialX's Chat plugin: [Setting up EssentialsX](prison_docs_0xx_setting_up_EssentialsX.md). - -Enabling the chat placeholder just requires editing one line within the `config.yml` file. Search for the keyword **EssentialsChat** in that file, then edit the `format:` tag. For example: - - format: '<{prison_rank_tag}:{DISPLAYNAME}>{MESSAGE}' - -Once setup, restart the server. Or use **/essentials reload**. Do not force all the plugins to be reloaded with a tool such as plugman since Prison (and other plugins) may fail to re-load properly. - - -This will include all placeholders that are active for the player, including the prestige chat prefixes. The only issue is that you cannot control the order of how they will display. - - -It is possible to manually set the order by using the individual placeholders for each rank you want to show. This allows you to omit certain placeholders too. Please see the next section of this document to learn how to set them up. - - -You can preview all of the placeholders with the placeholder search command. - - -``` -/prison placeholder search rank_tag - -/prison placeholder search RoyalCoffeeBeans rank_tag -/prison placeholder search RoyalCoffeeBeans 2 rank_tag -``` - - -Reviewing all placeholder tags - - -The placeholders are interested in are: `prison_rank_tag_pretiges` and `prison_rank_tag_default`. - - -So to set them up in the EsstentialsX Chat prefix would be as follows: - - - format: '<{prison_rank_tag_prestiges}{prison_rank_tag_default}:{DISPLAYNAME}>{MESSAGE}' - - - -

Ladder Specific Placeholders

- -One of the newer features available for placeholders has to do with ladder specific placeholders. This is similar to the mines placeholders but for ladders specifically. These player ladder placeholders are just the same a the player rank, but only for one ladder. The player rank placeholders will return all ranks on all ladders for that placeholder. - -This is an example of specifying the rank tag for both the prestige and default ladder. This ensures the expected order of these two tags, but it will also exclude other tags from other ladders, such as donor ladders or mod ladders. - - format: '<{prison_rank_tag_prestiges}{prison_rt_default}:{DISPLAYNAME}>{MESSAGE}' - - -Use the placeholder tools under `/prison placeholders` for more information and to see what is available for use. - - - -For example, to preview all of the placeholders with the placeholder search command. - - -``` -/prison placeholder search rank_tag - -/prison placeholder search RoyalCoffeeBeans rank_tag -/prison placeholder search RoyalCoffeeBeans 2 rank_tag -``` - - -Reviewing all placeholder tags - - - - -
- - - - -# Enabling HolographicDisplays Placeholders - -Follow directions on how to install and configure the HolographicDisplays plugin. - - -An important detail to realize, is that HolographicDisplays can only use placeholders that related to the server. It cannot access any of the prison placeholders on its own. It needs the help of other plugins to extend it's functionality. - -* [HolographicDisplays Download](https://dev.bukkit.org/projects/holographic-displays) -* [HolographicDisplays' Documentation](https://filoghost.me/docs/holographic-displays) - -* [HolographicExtension](https://www.spigotmc.org/resources/holographicextension.18461/) -* [PlaceholderAPI Setup Details](prison_docs_0xx_setting_up_PlaceholderAPI.md) -* [ProtocolLib](https://www.spigotmc.org/resources/protocollib.1997/) - -The simple directions on how to get everything to work is to download these plugins, and place them all in to your server's plugin directory. There is no need to modify any config files to get them to work with prison. Prison will register all of the internal placeholders with PlaceholderAPI so it knows they are valid and where to find them (where to send them to be resolved). - -The simplest way to create a HolographicDisplay would be to stand where you want one. Then enter the following command: - -``` -/hd create test -``` - -Then on the server file system, open the file: - -``` -plugins\HolographicDisplays\database.yml -``` - -Then edit the file. Keep in mind it is a yml file and must be valid yml. - -This is an example of a holographic sign: - -``` -temp5: - location: world, -99.832, 74.500, 191.215 - lines: - - 'Welcome to Prison Mine: temp5' - - 'Reset Interval: {slowest}%prison_mines_interval_temp5% - {slowest}%prison_mines_interval_formatted_temp5%' - - 'Reset Time Left: {medium}%prison_mines_timeleft_temp5% - {fast}%prison_mtlf_temp5%' - - 'Reset Time Left: {slowest}%prison_mines_timeleft_bar_temp5%' - - 'Reset Count: {medium}%prison_mines_reset_count_temp5%' - - 'Mine Size: {slowest}%prison_mines_size_temp5%' - - 'Blocks Remaining: {slowest}%prison_mr_temp5% {slowest}%prison_mp_temp5%%' - - 'Players in Mine: {slowest}%prison_mines_player_count_temp5%' -``` - -Notice that the prison placeholders are wrapped in the % % escape characters. The prefixed placeholders such as {slowest} and {fast} are for the plugin HolographicExtensions and they control how frequently the placeholders are refreshed. - -This is an example of the above settings, including the bar graph. Notice that the bar graph's properties can be adjusted for both the characters that are used, and the total number of characters (width). See the configuration within the file `/plugins/Prison/config.yml`. -Prison Holographic Displays - - -Once you update and save the database.yml file, you can have HolographicDisaplys reload from the files: - -``` -/hd reload -``` - -The above example will produce a holograph that is too tall and the bottom part will be underground. You can raise it up by manually increasing the **Y** value stored in *location:*. As you raise it up, and save the file, then you use **/hd reload** to refresh. It's also easier to make changes directly to the database.yml file. Repeat until it looks right. - - -One word of warning about editing the yml file, is that it must be valid yml, if not, then it could fail to load, or it may reset to a default file. If you're unsure about the file being proper yml, make sure you save a backup before trying to reload the HolographicDisplays settings. You can also run it through an online yml validator to fix any issues. To find an online yml validator, search for: "online yaml lint" or "online yaml validator". - - - - - -
- - + +### Prison Documentation +[Prison Documents - Table of Contents](prison_docs_000_toc.md) + +## Prison - Placeholder Guide + +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: 2023-09-21* + + +
+ + +# Overview + +Placeholders allow the sharing of data from one plugin with another plugin, and without either plugin knowing anything about each other. + +On the surface they appear to be simple, but there are a lot of moving parts below the surface, and with Prison, there are even more complicated things going on. + +Add in to the mix, that different plugins deal with placeholders in slightly different ways, and you can wind up with a challenge to get them to work under different circumstances. + + +**New Feature!** Custom Placeholders! + +Prison now supports the creation of custom placeholders, which can include any text, with formatting, and any number of placeholders too. Even non-prison placeholders. The benefit of custom placeholders is that you can create complex placeholders in one place, within prison, at any length, and then use them in any of your other plugins such as holographic displays, scoreboards, etc... Prison will expand all placeholders, including from other plugins, and provide the final result. + + +
+ + + + +# Placeholder Commands + + +*Since Prison v3.2.1-alpha.13* + + +There are a few useful commands within prison that will allow you list placeholders, search for placeholders, and to test random text that includes placeholders. + + +Sub-command listing of all placeholders commands: + +* **/prison placeholders** + +> Shows a list of all of the placeholder related commands. + + +* **/prison placeholders list** + +> Lists all placeholders that are available, including their aliases. Placeholders are grouped by their type, of which there are 10 different kinds. Some are player specific, rank or ladder specific, mine specific, or even hybrid combinations such as player-mine were the mine stats are based upon which mine the player is in. + + +* **/prison placeholders search** + +> Provides a simple search for placeholders, optionally using a player's name, and it shows the results with actual live placeholder values. Search values can be one or more word fragments. + + +* **/prison placeholders test** + +> Somewhat like search, but you have to provide the whole placeholder surrounded by escape characcters. Can provide more than one placeholder too. This is more like testing what you would place within a chat prefix or holographic sign. + + +* **/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 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** + +> Reloads and rebuilds all placeholders and then reregisters them. This is performed when adding or removing a new mine or rank. + + + +NOTE: the `/prison placeholders reload` command only reloads and registers the placeholders with the placeholder integrations. This would be required to enable placeholders when adding a new mine, a new rank, or a new ladder. If you reload another plugin, such as papi, you may need to reload the placeholders which will re-register them. Prison has been setup to survive a papi restart, but there could still be issues. + + +NOTE: Information on these command are provided in detail below. + + +
+ + +# Placeholder Types and Counts + +Prison has numerous placeholders, with number of different types. Each of these types have different internal requirements and conditions of usage. This is a high overview of the various types and their counts. + + +* **Total Available Placeholders:** 294 including aliases + + +* **Player Related:** 112 including aliases + * **Rank Related:** 8 including aliases + * **Rankup Related:** 20 including aliases + * **Player Balance Related:** 8 including aliases + * **Player Token Balance Related:** 12 including aliases + * **Player Blocks Totals Related: 4 including aliases + * **Player Tool Related:** 34 including aliases + * **Player Health Related:** 14 including aliases + * **Player XP and Levels Related:** 6 including aliases + * **Player Walk Speed:** 2 including aliases + + +* **Ladders Related:** 34 including aliases **times** each ladder + +> A LADDERS placeholder must include the ladder's name in the placeholder and therefore is static. + +> The ladder based placeholders end with `_laddername`, but they include the following possible prefixes, which may not be exclusive to ladder based placeholders. + +> Ladder placeholder prefixes: + * `prison_rank_` + * `prison_rankup_` + * `prison_player_` + + + +* **Ranks Related:** 24 including aliases **times** each rank + +> A RANKS placeholder needs to specify the Rank name as part of the placeholder. Each placeholder must specify a Rank and is static. + +> The ranks based placeholders end with `_rankname` but do not require a player to work. They also have a prefix of `prison_rank__` but these prefixes and suffixes are also shared with **RankPlayers** placeholders. See them for specifics. + +> Ranks placeholder prefixes: + * `prison_rank__` + + +* **RankPlayers Related:** 12 including aliases **times** each rank + +> A RANKPLAYERS placeholder is one that will change based upon the player's own Rank. Each player could have a different rank. Because of this relationship, these can only be used with instances of players such as scoreboards and chat prefixes; they will not work in holographic displays or with signs. + +> RankPlayers placeholders are very similar to the Rank placeholders in respect to the prefixes and suffixes, but these placeholders MUST include a player or they cannot work. Without a player, they cannot return a valid value, and therefore will return either a blank or zero. + +> What makes these placeholders stand out from rank placeholders is the prefix includes `player_`. For example: + +> RankPlayers placeholder prefixes: + * `prison_rank__player_` + + +> **Performance Warning:** There is a high risk of performance issues when calculating a full GUI page of items that includes the use of placeholders that are based upon the placeholders: `prison_rank__player_cost_rankname`. The reason for this is related to a progressively great number of calculations required to calculate high ranked prestige ranks. The performance impact can include processing and memory usages. + +> For example, if there are 26 default ranks, and the player is at rank A with no prestiges, then to calculate rank P4 would include the following ranks: +b --> z + p1 + a --> z + p2 + a --> z + p3 + a --> z + p4. +This results in a total of 107 ranks that must be collected, then the player's cost for each rank will have to be calculated. Then all of these must be added together to get the player's cost on rank P4. + +> So if there are thousands of prestige ranks, then the calculations will be numerous for each placeholder. + + +* **Player Ladder Balance Related:** 32 including aliases **times** each Mine + + +* **Mines Related:** 28 including aliases **times** each ladder + +> A MINES placeholder must specify the Mine mine as part of the placeholder. + +> The Mines related placeholders have the following prefixes, but they are also shared with the MinePlayers placeholders. +* `prison_mines_` +* `prison_top_mine_` + + + +* **MinePlayers Related:** 32 including aliases + +> A MINEPLAYERS placholder is similar to a RankPlayers placeholder in that it is dynamic and you cannot specify a mine's name with it. How it works, is that it provides the related stats for the mine in which the player is standing in. When the player leaves the mine, then these placeholders returns an empty string value (a blank). + +> The MinePLayers placeholders includ the following prefixes, but they are also similar to the Mines related placeholder too: + * `prison_player_` + * `prison_mines_` + + +* **PLAYERBLOCKS:** 4 including aliases + +> Every block type that a player breaks within a mine is tracked. These provide the stats on those blocks. + + +* **STATSMINES Related:** 18 including aliases + +> These list the blocks within a mine. They are referred to with a `_nnn_` notation where "nnn" is the line number + + +* **STATSRANKS Related:** 6 including aliases + +> Top-n stats for each rank. The rank name must be specified on the placeholder. + + +* **STATSPLAYERS:** 30 including aliases + +> Various placeholders for the top-n ranked players. These are over all ranks. There are a couple of shortcut placehodlders where one placeholders contain multiple fileds for easier usage. + + + +* **ONLY_DEFAULT_OR_PRESTIGES:** 4 including aliases + +> A couple of placeholders that will only include the default and prestige ladder's rank tag name. These are handy such that you only need to use the one, and it will ensure none of the other ladder's ranks will be included. + + + +* **CUSTOM:** Depends upon how many are configured on your server. + +> Custom placeholders allow for the creation of complex text that can include many other placeholders, including their placeholder attributes and other plugin placeholders. The benefit is that when using these in another plugin, you just need to use the short simple placeholder name and it will auto expand everything for you. + + + +
+ + +# Requirements + +There is always more than one way to do things, and the same goes for having more than one way to use placeholders. This documentation, and our test servers, primarily rely on the use of PlaceholderAPI as the core component to making placeholders work. Depending upon other plugins that you may use, they may have other dependencies too. + +**PlaceholderAPI** - [Setting up PlaceholderAPI](prison_docs_0xx_setting_up_PlaceholderAPI.md) - Strongly Suggested if using placeholders. + + +**Holographs** and **Scoreboards** - There are actual a couple of holograph display plugins. Most of the references in this document refer to Holographic Displays, but some of the newer plugins can provide the same functionality, plus many new features. + +Some of example of other holographic plugins are: AnimatedScoreboard, DecentHolograms, Scoreboard Revision, and etc.. + + +
+ + +# Placeholder Theory for Prison + +*(needs updating: Prison now has 10 types of placeholders including top-n variations)* + + +There are few major types of placeholders in prison: Player, Ranks, Ladders, Mines, and Stats based. With the most recent releases of prison, there have been hybrids added that are a combination of the player placeholders and with mines and ranks. For example there are now ladder based placeholder that allow targeting ranks on a specific ladder, instead of all ladders. Also there are player mine placeholders that report on the mine stats for the mine in which the player is physically located in. The player mine placeholders have no value when the player is not in a mine, and they will change as the player goes from mine to mine. + +There are also different types of data that are returned in placeholders. Text, numbers, formatted numbers, and bar graphs. + +The player based placeholders can only report on the player that is initiating the command, or request. These placeholders pertain to the player's attributes, such as rank, next rank, their balance, how more they need before reaching the next rank, and etc. Internally, all of these requests must include the player's UUID, which is why you cannot just add them to a sign, since the sign does not know any player's UUID. + +There are actually two major kinds of player based placeholders; a third type is "related" more to mines and not specifically to the player's ranks. Rank placeholders that returns all of the player's current attributes for all active ladders they are associated with. For example, if they are active on four ladders, then they will have four active ranks on four ladders with possible values. So it may look something like this: `[mod][Zeus][+2][B]`, of which the ladders could be mod, donor, prestige, and default. The thing to remember about player rank placeholders is that they may return more than one value, and you cannot control the order of the values. + +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. + +Prison has integrations for direct use of providing placeholder values to to the other plugins. Some of those other plugins request placeholder values using partial placeholder names. Therefore to improve performance and to prevent having to always reconstructing the full placeholder names, prison precomputes the fragments for all placeholders. Therefore, with our example of 40 mines and 10 placeholders, the actual internal number of placeholder combinations that prison will respond to is 800: 40 mines x 10 placeholders per mine x 2 for aliases = 800 placeholders for prison. + +Off hand this may sound bad, but Prison utilizes enumerations for identifying placeholders, so they may be objects, but they are lightweight and helps ensure placeholders align with the code at compile time. This not only provides better performance, and less memory consumption, but programming errors and typos are caught at compile time and not runtime, so they also provide for a more stable and reliable Prison environment. + +Internally, placeholders within Prison are case insensitive. But Prison uses lower cased placeholder names to register with any placeholder integration. Therefore, although prison may be case insensitive, the placeholder plugins may not recognize the placeholders unless you use them as all lower case names. + +Also, internally, prison only responds to the placeholder name without the escape characters. The escape characters are generally curly braces { }, or percents % %, but may be other characters. All placeholder plugins strip off the escape characters before passing anything to prison. So proper use of placeholders is dependent upon what is being required by your placeholder plugin and may require a mix of escape characters. + +
+ + +# Placeholder Attributes - Customize almost any Prison Placeholder + +*Since Prison v3.2.4-alpha.2* + + +Placeholders within prison can now be dynamically customized without having to make any changes to any configurations. The same placeholder can be used in multiple place, each with different configurations. This is now possible through the use of placeholder attributes and offers a large degree of customization. + + +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=<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. + + + +The following shows how a few placeholder need to have the "minename" replaced with the actual mine's name. For these examples, we will use a mine named **temp5**. + +* **prison_mines_size_minename** - `{prison_mines_size_temp5}` +* **prison_mines_remaining_minename** - `{prison_mines_remaining_temp5}` +* **prison_mines_remaining_bar_minename** - `{prison_mines_remaining_bar_temp5}` +* **prison_mines_timeleft_bar_minename** - `{prison_mines_timeleft_bar_temp5}` + + + +A few Examples using Placeholder Attributes: + +* `{prison_mines_size_temp5::nFormat:#,##0}` - **654,321** +* `{prison_mines_size_temp5::nFormat:#,##0:0:none}` - **654,321** +* `{prison_mines_size_temp5::nFormat:#,##0.00:1:kmg}` - **654.32 k** +* `{prison_mines_size_temp5::nFormat:#,##0:0:kmg}` - **654k** + + +* `{prison_mines_remaining_bar_temp5}` - Normally displays as (no color) + * **>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<** +* `{prison_mines_remaining_bar_temp5::bar:10}` - Using default values, but change length to 10 + * **>>>>>>>>><** +* `{prison_mines_remaining_bar_temp5::bar:10:&2:#:&d:-}` - Change all settings + * **#######---** +* `{prison_mines_timeleft_bar_temp5::bar:40:&2:O:&d:x:debug}` - Enable debug mode for the attribute + * **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: + + +The placeholder: `{prison_mines_timeleft_bar_temp5::bar:40:&2:O:&d:x:debug}` + +The full command: +`/prison placeholders test {prison_mines_timeleft_bar_temp5::bar:40:&2:O:&d:x:debug}` + + +Example of an attribute with debug + +When debug mode is enabled, it will print to the console information about the placeholder attribute, as seen in the above screen print. This could be useful when testing the configuration of placeholder attributes + + +Using the command `/prison placeholders test` should be used to test and perfect the use of the placeholder attributes. + +
+ + + +## Placeholder Attribute: nFormat - Numeric Formats + + +The Numeric Format attribute will only work on placeholders that return plain numbers. If there is a "_format" version of the placeholder, then an attribute will override the default formatting. + +Example of this attribute's usage is as follows, using descriptions for each parameter. + +`::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. Examples of + how the formatting can be used: + * #,### + * #,###.00 + * #,###.00000 + +- **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 the placeholder type that is used. + + * **none**: No display of units. No transformations. + * **kmg**: Uses one character units: kMGTPEZY. Transforms results by + dividing by 1000.0 until value is less than 1000.0, and + each time it increments the unit character. + k=1,000, M=1,000,000 and etc. These are metric SI codes. + * **kmbt**: Uses one character units: KMBTqQsS. Transforms results by + dividing by 1000.0 until value is less than 1000.0, and + each time it increments the unit character. + k=1,000, M=1,000,000 and etc. These are non-standard codes. + * **binary**: Uses a base-two divisor of 1024 along with the units: + KB, MB, GB, TB, PB, EB, ZB, and YB. + + * *Note:* Other unitTypes can be added along with different style of + 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 + 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. 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. + + + +The parameters that are optional do not have to be included, unless another parameter after the optional ones are needed. Then the optional parameter must be supplied and cannot be empty. + + +`{prison_mines_size_temp5::nFormat:#,##0.00:1:kmg}` + + + +Although it is not suggested to include color codes in the formatting of numbers, it may be possible with the addition of the quoting them with single quotes. The following use of **hex2** format works well with testing on a scoreboard that does not support hex colors, and is a way to inject the hex color when it cannot be used directly in the scoreboard configs. + +``` +{prison_mines_size_temp5::nFormat:'#af33ff'#,##0.00:1:kmg:hex} +{prison_mines_size_temp5::nFormat:'#af33ff'#,##0.00:1:kmg:hex2} +``` + + + +
+ + + + +## Placeholder Attribute: bar - Bar Graphs + + +The bar placeholder attribute only works with placeholders with the word bar in them. + + +Example of this attribute's usage is as follows, using descriptions for each parameter. + +`::bar:size:posColor:posSeg:negColor:negSeg:reverse:hex:hex2:debug:player=` + + + +- **bar**: the keyword to identify this attribute. +- **size**: The number of segments to generate. +- **Positive Color**: The color code to use for the positive segments. + Color codes should start with an &. +- **Positive Segment**: The value that will be used for the positive + segment. +- **Negative Color**: The color code to use for the negative segments. + Color codes should start with an &. +- **Negative Segment**: The value that will be used for the negative + segment. + + +- **reverse**: **Optional.** Case sensitive. Non-positional; can be placed anywhere. + When enabled, this will reverse the bar graph. + + +- **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. 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. + + + +The parameters are all optional and if they are not supplied then the default values for the bar graph will be used instead. + +`{prison_mines_remaining_bar_temp5::bar:10}` + +`{prison_mines_remaining_bar_temp5::bar:10:&2:#:&d:-}` + +`{prison_mines_timeleft_bar_temp5::bar:40:&2:O:&d:x:debug}` + + +To use hex color codes within the bar graphs, the plugins that are requesting them, may not always support hex colors. So the options of **hex** and **hex2** are options to provide pre-formatting of the hex colors so that way the hex colors could work with plugins that do not support them. If the use of **hex** does not work, then **hex2** may. + + +Examples of using hex color codes in a bar graph placeholder. Try it first with **hex**, and if that does not work, then try **hex2**. + +``` +{prison_mines_timeleft_bar_a::bar:15:#abcdef:O:#5a3c7f:x:hex} +{prison_mines_timeleft_bar_a::bar:15:#abcdef:O:#5a3c7f:x:hex2} +``` + + + +
+ + + + +## Placeholder Attribute: text - Text + + +This placeholder attribute is for text formatting the placeholder results. The only thing it does is to process the hex, hex2, and debug options. + + +This placeholder attribute can be used with any placeholder, even for placeholders +that have other attributes to format their content. Since this is strictly processing +the hex color codes, it will operate upon the final text output from the other +placeholders. + + + +Example of this attribute's usage is as follows, using descriptions for each parameter. + +`::text:hex:hex2:debug:player=` + + + +- **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. 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. + + + + +
+ + +# Prison's Custom Placeholders + + +Have you ever tried to setup one row in a scoreboard that included three or four placeholders? Did any of them include placeholder attributes? Some scoreboards even impose limits on how many characters you can use in the config settings. + +With Prison's new Custom Placeholders, you can define any number of them within the prison's `config.yml` file, and then use just the custom placeholder's short name. Prison will automatically expand all included placeholders, even non-prison placeholders. + + +
+ +### Custom Placeholder Configurations + +Prison's custom placeholders are defined in the `plugins/Prison/config.yml` file, under the grouping of `placeholder`. + + +```yaml +placeholder: + + # Custom Placeholders: + # They MUST begin with 'prison__', which has two underscores, or they will not work. + # Custom placeholders can have an abbreviated format where it is the placeholder + # with the quoted value, which can be multi-lined. + # The extended format can have additonal settings. The actual placeholder is + # paired with 'placeholder'. + # If the custom placeholder contains non-prison placeholders, then you can set + # the 'papi_expansion' to true. + # If a description is provided, it will be shown within the placeholder listing. + # Note that the use of hex colors will not work with bukkit versions prior to + # spigot 1.14. + custom-placeholders: + prison__chat_prefix: + placeholder: "{prison_rank_tag_default}{prison_rank_tag_prestiges}" + papi_expansion: true + description: "Can use this in your chat prefix. May have to use %% instead of {}." + prison__player_stats: "{prison_rank_tag_default} -> {prison_rankup_rank_tag_default} + {prison_rankup_cost_remaining_bar_default::bar:50:&a:|:&d:|} + {prison_rankup_cost_remaining_formatted_default} needed to rankup" + +# Pre-spigot 1.14: Cannot do RGB colors: + prison__branding_pre_1_14: "&2P&3r&4o &5M&6i&4n&3e&2s" + + prison__branding: "&#e81416P&#ffa500r&#faeb36o + Oc314Mǧde7ib369dn𑋡de&#ac7ad1s" + +``` + + +
+ + +### Custom Placeholders Format - Name + +A custom placeholder is only identified as a custom placeholder by the prefix of it's name. Therefore, all custom placeholders must start with `prison__`. That is two underscores. If it does not have two underscores, it will be ignored. + +The remainder of the custom placeholder's name can be any valid character combination, excluding any white space. We strongly suggest it is kept to alpha-numeric with underscores. But you may be able to use dashes, other symbols, including colons. If you try to use something other than alpha-numeric plus underscores, then do so at your own risk because other plugins, including Prison, may not handle them correctly or successfully. + + +
+ + +#### Custom Placeholders Format - Abbreviated (simple) + +The abbreviated form of a custom placeholder is simply the name of the placeholder, followed by the String value. + +Two examples are as follows, where the first is a one liner, and the other is a multi-line example. + +```yaml +placeholder: + custom-placeholders: + prison__branding: "&2P&3r&4o &5M&6i&4n&3e&2s" + prison__multi_line: "This is a simple example with + no placeholders, but it's on multiple lines + as this placeholder implies." + +``` + +Please note that multi-line String values wraps to the next line, indented two character more than the placeholder's name. + + +
+ + +#### Custom Placeholders Format - Expanded (complex) + +The complex form of a custom placeholder has at least one attribute, and potentially other settings that can expand the functionality of a placeholder. + +**placeholder** attribute - This contains the actual placeholder String value. It can be multiple lines in length, and can have none, or many other placeholders in it. + +**papi_expansion** attribute - Defaults to a value of `false`. If this value is `true`, then after prison expands all prison placeholders, Prison will then have PAPI expand all non-prison placeholders. If a non-prison placeholder is used in the abbreviated placeholders, or if this one is set to `false`, then it will be ignored and you may see it displayed in the final text. + +**description** attribute - This is a description of the custom placeholder, which is optional. It is ONLY displayed in the placeholder listings: `/prison placeholders list` + + +Two examples are as follows, where the first is a one liner, and the other is a multi-line example. + +```yaml +placeholder: + custom-placeholders: + prison__branding: "&2P&3r&4o &5M&6i&4n&3e&2s" + prison__chat_prefix: + placeholder: "{prison_rank_tag_default}{prison_rank_tag_prestiges}: &3{player}:&r" + papi_expansion: true + description: "Can use this in your chat prefix. May have to use %% instead of {}." + +``` + +Please note that multi-line String values wraps to the next line, indented two character more than the placeholder's name. + + +
+ + + +# Prison Command Placeholders - Mines, Ranks, Ladders, and Block Commands + +This document is not intended to cover Prison command placeholders, but within Prison there are many areas where you can setup commands. Each of them have their own set of placeholders. Prison supports many placeholders to allow you to better customize command. + +The commands can contain more than one command. Keep them all on one line, but end each command with a semi-colon: `;`. + + +To see the list of placeholders, most commands have command parameter that will show all of them. This is a list of all of these commands, and their related placeholders. Please run these commands in the console, for yourself, to confirm that there have not been any new updates since this document was last updated. + +Keep in mind that the use of these placeholder are very strict. They include the curly braces, and they must be in case in which they are listed. + +`/ranks command add placeholders` + +**{player} {player_uid} {msg} {broadcast} {title} {actionBar} {inline} {inlinePlayer} {sync} {syncPlayer} {ifPerm:} {ifNotPerm:} {firstJoin} {promote} {demote} {balanceInitial} {balanceFinal} {currency} {originalRankCost} {rankupCost} {ladder} {rank} {rankTag} {targetRank} {targetRankTag}** + +`/ranks ladder command add placeholders` + +**{player} {player_uid} {msg} {broadcast} {title} {actionBar} {inline} {inlinePlayer} {sync} {syncPlayer} {ifPerm:} {ifNotPerm:} {firstJoin} {promote} {demote} {balanceInitial} {balanceFinal} {currency} {originalRankCost} {rankupCost} {ladder} {rank} {rankTag} {targetRank} {targetRankTag}** + +`/mines command add placeholders` + +**{player} {player_uid} {msg} {broadcast} {title} {actionBar} {inline} {inlinePlayer} {sync} {syncPlayer} {ifPerm:} {ifNotPerm:}** + +`/mines blockevent add placeholders` + +**{player} {player_uid} {msg} {broadcast} {title} {actionBar} {inline} {inlinePlayer} {sync} {syncPlayer} {ifPerm:} {ifNotPerm:} {blockName} {mineName} {locationWorld} {locationX} {locationY} {locationZ} {coordinates} {worldCoordinates} {blockCoordinates} {blockChance} {blockIsAir} {blocksPlaced} {blockRemaining} {blocksMinedTotal} {mineBlocksRemaining} {mineBlocksRemainingPercent} {mineBlocksTotalMined} {mineBlocksSize} {blockMinedName} {blockMinedNameFormal} {blockMinedBlockType} {eventType} {eventTriggered} {utilsDecay}** + + + + +#### Prison Command Placeholder Descriptions + + +Detailed information on what exactly each of these placeholders do, is not intended to be a part of this document. But the following is a brief description. + +Additional information on the BlockEvent placeholders can be found in the [BlockEvent documentation](prison_docs_115_using_BlockEvents.md). + +If a placeholder is marked with **Non-Positional**, that means that the placeholder can appear anywhere in the command to trigger the effect. It's non-positional since it's removed when detected, therefore when the command is ran, it will not be encountered. + + +* **{player}** - The player's name. +* **{player_uid}** - The player's UUID. +* **{msg}** - Send a message to the player. The message follows this placeholder. +* **{broadcast}** - Broadcast a message to all players on the server. +* **{title}** - Send a message to the player, but show in the screen's title region. +* **{actionBar}** - Send a message to the player, but show in the action bar. + + +* **{inline}** - Run the command "inline" with the processing of the original prison command, but run as console. **Non-Postional.** +* **{inlinePlayer}** - Run the command "inline" with the processing of the original prison command, but run the command as the player. **Non-Postional.** +* **{sync}** - Submit the command to run in a synchronous thread at the first opportunity. This runs the command as console. Since the command is submitted, it may have to wait behind other tasks. **Non-Postional.** +* **{syncPlayer}** - Submit the command to run in a synchronous thread at the first opportunity. This runs the command as the player; if the player does not have access to run the specified command, then it will fail. Since the command is submitted, it may have to wait behind other tasks. **Non-Postional.** + + +* **{ifPerm:};** - Runs the commands that follows this placeholder, only if the player has the specified permission. NOTE: In order for this to work properly, it must be immediately be followed by a semi-colon so it's treated as it's own "command". +* **{ifNotPerm:};** - Runs the commands that follows this placeholder, but only if the player DOES NOT have the specified permission. NOTE: In order for this to work properly, it must be immediately be followed by a semi-colon so it's treated as it's own "command". + + +* **{firstJoin}** - Runs the commands that follows this placeholder, only if the rankup is based upon first join. This protects the commands that follows from being ran each time when the player hits the specified rank in the future. Example would be Rank A's command such that it runs on first join, but it will not run when the player prestiges and they are set back to A on the default ladder. **Non-Positional.** + + +* **{promote}** - This runs the command only on promotions such as rankup, promote, and setRank. **Non-Positional.** +* **{demote}** - This runs the command only on demotions such as demote. **Non-Positional.**c + +* **{balanceInitial}** - The player's balance before the rankup event was ran. +* **{balanceFinal}** - The player's balance after the rankup event was ran. +* **{targetRank}** - The next rank's name. * **{targetRankTag}** - The next ranks's tag value. +* **{currency}** - If the rank is using a different currency, then this parameter would provide the name of that currency. * **{originalRankCost}** - The rank cost for ranking up, but without the global rank cost multipliers. * **{rankupCost}** - The rank cost for ranking up, including the global rank cost multipliers. * **{ladder}** - The current ladder name. * **{rank}** - The current rank name. * **{rankTag}** - The current rank's tag value. + +* **{blockName}** - The name of the block that was mined. +* **{mineName}** - The mine where the block was mined. +* **{locationWorld}** - The world name where the mine exists. + + + +* **{locationX}** - The **X** coordinates for the broken block. This is an integer value. +* **{locationY}** - The **Y** coordinates for the broken block. This is an integer value. +* **{locationZ}** - The **Z** coordinates for the broken block. This is an integer value. + + +* **{coordinates}** - This provides the X, Y, and Z coordinates for the broken block. These are double values, surrounded by parenthesis and separated by commas. Format: **(X,Y,Z)** Example: `(183.2,88.3792,-3828.248)` +* **{blockCoordinates}** - This is similar to the **{coordinates}** placeholder, except for the use of integer values. Format: **(blockName,world,X,Y,Z)** Example: `(,prisonWorld,183,88,-3828)` +* **{worldCoordinates}** - This combines both the **{locationWorld}** and **{blockCoordinates}** placeholder in to one placeholder. The coordinates are integer values. Format: **(world,X,Y,Z)** Example: `(prisonWorld,183,88,-3828)` + + +* **{blockChance}** - For the block type that was mined, what was the chance of it's spawn rate. +* **{blockIsAir}** - Indicates if the block being processed was AIR. This could be true if an included block within an explosion was already replaced with AIR. +* **{blocksPlaced}** - +* **{blockRemaining}** - +* **{blocksMinedTotal}** - +* **{mineBlocksRemaining}** - +* **{mineBlocksRemainingPercent}** - +* **{mineBlocksTotalMined}** - +* **{mineBlocksSize}** - +* **{blockMinedName}** - +* **{blockMinedNameFormal}** - +* **{blockMinedBlockType}** - +* **{eventType}** - This contains the name of the event that prison is handling. This is an internal event name as specified by Prison. +* **{eventTriggered}** - If Prison was handling a multi-block event, such as an explosion, and if that event supports identifying what triggered it, then this will contain that information. Example could be what enchantment was used to produce the explosion, or the name of the potion, etc. +* **{utilsDecay}** - + + + +This is mentioned here since these rank command placeholders are not part of all the other placeholders, so as such, it may be difficult to find information for these items. + + + +
+ + + + +# Prison Placeholder Command Listing + + +Prison Placeholder Commands + +Example of placeholder command listings + + +

Prison Placeholder Listings

+ +Prison Placeholder Listing +Prison Placeholder Listing + +Example of the list of placeholders that is available through **/prison placeholders list**. Please note that this list may evolve as new placeholders are added. Use these commands to get the current listing that is available on your server. + + +

Prison Placeholder Search with Two Search Patterns

+ + +Prison Placeholder Search + +This is an example of searching for placeholders using a player's name plus two search patterns: *temp5* and *format*. The term temp5 is the name of a mine and is an example of a the dynamic construction of placeholders, and that you can still perform a search with them. The search patterns can be any String fragment found in either the placeholder, or it's alias. + +If more than one search pattern is provided, then all patters must hit on the same placeholder to be included in the results. They behave as a logical AND relationship. + +A player's is provided, but results do not include any player, rank, or ladder entries. This shows that if a player's name is provide, it is recognized as a player and will not prevent valid hits. + + +The following example shows what the command is like when specifying the player's name, a page numer for the results, and three search parameters: + +``` +/prison placeholders search RoyalCoffeeBeans 1 rankup cost default +``` + +This example shows the current placeholder values for that player, including an example of a bar graph. + +Prison Placeholder Search + + +

Prison Placeholder Listings - All Placeholders

+ +Prison Placeholder Listing + +In this contrived example, since all placeholders begin with "prison", this search returns a listing of all placeholders. In this example, using the current Prison v3.2.1-alpha.13 release, it has generated 65 pages of results, at 6 placeholders per page which includes the alias. + +The following shows an example of all placeholders that are active with Prison_v3.2.2-alpha.10.jar. It includes a total of 1,294 placeholders, on 108 pages. This is based upon 4 ladders, 13 ranks, and 41 mines. + + +Prison Placeholder Listing + + + + +

Prison Placeholder Listings

+ +Prison Placeholder Listing + + + +
+ + +# Chat Placeholders + +There are two major ways a placeholder can be resolved within Prison: through chat or through a placeholder integration. + +Chat based placeholders do not rely on other plugins for them to work. Instead they use the org.bukkit.event.player.AsyncPlayerChatEvent, of which Prison will respond and provide translations to prison related placeholders that it find with the chat message. + +Although no plugin is required for Prison to properly handle chat based placeholders, other plugins may be required to generate their use. Such as EssentialsX's Chat plugin. It provides a way to prefix chat messages with placeholders. + + + +
+ + + +# Enabling EssentialX's Chat Placeholders + +Set up the EssentialX's Chat plugin: [Setting up EssentialsX](prison_docs_0xx_setting_up_EssentialsX.md). + +Enabling the chat placeholder just requires editing one line within the `config.yml` file. Search for the keyword **EssentialsChat** in that file, then edit the `format:` tag. For example: + + format: '<{prison_rank_tag}:{DISPLAYNAME}>{MESSAGE}' + +Once setup, restart the server. Or use **/essentials reload**. Do not force all the plugins to be reloaded with a tool such as plugman since Prison (and other plugins) may fail to re-load properly. + + +This will include all placeholders that are active for the player, including the prestige chat prefixes. The only issue is that you cannot control the order of how they will display. + + +It is possible to manually set the order by using the individual placeholders for each rank you want to show. This allows you to omit certain placeholders too. Please see the next section of this document to learn how to set them up. + + +You can preview all of the placeholders with the placeholder search command. + + +``` +/prison placeholder search rank_tag + +/prison placeholder search RoyalCoffeeBeans rank_tag +/prison placeholder search RoyalCoffeeBeans 2 rank_tag +``` + + +Reviewing all placeholder tags + + +The placeholders are interested in are: `prison_rank_tag_pretiges` and `prison_rank_tag_default`. + + +So to set them up in the EsstentialsX Chat prefix would be as follows: + + + format: '<{prison_rank_tag_prestiges}{prison_rank_tag_default}:{DISPLAYNAME}>{MESSAGE}' + + + +

Ladder Specific Placeholders

+ +One of the newer features available for placeholders has to do with ladder specific placeholders. This is similar to the mines placeholders but for ladders specifically. These player ladder placeholders are just the same a the player rank, but only for one ladder. The player rank placeholders will return all ranks on all ladders for that placeholder. + +This is an example of specifying the rank tag for both the prestige and default ladder. This ensures the expected order of these two tags, but it will also exclude other tags from other ladders, such as donor ladders or mod ladders. + + format: '<{prison_rank_tag_prestiges}{prison_rt_default}:{DISPLAYNAME}>{MESSAGE}' + + +Use the placeholder tools under `/prison placeholders` for more information and to see what is available for use. + + + +For example, to preview all of the placeholders with the placeholder search command. + + +``` +/prison placeholder search rank_tag + +/prison placeholder search RoyalCoffeeBeans rank_tag +/prison placeholder search RoyalCoffeeBeans 2 rank_tag +``` + + +Reviewing all placeholder tags + + + + +
+ + + + +# Enabling HolographicDisplays Placeholders + +Follow directions on how to install and configure the HolographicDisplays plugin. + + +An important detail to realize, is that HolographicDisplays can only use placeholders that related to the server. It cannot access any of the prison placeholders on its own. It needs the help of other plugins to extend it's functionality. + +* [HolographicDisplays Download](https://dev.bukkit.org/projects/holographic-displays) +* [HolographicDisplays' Documentation](https://filoghost.me/docs/holographic-displays) + +* [HolographicExtension](https://www.spigotmc.org/resources/holographicextension.18461/) +* [PlaceholderAPI Setup Details](prison_docs_0xx_setting_up_PlaceholderAPI.md) +* [ProtocolLib](https://www.spigotmc.org/resources/protocollib.1997/) + +The simple directions on how to get everything to work is to download these plugins, and place them all in to your server's plugin directory. There is no need to modify any config files to get them to work with prison. Prison will register all of the internal placeholders with PlaceholderAPI so it knows they are valid and where to find them (where to send them to be resolved). + +The simplest way to create a HolographicDisplay would be to stand where you want one. Then enter the following command: + +``` +/hd create test +``` + +Then on the server file system, open the file: + +``` +plugins\HolographicDisplays\database.yml +``` + +Then edit the file. Keep in mind it is a yml file and must be valid yml. + +This is an example of a holographic sign: + +``` +temp5: + location: world, -99.832, 74.500, 191.215 + lines: + - 'Welcome to Prison Mine: temp5' + - 'Reset Interval: {slowest}%prison_mines_interval_temp5% - {slowest}%prison_mines_interval_formatted_temp5%' + - 'Reset Time Left: {medium}%prison_mines_timeleft_temp5% - {fast}%prison_mtlf_temp5%' + - 'Reset Time Left: {slowest}%prison_mines_timeleft_bar_temp5%' + - 'Reset Count: {medium}%prison_mines_reset_count_temp5%' + - 'Mine Size: {slowest}%prison_mines_size_temp5%' + - 'Blocks Remaining: {slowest}%prison_mr_temp5% {slowest}%prison_mp_temp5%%' + - 'Players in Mine: {slowest}%prison_mines_player_count_temp5%' +``` + +Notice that the prison placeholders are wrapped in the % % escape characters. The prefixed placeholders such as {slowest} and {fast} are for the plugin HolographicExtensions and they control how frequently the placeholders are refreshed. + +This is an example of the above settings, including the bar graph. Notice that the bar graph's properties can be adjusted for both the characters that are used, and the total number of characters (width). See the configuration within the file `/plugins/Prison/config.yml`. +Prison Holographic Displays + + +Once you update and save the database.yml file, you can have HolographicDisaplys reload from the files: + +``` +/hd reload +``` + +The above example will produce a holograph that is too tall and the bottom part will be underground. You can raise it up by manually increasing the **Y** value stored in *location:*. As you raise it up, and save the file, then you use **/hd reload** to refresh. It's also easier to make changes directly to the database.yml file. Repeat until it looks right. + + +One word of warning about editing the yml file, is that it must be valid yml, if not, then it could fail to load, or it may reset to a default file. If you're unsure about the file being proper yml, make sure you save a backup before trying to reload the HolographicDisplays settings. You can also run it through an online yml validator to fix any issues. To find an online yml validator, search for: "online yaml lint" or "online yaml validator". + + + + + +
+ + diff --git a/docs/prison_docs_626_configuring_worldguard_regions.md b/docs/prison_docs_626_configuring_worldguard_regions.md index e2f4c368d..145783c2f 100644 --- a/docs/prison_docs_626_configuring_worldguard_regions.md +++ b/docs/prison_docs_626_configuring_worldguard_regions.md @@ -13,7 +13,7 @@ The preferred way is with using **Access by Ranks**, but other alternative techn Please note that work is underway with providing prison based commands to help generate and update WorldGuard regions. So far, they are very flexible with the ability to customize what commands are ran by a series of config settings within the config.yml file. The primary problem is when you need to use WorldEdit command with the regions, since most of them do not allow you to specify the world. So one technique prison is employing is to run the commands through an admin that is online so it behaves as if they have entered the commands themselves. -*Documented updated: 2024-0-21* +*Documented updated: 2024-09-21*
@@ -246,10 +246,12 @@ These reports can become pretty complex, especially if there are many events tha Prison also has a debug mode that allows debugging of an actual block breakage event, and inspects what each plugin does with that event. + You can enable it with: - `/prison debug` (run in console: enables debug mode in prison) - `/mines wand` (run in game: gives your admin charater a mine wand) - `` on a block (sneak click with your right mouse button to trigger the event) +* `/prison debug` (run in console: enables debug mode in prison) +* `/mines wand ` (run in game: gives your admin charater a mine wand) +* `` on a block (sneak click with your right mouse button to trigger the event) + The details will be printed to the console. To turn off Prison's debug mode: `/prison debug` From 7c42c51098e172eaa75fc16b134f4b1e325c4e2c Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 22 Sep 2024 00:10:49 -0400 Subject: [PATCH 195/323] Custom placeholders: Fix an issue with the custom placeholders changes being able to correctly count the aliases in the command `/prison commands list`. --- docs/changelog_v3.3.x.md | 5 ++++- .../mcprison/prison/placeholders/PlaceholderManager.java | 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 00fe8ff1a..6e14541e5 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.19c 2024-09-21 +# 3.3.0-alpha.19c 2024-09-22 + + +* **Custom placeholders: Fix an issue with the custom placeholders changes being able to correctly count the aliases in the command `/prison commands list`.** * **Custom Placeholders: Added support for a more complex custom placeholder where the default is an abbreviated placeholder (simple) and a more complex expanded placeholder where you can set various options such as enable PAPI expansions and adding descriptions.** 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 f9e713dcd..64c1b2072 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 @@ -909,7 +909,7 @@ else if ( count++; totalCount++; - if ( ph.isAlias() ) { + if ( ph.getAlias() != null && ph.getAlias().isAlias() ) { aliases++; totalAliases++; } From d48cf39493b9154fef4e1d2382da24e8e81a22ac Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 22 Sep 2024 00:11:52 -0400 Subject: [PATCH 196/323] WorldGuard Regions: Updated the configs to include placeholders for the world, and updated the code to support it too. --- docs/changelog_v3.3.x.md | 3 + .../prison/mines/commands/MinesCommands.java | 78 ++++++++++++++++--- prison-spigot/src/main/resources/config.yml | 55 ++++++------- 3 files changed, 97 insertions(+), 39 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 6e14541e5..04acb748b 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.19c 2024-09-22 +* **WorldGuard Regions: Updated the configs to include placeholders for the world, and updated the code to support it too.** + + * **Custom placeholders: Fix an issue with the custom placeholders changes being able to correctly count the aliases in the command `/prison commands list`.** 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 0e230288c..7f5833673 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 @@ -36,6 +36,7 @@ import tech.mcprison.prison.commands.Wildcard; import tech.mcprison.prison.internal.CommandSender; import tech.mcprison.prison.internal.Player; +import tech.mcprison.prison.internal.World; import tech.mcprison.prison.internal.block.Block; import tech.mcprison.prison.internal.block.MineResetType; import tech.mcprison.prison.internal.block.PrisonBlock; @@ -5429,11 +5430,13 @@ public void commandWorldGuardRegionsGlobalInfo(CommandSender sender, + "specified and ran from console, it will only list the " + "commands and will not try to run them.") String playerName, @Arg(name = "options", def = "view", - description = "Options: default 'view' [view, run]. The option 'view' will generate the " + description = "Options: default 'view' [view, run, world-name]. The option 'view' will generate the " + "list of commands and display them in the console. The 'run' will submit them " + "to be ran as the player, who must be online. They will be " + "teleported to the mine's spawn point to ensure they are in the correct " - + "world.") @Wildcard String options) { + + "world. If running from console, you must supply the world name, or these " + + "commands cannot be ran from the console." + ) @Wildcard String options) { String cmd = "globalInfo"; @@ -5456,11 +5459,14 @@ public void commandWorldGuardRegionsGlobalDefine(CommandSender sender, + "specified and ran from console, it will only list the " + "commands and will not try to run them.") String playerName, @Arg(name = "options", def = "view", - description = "Options: default 'view' [view, run]. The option 'view' will generate the " + description = "Options: default 'view' [view, run, world-name]. " + + "The option 'view' will generate the " + "list of commands and display them in the console. The 'run' will submit them " + "to be ran as the player, who must be online. They will be " + "teleported to the mine's spawn point to ensure they are in the correct " - + "world.") @Wildcard String options) { + + "world. If running from console, you must supply the world name, or these " + + "commands cannot be ran from the console." + ) @Wildcard String options) { String cmd = "globalDefine"; @@ -5482,11 +5488,13 @@ public void commandWorldGuardRegionsGlobalMobSpawningDeny(CommandSender sender, + "specified and ran from console, it will only list the " + "commands and will not try to run them.") String playerName, @Arg(name = "options", def = "view", - description = "Options: default 'view' [view, run]. The option 'view' will generate the " + description = "Options: default 'view' [view, run, world-name]. The option 'view' will generate the " + "list of commands and display them in the console. The 'run' will submit them " + "to be ran as the player, who must be online. They will be " + "teleported to the mine's spawn point to ensure they are in the correct " - + "world.") @Wildcard String options) { + + "world. If running from console, you must supply the world name, or these " + + "commands cannot be ran from the console. " + ) @Wildcard String options) { String cmd = "globalMobSpawningDeny"; @@ -5494,6 +5502,7 @@ public void commandWorldGuardRegionsGlobalMobSpawningDeny(CommandSender sender, String mineName = "*global*"; + worldGuardRegions( sender, wgSetting, mineName, playerName, options, cmd ); } @@ -5608,20 +5617,40 @@ public void commandWorldGuardRegionsMineAreaSelect(CommandSender sender, } +// public void worldGuardRegions( CommandSender sender, String wbSetting, +// String mineName, String playerName, String options, +// String command ) { +// +// worldGuardRegions(sender, wbSetting, mineName, playerName, options, command, null); +// } + public void worldGuardRegions( CommandSender sender, String wbSetting, - String mineName, String playerName, String options, String command ) { + String mineName, String playerName, String options, + String command ) { PrisonMines pMines = PrisonMines.getInstance(); Mine mine = "*global*".equalsIgnoreCase(mineName) ? null : pMines.getMine( mineName ); Player player = null; boolean run = false; + String world = null; if ( mine == null && !"*global*".equalsIgnoreCase(mineName) ) { sender.sendMessage( "A valid mine name is required. Try again.");; return; } + // First check to make sure the playerName does not contain the world parameter: + if ( playerName != null ) { + Optional wOpt = Prison.get().getPlatform().getWorld( playerName ); + if ( wOpt.isPresent() ) { + // Player name is a world name, so use it: + world = playerName; + playerName = ""; + } + } + + if ( playerName.equalsIgnoreCase("run") ) { if ( sender.isPlayer() ) { @@ -5632,7 +5661,7 @@ public void worldGuardRegions( CommandSender sender, String wbSetting, sender.sendMessage( "A valid player name must be provided if this command is ran from the console."); } } - else if ( playerName.equalsIgnoreCase( "view" ) || options.equalsIgnoreCase( "view" ) ) { + else if ( playerName.equalsIgnoreCase( "view" ) || options.toLowerCase().contains( "view" ) ) { run = false; } else { @@ -5641,11 +5670,28 @@ else if ( playerName.equalsIgnoreCase( "view" ) || options.equalsIgnoreCase( "vi if ( player == null ) { } - if ( options.equalsIgnoreCase( "run" ) ) { + if ( options.toLowerCase().contains( "run" ) ) { run = true; } } + if ( options != null ) { + + // If a world name is supplied, then it should be what's left after you remove any possible + // values for 'view' or 'run'. + String worldName = options.replace("view", "").replace("run", "").trim(); + + if ( worldName != null && worldName.length() > 0 ) { + Optional wOpt = Prison.get().getPlatform().getWorld( worldName ); + if ( wOpt.isPresent() ) { + // Player name is a world name, so use it: + world = worldName; + + // Do not change options... it's not used anymore: + } + } + } + String mode = run ? "Running" : "Viewing"; ChatDisplay display = new ChatDisplay("WorldGuard Region Commands - " + mode); @@ -5668,11 +5714,13 @@ else if ( "*global*".equalsIgnoreCase(mineName) ) { teleportPlayer(player, mine, "spawn"); } - String world = mine != null && !mine.isVirtual() ? + String worldName = mine != null && !mine.isVirtual() ? mine.getWorldName() : + world != null ? world : player != null ? player.getLocation().getWorld().getName() : "world-not-set"; - display.addText( "&3World: &7%s", world ); + + display.addText( "&3World: &7%s", worldName ); display.addText(""); @@ -5684,6 +5732,11 @@ else if ( "*global*".equalsIgnoreCase(mineName) ) { List cmds = new ArrayList<>(); + String worldPlaceholder = worldName.equals("world-not-set") ? "" : + !sender.isPlayer() ? "-w " + worldName : + ""; + + String regionMineName = Prison.get().getPlatform().getConfigString( "prison-mines.world-guard.region-mine.region-mine-name", "prison_mine_{mine}"); String regionGroupPerms = Prison.get().getPlatform().getConfigString( @@ -5708,7 +5761,8 @@ else if ( "*global*".equalsIgnoreCase(mineName) ) { String msg = cmd.replace("{mine-pos1}", minePos1) .replace("{mine-pos2}", minePos2) .replace("{region-mine-name}", regionMineName) - .replace("{region-group-permission}", regionGroupPerms); + .replace("{region-group-permission}", regionGroupPerms) + .replace("{world}", worldPlaceholder); cmds.add( msg ); display.addText( "&4 %s", msg ); diff --git a/prison-spigot/src/main/resources/config.yml b/prison-spigot/src/main/resources/config.yml index 61a72fbfc..84fc36502 100644 --- a/prison-spigot/src/main/resources/config.yml +++ b/prison-spigot/src/main/resources/config.yml @@ -389,55 +389,56 @@ prison-mines: prevent-usage-in-mines: - GoldMine - SampleMineName + world-guard: - WARNING: WorldGuard support is not yet available. Coming soon. + WARNING: WorldGuard may not be fully supported yet. global-region-commands: info: - - '/rg list' - - '/rg info __global__' + - '/rg list {world}' + - '/rg info {world} __global__' define: - - '/rg flag __global__ passthrough deny' + - '/rg flag {world} __global__ passthrough deny' deny-mob-spawning: - - 'rg flag __global__ mob-spawning deny' + - 'rg flag {world} __global__ mob-spawning deny' - '/gamerule doMobSpawning false' mine-region-commands: info: - - '/rg list' - - '/rg info {region-mine-name}' + - '/rg list {world}' + - '/rg info {world} {region-mine-name}' redefine: - '//pos1 {mine-pos1}' - '//pos2 {mine-pos2}' - - '//region redefine {region-mine-name}' + - '//region redefine {world} {region-mine-name}' define: - - '/region define {region-mine-name}' - - '/region addmember {region-mine-name} {region-group-permission}' - - '/region setpriority {region-mine-name} 20' - - '/region flag {region-mine-name} block-break allow' - - '/region flag {region-mine-name} item-pickup allow' - - '/region flag {region-mine-name} exp-drops allow' - - '/region flag {region-mine-name} item-drop allow' + - '/region define {world} {region-mine-name}' + - '/region addmember {world} {region-mine-name} {region-group-permission}' + - '/region setpriority {world} {region-mine-name} 20' + - '/region flag {world} {region-mine-name} block-break allow' + - '/region flag {world} {region-mine-name} item-pickup allow' + - '/region flag {world} {region-mine-name} exp-drops allow' + - '/region flag {world} {region-mine-name} item-drop allow' select: - - '/region select {region-mine-name}' + - '/region select {world} {region-mine-name}' mine-area-region-commands: info: - - '/rg list' - - '/rg info {region-mine-area-name}' + - '/rg list {world}' + - '/rg info {world} {region-mine-area-name}' redefine: - '//pos1 {mine-area-pos1}' - '//pos2 {mine-area-pos2}' - - '/region redefine {region-mine-area-name}' + - '/region redefine {world} {region-mine-area-name}' define: - - '/region define {region-mine-area-name}' - - '/region addmember {region-mine-area-name} {region-group-permission}' - - '/region setpriority {region-mine-area-name} 10' - - '/region flag {region-mine-area-name} block-break deny' - - '/region flag {region-mine-area-name} item-pickup allow' - - '/region flag {region-mine-area-name} exp-drops allow' - - '/region flag {region-mine-area-name} item-drop allow' + - '/region define {world} {region-mine-area-name}' + - '/region addmember {world} {region-mine-area-name} {region-group-permission}' + - '/region setpriority {world} {region-mine-area-name} 10' + - '/region flag {world} {region-mine-area-name} block-break deny' + - '/region flag {world} {region-mine-area-name} item-pickup allow' + - '/region flag {world} {region-mine-area-name} exp-drops allow' + - '/region flag {world} {region-mine-area-name} item-drop allow' select: - - '/region select {region-mine-area-name}' + - '/region select {world} {region-mine-area-name}' region-mine: enable: true From 7e4f5a0795b677a4bfac7d453ffc5a2a92eb4550 Mon Sep 17 00:00:00 2001 From: vicentefelipechile Date: Mon, 23 Sep 2024 14:33:03 -0300 Subject: [PATCH 197/323] Added spanish location --- .../main/resources/lang/core/es_ES.properties | 176 ++++----- .../resources/lang/mines/es_ES.properties | 18 +- .../resources/lang/ranks/es_ES.properties | 343 ++++++++++++++++++ .../resources/lang/sellall/es_ES.properties | 74 ++++ .../resources/lang/spigot/es_ES.properties | 324 +++++++++++++++++ 5 files changed, 827 insertions(+), 108 deletions(-) create mode 100644 prison-core/src/main/resources/lang/ranks/es_ES.properties create mode 100644 prison-core/src/main/resources/lang/sellall/es_ES.properties create mode 100644 prison-core/src/main/resources/lang/spigot/es_ES.properties 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 071440daf..f7ceb5748 100644 --- a/prison-core/src/main/resources/lang/core/es_ES.properties +++ b/prison-core/src/main/resources/lang/core/es_ES.properties @@ -76,137 +76,121 @@ # like to share, please contact a staff member on our Discord server. #Thanks for your contributions! # -messages__version=10 +messages__version=11 messages__auto_refresh=true - core_output__prefix_template=| %1 | &7 -core_output__prefix_template_prison=Prison -core_output__prefix_template_info=Info -core_output__prefix_template_warning=Warning +core_output__prefix_template_prison=Prisión +core_output__prefix_template_info=Información +core_output__prefix_template_warning=Advertencia core_output__prefix_template_error=Error -core_output__prefix_template_debug=Debug +core_output__prefix_template_debug=Depurar core_output__color_code_info=&3 core_output__color_code_warning=&c core_output__color_code_error=&c 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 - +core_output__error_startup_failure=Prisión: (Enviando a System.err debido a falla en el registro de salida): +core_output__error_incorrect_number_of_parameters=Falla en el registro (%1): Número incorrecto de parámetros: [%2] Mensaje en bruto original: [%3] Argumentos: %4 core_text__prefix=&3 -core_text__just_now=just now -core_text__ago=ago -core_text__from_now=from now -core_text__and=and +core_text__just_now=justo ahora +core_text__ago=hace +core_text__from_now=dentro de +core_text__and=y core_text__time_units_prefix_spacer= -core_text__time_units_singular=year,month,week,day,hour,minute,second -core_text__time_units_plural=years,months,weeks,days,hours,minutes,seconds -core_text__time_units_short=y,m,w,d,h,m,s - +core_text__time_units_singular=año,mes,semana,día,hora,minuto,segundo +core_text__time_units_plural=años,meses,semanas,días,horas,minutos,segundos +core_text__time_units_short=a,m,s,d,h,m,s -core_tokens__name_required=Prison Tokens=A player's name is required when used from console. -core_tokens__cannot_view_others_balances=Prison Tokens: You do not have permission to view other player's balances. -core_tokens__view_balance=&3%1 has %2 tokens. -core_tokens__add_invalid_amount=Prison Tokens: Invalid amount: '%1'. Must be greater than zero. -core_tokens__added_amount=&3%1 now has &7%2 &3tokens after adding &7%3&3. -core_tokens__removed_amount=&3%1 now has &7%2 &3tokens after removing &7%3&3. -core_tokens__set_amount=&3%1 now has &7%2 &3tokens. +core_tokens__name_required=Tokens de la Prisión=Se requiere un nombre de jugador cuando se usa desde la consola. +core_tokens__cannot_view_others_balances=Tokens de la Prisión: No tienes permiso para ver los saldos de otros jugadores. +core_tokens__view_balance=&3%1 tiene %2 tokens. +core_tokens__add_invalid_amount=Tokens de la Prisión: Cantidad inválida: '%1'. Debe ser mayor que cero. +core_tokens__added_amount=&3%1 ahora tiene &7%2 &3tokens después de agregar &7%3&3. +core_tokens__removed_amount=&3%1 ahora tiene &7%2 &3tokens después de eliminar &7%3&3. +core_tokens__set_amount=&3%1 ahora tiene &7%2 &3tokens. +core_runCmd__name_required=Se requiere un nombre de jugador válido. +core_runCmd__command_required=Se requiere un comando. -core_runCmd__name_required=A valid player name is required. -core_runCmd__command_required=A command is required. - +core_prison_utf8_test=Привет! Давай поÑмотрим, работает ли? Test 01 # The following are the original messages and they will eventually be replaced. includeError=[%1] tiene un valor inválido. excludeError=[%1] tiene un valor inválido. -cantAsConsole=No puedes realizar esto desde la consola. -missingArgument=The argument [%1] no está definido (no tiene valor predeterminado). +cantAsConsole=No puedes hacer esto como consola. +missingArgument=El argumento [%1] no está definido (no tiene un valor predeterminado). missingFlagArgument=La bandera -%1 no tiene los parámetros requeridos. -undefinedFlagArgument= [%1] para la bandera -%2 no está definido. -internalErrorOccurred=Un error interno ha ocurrido al ejecutar este comando. -noPermission=No tienes los permisos requeridos para ejecutar este comando. +undefinedFlagArgument=El argumento [%1] de la bandera -%2 no está definido. +internalErrorOccurred=Se produjo un error interno al intentar realizar este comando. +noPermission=Le faltan los permisos necesarios para realizar este comando. blockParseError=El parámetro [%1] no es un bloque válido. numberParseError=El parámetro [%1] no es un número. -numberTooLow=El parámetro [%1] debe ser igual o mayor a %2. -numberTooHigh=El parámetro [%1] debe ser igual o menor a %2. -numberRangeError=El parámetro [%1] debe ser igual o mayor a %2 y menor o igual a %3. -tooFewCharacters=El parámetro [%1] debe ser igual o mayor a %2 caracteres. -tooManyCharacters=El parámetro [%1] debe ser igual o menor a %2 caracteres. -playerNotOnline=El jugador %1 no se encuentra conectado. -worldNotFound=El mundo %1 no ha sido encontrado. - - - - - - +numberTooLow=El parámetro [%1] debe ser igual o mayor que %2. +numberTooHigh=El parámetro [%1] debe ser igual o menor que %2. +numberRangeError=El parámetro [%1] debe ser igual o mayor que %2 y menor o igual que %3. +tooFewCharacters=El parámetro [%1] debe tener igual o mayor que %2 caracteres. +tooManyCharacters=El parámetro [%1] debe tener igual o menor que %2 caracteres. +playerNotOnline=El jugador %1 no está en línea. +worldNotFound=El mundo %1 no se encontró. -core_gui__click_to_decrease=&3Click to decrease. -core_gui__click_to_increase=&3Click to increase. -core_gui__click_to_cancel=&3Click to cancel. -core_gui__click_to_close=&3Click to close. -core_gui__click_to_confirm=&3Click to confirm. -core_gui__click_to_delete=&3Click to delete. -core_gui__click_to_disable=&3Click to disable. -core_gui__click_to_edit=&3Click to edit. -core_gui__click_to_enable=&3Click to enable. -core_gui__click_to_open=&3Click to open. +core_gui__click_to_decrease=&3Haz clic para disminuir. +core_gui__click_to_increase=&3Haz clic para aumentar. -core_gui__left_click_to_confirm=&3Left-Click to confirm. -core_gui__left_click_to_reset=&3Left-Click to reset. -core_gui__left_click_to_open=&3Left-Click to open. -core_gui__left_click_to_edit=&3Left-Click to edit. +core_gui__click_to_cancel=&3Haz clic para cancelar. +core_gui__click_to_close=&3Haz clic para cerrar. +core_gui__click_to_confirm=&3Haz clic para confirmar. +core_gui__click_to_delete=&3Haz clic para eliminar. +core_gui__click_to_disable=&3Haz clic para desactivar. +core_gui__click_to_edit=&3Haz clic para editar. +core_gui__click_to_enable=&3Haz clic para habilitar. +core_gui__click_to_open=&3Haz clic para abrir. +core_gui__left_click_to_confirm=&3Haz clic izquierdo para confirmar. +core_gui__left_click_to_reset=&3Haz clic izquierdo para restablecer. +core_gui__left_click_to_open=&3Haz clic izquierdo para abrir. +core_gui__left_click_to_edit=&3Haz clic izquierdo para editar. -core_gui__right_click_to_cancel=&3Right-Click to cancel. -core_gui__right_click_to_delete=&3Right-Click to delete. -core_gui__right_click_to_disable=&3Right-Click to disable. -core_gui__right_click_to_enable=&3Right-Click to enable. -core_gui__right_click_to_toggle=&3Right-Click to toggle. +core_gui__right_click_to_cancel=&3Haz clic derecho para cancelar. +core_gui__right_click_to_delete=&3Haz clic derecho para eliminar. +core_gui__right_click_to_disable=&3Haz clic derecho para desactivar. +core_gui__right_click_to_enable=&3Haz clic derecho para habilitar. +core_gui__right_click_to_toggle=&3Haz clic derecho para alternar. +core_gui__right_click_and_shift_to_delete=&3Haz clic derecho y shift para eliminar. +core_gui__right_click_and_shift_to_disable=&3Haz clic derecho y shift para desactivar. +core_gui__right_click_and_shift_to_toggle=&3Haz clic derecho y shift para alternar. -core_gui__right_click_and_shift_to_delete=&3Right-Click and shift to delete. -core_gui__right_click_and_shift_to_disable=&3Right-Click and shift to disable. -core_gui__right_click_and_shift_to_toggle=&3Right-Click and shift to toggle. - - -core_gui__page_next=&3Next page. -core_gui__page_prior=&3Prior page. +core_gui__page_next=&3Página siguiente. +core_gui__page_prior=&3Página anterior. # Note: The core_gui__page_tools_ messages all use the following placeholders # so you can structure them any way you need to. You not no have to use # any of them, but you can also use all of them. # {first_page} {prior_page} {current_page} {next_page} {last_page} -core_gui__page_tools_close=&3Close -core_gui__page_tools_go_back=&3Go Back -core_gui__page_tools_first_page=&3Prior page: {first_page} of {last_page} -core_gui__page_tools_prior_page=&3Prior page: {prior_page} of {last_page} -core_gui__page_tools_current_page=&3Current page: {current_page} of {last_page} -core_gui__page_tools_next_page=&3Next page: {next_page} of {last_page} -core_gui__page_tools_last_page=&3Last page: {last_page} of {last_page} - - -core_gui__money_earned=&3You earned &a$%1 -core_gui__price=&3Price: %1 -core_gui__confirm=&3Confirm: %1 %2 -core_gui__delay=&3Delay: %1 secs -core_gui__multiplier=&3Multiplier: x %1 -core_gui__value=&3Value: %1 -core_gui__permission=&3Permission: &7%1 -core_gui__prestige_name=&3Prestige name: %1 - - - - +core_gui__page_tools_close=&3Cerrar +core_gui__page_tools_go_back=&3Volver +core_gui__page_tools_first_page=&3Página anterior: {first_page} de {last_page} +core_gui__page_tools_prior_page=&3Página anterior: {prior_page} de {last_page} +core_gui__page_tools_current_page=&3Página actual: {current_page} de {last_page} +core_gui__page_tools_next_page=&3Página siguiente: {next_page} de {last_page} +core_gui__page_tools_last_page=&3Última página: {last_page} de {last_page} + +core_gui__money_earned=&3Ganaste &a$%1 +core_gui__price=&3Precio: %1 +core_gui__confirm=&3Confirmar: %1 %2 +core_gui__delay=&3Retraso: %1 segs +core_gui__multiplier=&3Multiplicador: x %1 +core_gui__value=&3Valor: %1 +core_gui__permission=&3Permiso: &7%1 +core_gui__prestige_name=&3Nombre de prestigio: %1 # For format, the edit codes need to be within []. A number defines the width # and negative numbers will left justify the values with padding. An empty [] @@ -215,9 +199,9 @@ core_gui__prestige_name=&3Prestige name: %1 # Important: Every [] must be paired with a value or it will produce a runtime error: # 'Incorrect number of parameters: [Format specifier %s] core_ranks_topn__player_line_1_header_format=[4] [-18] [-10] [11] [-8] [-12] -core_ranks_topn__player_line_1_header_values=Rank, Player, PreDefRanks, Balance, r-Score, Penalty +core_ranks_topn__player_line_1_header_values=Rango, Jugador, PreDefRanks, Balance, r-Score, Penalización core_ranks_topn__player_line_2_header_format=[4] [-10] [7] [-18] [9] -core_ranks_topn__player_line_2_header_values=Rank, Ranks, r-Score, Player, Balance +core_ranks_topn__player_line_2_header_values=Rango, Rangos, r-Score, Jugador, Balance # For detail_values you can use any of the following placeholders, but they must pair up # with the detail_format's []. @@ -229,6 +213,4 @@ core_ranks_topn__player_line_2_header_values=Rank, Ranks, r-Score, Player, Balan core_ranks_topn__player_line_1_detail_format= [-4] [-18] [-12] [10] [7] [10] core_ranks_topn__player_line_1_detail_values={rankPosition}, {playerName}, {prestigeDefaultRankTagNoColor}, {balanceKmbt}, {rankScore}, {rankScorePenalty} core_ranks_topn__player_line_2_detail_format= [-3] [-10] [7] [-18] [9] -core_ranks_topn__player_line_2_detail_values={rankPosition}, {prestigeDefaultRankTagNoColor}, {rankScore}, {playerName}, {balanceKmbt} - - +core_ranks_topn__player_line_2_detail_values={rankPosition}, {prestigeDefaultRankTagNoColor}, {rankScore}, {playerName}, {balanceKmbt} \ No newline at end of file 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 cc91e67e4..dcf8181ba 100644 --- a/prison-core/src/main/resources/lang/mines/es_ES.properties +++ b/prison-core/src/main/resources/lang/mines/es_ES.properties @@ -63,10 +63,6 @@ messages__version=5 messages__auto_refresh=true - - -# The following are the original messages and they will eventually be replaced. - reset_warning=&7Todas las minas %1 se reiniciarán en &3%2&7. reset_message=&7Todas las minas %1 han sido reiniciadas. skip_reset_message= @@ -99,10 +95,10 @@ block_deleted=&7Se ha eliminado el bloque &3%1 &7de la mina &3%2&7. mine_redefined=&7Se ha &3redefinido &7la mina exitosamente. missing_world=&7El mundo en el que se ha creado la mina no se ha podido encontrar. -mines_mtp__unable_to_teleport=Sorry. You're unable to teleport there. -mines_mtp__unable_to_teleport_others=&3You cannot teleport other players to a mine. Ignoring parameter. -mines_mtp__no_target_mine_found=No target mine found. &3Resubmit teleport request with a mine name. -mines_mtp__player_must_be_in_game=You can only teleport players that are online and in the game. -mines_mtp__player_must_be_in_game=&3Specified player is not in the game so they cannot be teleported. -mines_mtp__cannot_use_virtual_mines=&cInvalid option. This mine is a virtual mine&7. Use &a/mines set area &7to enable the mine. -mines_mtp__teleport_failed=&3Teleport failed. Are you sure you're a Player? +mines_mtp__unable_to_teleport=Lamentablemente, no puedes teletransportarte allí. +mines_mtp__unable_to_teleport_others=&3No puedes teletransportar a otros jugadores a una mina. Ignorando parámetro. +mines_mtp__no_target_mine_found=No se ha encontrado una mina objetivo. &3Vuelve a enviar la solicitud de teletransporte con un nombre de mina. +mines_mtp__player_must_be_in_game=Sólo puedes teletransportar a jugadores que estén en línea y en el juego. +mines_mtp__player_must_be_in_game=&3El jugador especificado no está en el juego, por lo que no se puede teletransportar. +mines_mtp__cannot_use_virtual_mines=&cOpción inválida. Esta mina es una mina virtual&7. Utiliza &a/mines set area &7para habilitar la mina. +mines_mtp__teleport_failed=&3Fallo en el teletransporte. ¿Estás seguro de que eres un jugador? \ No newline at end of file diff --git a/prison-core/src/main/resources/lang/ranks/es_ES.properties b/prison-core/src/main/resources/lang/ranks/es_ES.properties new file mode 100644 index 000000000..077a4aaf7 --- /dev/null +++ b/prison-core/src/main/resources/lang/ranks/es_ES.properties @@ -0,0 +1,343 @@ + # NOTE: A messages__version is an arbitrary integer that will be manually incremented within Prison +# when there are changes to these messages. This value represents when message content is +# changed, fixed, or added to. This value may not be increased if the change is very small and +# insignificant, such as a space or a couple of letters. +# +# messages__auto_refresh=true indicates that this file will automatically be replaced if +# Prison detects a messages__version difference. The old file will be deleted (renamed) and +# a new copy will be placed in the directory to be used. If this value is set to false, then +# Prison will not refresh this file and there could be issues with the display of other messages. +# If auto refresh is set to false, we are not held responsible for possible issues that can +# arise from inaccurate messages. If set to false, then you are responsible for maintaining +# the messages on your own. +# +# If you make changes to this file, and you have messages__auto_refresh=false, then those +# changes will be replaced when this file is updated. Since the old file is renamed, and +# not deleted, you can manually merge your changes back in to the new update. The old +# renamed files will never be deleted by prison; you can remove them when you feel like it +# is safe to do so. +# +# 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 +# like to share, please contact a staff member on our Discord server. +#Thanks for your contributions! +# + +## +## Prison Supports Unicode (UTF-8) encoding in these properties files. BUt you must +## follow these instructions to ensure everything works properly. +## +## 1. You should only edit these files using a UTF-8 editor. On windows use NotePad, not WordPad. +## WordPad will save as plain text. To confirm the save was successful: save, close the editor, +## then reopen to confirm the encoding was preserved. +## +## 2. When running on Windows, you must enable utf-8 encoding in minecraft's console. Windows +## defaults to a characterpage 1252. To enable window's use of utf-8, you need to change the +## encoding prior to launching spigot/paper: +## chcp 65001 +## +## Full example of a windows script, which hooks for java debugging: +## rem Note: chcp 65001 enables utf-8 in windows, when normally windows uses characterpage 1252 +## chcp 65001 +## java -Dfile.encoding="UTF-8" -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 -Xms1g -Xmx4g -jar spigot-1.8.8.jar nogui --log-strip-color +## pause +## +## 3. When viewing the logs/latest.log files you must use an editor such as NotePad instead of WordPad. +## +## 4. Unicode is properly displayed in game, in console, in the logs, and with paste.helpch.at when using +## /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. +# +# NOTE: You can add line feeds to your messages by inserting the placeholder '{br}'. +# + +## NOTE: Prison now supports the use of secondary placeholders on all "player" related messages. +## Just add these placeholders, in any position, combination, or quantity, to any +## message's text. +## {player} {rank_default} {rank_tag_default} {rank_next_default} {rank_next_tag_default} +## {rank_prestiges} {rank_tag_prestiges} {rank_next_prestiges} {rank_next_tag_prestiges} +## Player based messages are generally messages sent to player. Not all messages are able +## to support these secondary placeholders; if you find one that is not supported, please +## contact RoyalBlueRanger in a support thread on the Prison discord server and I may +## be able to enable them. + + +messages__version=29 +messages__auto_refresh=true + +ranks_rankup__rankup_no_player_name=Tienes +ranks_rankup__rankup_no_player_name_broadcast=Alguien +ranks_rankup__rankup_you_are=Tú eres +ranks_rankup__rankup_success=¡Felicidades! %1 subió de rango a '%2'. %3 +ranks_rankup__demote_success=Desafortunadamente, %1 ha sido degradado a rango '%2'. %3 +ranks_rankup__log_rank_change=%1 inició el cambio de rango: %2 +ranks_rankup__rankup_cant_afford=¡No tienes suficiente dinero para subir de rango! El siguiente rango cuesta %1%2. +ranks_rankup__rankup_lowest=%1 ya está en el rango más bajo! +ranks_rankup__rankup_highest=%1 ya está en el rango más alto! +ranks_rankup__rankup_failure=Fallo genérico al subir de rango. Revise los detalles de la subida de rango para identificar la razón. +ranks_rankup__rankup_failed_to_load_player=Error al cargar el jugador. +ranks_rankup__rankup_failed_to_load_ladder=Error al cargar la escalera. +ranks_rankup__rankup_failed_to_assign_rank=Error al asignar un rango. Revise los detalles de la subida de rango para identificar la razón. +ranks_rankup__rankup_failed_to_assign_rank_with_refund=Error al asignar un rango. Revise los detalles de la subida de rango para identificar la razón. Se han aplicado reembolsos. +ranks_rankup__rankup_failed_to_save_player_file=Error al recuperar o escribir datos. Sus archivos pueden estar dañados. Alerta a un administrador del servidor. +ranks_rankup__rankup_no_ranks=No hay rangos en esta escalera. +ranks_rankup__rankup_rank_does_not_exist=El rango %1 no existe en este servidor. +ranks_rankup__rankup_rank_is_not_in_ladder=El rango %1 no existe en la escalera %2. +ranks_rankup__rankup_currency_is_not_supported=La moneda, %1, no es compatible con ninguna economía cargada. +ranks_rankup__rankup_ladder_removed=La escalera %1 fue eliminada. +ranks_rankup__rankup_failure_removing_ladder=La subida de rango falló porque el jugador no pudo ser eliminado de la escalera %1. (Los jugadores no pueden ser eliminados de la escalera 'default'). +ranks_rankup__rankup_in_progress_failure=La subida de rango no pudo completarse normalmente. No se estableció ningún estado. + +ranks_rankup__rankup_failure_to_get_rankplayer=¡No existes! El servidor no tiene registros tuyos. Intenta unirte de nuevo, o contacta a un administrador del servidor para obtener ayuda. +ranks_rankup__rankup_failure_invalid_ladder=La escalera '%1' no existe. +ranks_rankup__rankup_failure_must_be_online_player=&3Debes ser un jugador en el juego para ejecutar este comando, y/o el jugador debe estar en línea. +ranks_rankup__no_permission=Necesitas el permiso '%1' para subir de rango en esta escalera. +ranks_rankup__cannot_run_from_console=&7No se puede ejecutar la subida de rango desde la consola. Consulta &3/rankup help&7. +ranks_rankup__invalid_player_name=&7Nombre de jugador no válido. '%1' +ranks_rankup__internal_failure=&7Modo de subida de rango no válido. Fallo interno. Por favor, informa. +ranks_rankup__error_no_default_ladder=&c[ERROR] ¡No hay una escalera predeterminada! ¡Por favor, informa esto a un administrador! +ranks_rankup__error_no_lower_rank=&c[ERROR] ¡No se puede obtener el rango más bajo! ¡Por favor, informa esto a un administrador! + +ranks_rankup__error_no_ladder=&c[ERROR] ¡La escalera %1 no existe! ¡Por favor, informa esto a un administrador! +ranks_rankup__error_no_lower_rank_on_ladder=&c[ERROR] ¡La escalera %1 no tiene rangos! ¡Por favor, informa esto a un administrador! + +ranks_rankup__error_player_not_on_default_ladder=&c[ERROR] El jugador no está en la escalera predeterminada. Jugador: %1 +ranks_rankup__not_at_last_rank=&c¡No estás en el último rango! +ranks_rankup__at_last_rank=&c¡Estás en el último rango! +ranks_rankup__not_able_to_prestige=&7[&3Lo siento&7] &3No pudiste &6Prestigiar! +ranks_rankup__not_able_to_reset_rank=&7No se puede restablecer tu rango en la escalera predeterminada. + +ranks_rankup__balance_set_to_zero=&7Tu saldo se ha establecido en cero. +ranks_rankup__prestige_successful=&7[&3Felicidades&7] &3Has &6Prestigiado&3 a %1&c! +ranks_rankup__prestige_failure=&7[&3Lo siento&7] &3No pudiste &6Prestigiar&3 a %1&c! +ranks_rankup__confirm_prestige_line_1=&3Confirmar Prestigio: %1 +ranks_rankup__confirm_prestige_line_2=&3 Costo: &7%1 +ranks_rankup__confirm_prestige_line_3=&3 Saldo: &7%1%2 +ranks_rankup__confirm_prestige_line_4=&3 El rango predeterminado se restablecerá. +ranks_rankup__confirm_prestige_line_5=&3 El saldo se restablecerá. +ranks_rankup__confirm_prestige_line_6=&3Confirmar con el comando: '&7/prestige %1confirm&3' +ranks_rankup__confirm_prestige_line_7=&3Confirmar haciendo clic en el bloque verde + +ranks_rankup__invalid_charge_value=&3Valor no válido para chargePlayer. Los valores válidos son: %1 %2 +ranks_rankup__invalid_refund_value=&3Valor no válido para refundPlayer. Los valores válidos son: %1 %2 + +ranks_rankutil__failure_internal=Fallo al realizar la comprobación de rankupPlayerInternal, revisa los registros del servidor para ver la traza de la pila: %1 +ranks_rankutil__failure_saving_player_data=Se produjo un error al guardar los archivos de jugador. + +ranks_firstJoinHandler__no_ranks_on_server=¡No hay rangos en el servidor! El nuevo jugador no tiene rango. +ranks_firstJoinHandler__could_not_save_player=No se pudieron guardar los archivos del jugador. +ranks_firstJoinHandler__success=¡Bienvenido! %1 acaba de unirse al servidor y se le asignó el rango predeterminado. + +ranks_prisonRanks__failure_no_economy_status=&cSin plugin de economía +ranks_prisonRanks__failure_no_economy=PrisonRanks.enable() - Falló - No hay un plugin de economía activo - %1 +ranks_prisonRanks__failure_loading_ranks_status=&cError al cargar los archivos de rango: %1 +ranks_prisonRanks__failure_loading_ranks=Error al cargar un archivo de rango. %1 +ranks_prisonRanks__failure_loading_ladders_status=&cError al cargar los archivos de escalera: %1 +ranks_prisonRanks__failure_loading_ladders=Error al cargar un archivo de escalera. %1 +ranks_prisonRanks__failure_loading_players_status=&cError al cargar los archivos de jugador: %1 +ranks_prisonRanks__failure_loading_players=Error al cargar un archivo de jugador. %1 +ranks_prisonRanks__failed_loading_players=&cError al cargar los jugadores: %1 +ranks_prisonRanks__failed_to_load_player_file=Error al cargar un archivo de jugador. %1 + +ranks_prisonRanks__status_loaded_ranks=Se cargaron %1 rangos en total. rangos predeterminados: %2 rangos de prestigio: %3 otros rangos: %4 +ranks_prisonRanks__status_loaded_ladders=Se cargaron %1 escaleras. +ranks_prisonRanks__status_loaded_players=Se cargaron %1 jugadores. + +ranks_prisonRanks__failure_with_ladder=&cError al %1 una nueva escalera de %2, no se pudo encontrar ninguna preexistente. +ranks_prisonRanks__failure_with_ladder_create=crear +ranks_prisonRanks__failure_with_ladder_save=guardar +ranks_prisonRanks__failure_with_ladder_default=predeterminada +ranks_prisonRanks__failure_with_ladder_prestiges=prestigios + +ranks_prisonRanks__added_new_player=&7Prisión: &cNuevo jugador añadido &7a la prisión: &3%1 &7fue encontrado en el servidor. +ranks_prisonRanks__added_and_fixed_players=Cargador de rango de prisión: Se añadieron %1 jugadores a la prisión. Se corrigieron %2 jugadores que no tenían un rango en la escalera predeterminada. + +ranks_rank__failure_loading_ranks=&aError: Cargando Rangos! &7Excepción al analizar documentos de rango. Id de rango= %1 nombre= %2 [%3] + +ranks_rankManager__failure_loading_rankManager=&aError: al cargar la escalera %1 (id de escalera: %2): &7No se pudo cargar el RankManager, por lo que no se puede acceder a ningún rango. +ranks_rankManager__failure_duplicate_rank=&aError: Fallo al cargar la escalera de Rank: El rango '%1' ya estaba vinculado a la escalera '%2', pero se intentó agregar a la escalera '%3'. Este rango no estará vinculado a la escalera '%4' + +ranks_rankManager__remove_rank_warning=Advertencia de eliminación de rango: No existe un rango de respaldo, por lo que los jugadores con el rango que se está eliminando no tendrán ningún rango en esa escalera. +ranks_rankManager__cannot_save_player_file=RemoveRank: No se pudo guardar el archivo del jugador. +ranks_rankManager__player_is_now=El jugador %1 es ahora %2 +ranks_rankManager__cannot_save_ladder_file=RemoveRank: No se pudo guardar la escalera %1. +ranks_rankManager__failure_no_economy=Fallo de economía: &7La moneda &a%1&7 fue registrada con el rango &a%2&7, pero no es compatible con ninguna integración de economía. +ranks_rankManager__ranks_by_ladders=&7Rangos por escaleras: + +ranks_ladderManager__cannot_save_ladder_file=&cLadderManager.saveLadder: No se pudo guardar la escalera. &7%1 &3Error= [&7%2&3]" + +ranks_playerManager__cannot_save_player_file=Se produjo un error al guardar los archivos de jugador: %1 +ranks_playerManager__cannot_add_new_player=PlayerManager.getPlayer(): Error al añadir el nuevo nombre de jugador: %1. %2 +ranks_playerManager__cannot_save_new_player_file=Error al crear un nuevo archivo de datos de jugador para el jugador %1 nombre de archivo de destino: %2 +ranks_playerManager__no_player_name_available= +ranks_playerManager__cannot_load_player_file=No se pudo cargar el jugador: %1 +ranks_playerManager__failed_to_load_economy_currency=Error al cargar la economía para obtener el saldo del jugador %1 con una moneda de %2. +ranks_playerManager__failed_to_load_economy=Error al cargar la economía para obtener el saldo del jugador %1. +ranks_playerManager__last_rank_message_for__prison_rankup_rank_tag_default= + +ranks_commandCommands__command_add_cannot_use_percent_symbols=&7No se pueden usar símbolos de porcentaje como caracteres de escape de marcadores de posición; debe usar { } en su lugar. +ranks_commandCommands__command_add_placeholders=&7Marcadores de posición personalizados para comandos de rango son: &3%1 +ranks_commandCommands__rank_does_not_exist=El rango '%1' no existe. +ranks_commandCommands__command_add_duplicate=El comando duplicado '%1' no se añadió al rango '%2'. +ranks_commandCommands__command_add_success=Se añadió el comando '%1' al rango '%2'. + +ranks_commandCommands__command_remove_sucess=Se eliminó el comando '%1' del rango '%2'. +ranks_commandCommands__command_remove_failed=El rango no contiene ese comando. No se realizó ningún cambio. + +ranks_commandCommands__command_list_contains_none=El rango '%1' no contiene comandos. +ranks_commandCommands__command_list_cmd_header=Comandos de RankUp para el rango %1 +ranks_commandCommands__command_list_click_cmd_to_remove=&8Haz clic en un comando para eliminarlo. +ranks_commandCommands__command_list_click_to_remove=Haz clic para eliminar. +ranks_commandCommands__command_list_add_button=&7[&a+&7] Añadir un nuevo comando +ranks_commandCommands__command_list_add_new_command_tool_tip=&7Añadir un nuevo comando. +ranks_commandCommands__command_row_number_must_be_greater_than_zero=&7Por favor, proporciona un número de fila válido mayor que cero. Fila era=[&b%1&7] +ranks_commandCommands__command_row_number_too_high=&7Por favor, proporciona un número de fila válido no mayor que &b%1&7. Fila era=[&b%2&7] + +ranks_commandCommands__ladder_command_add_placeholders=&7Marcadores de posición personalizados para comandos de escalera son: &3%1 +ranks_commandCommands__ladder_ladder_does_not_exist=La escalera '%1' no existe. +ranks_commandCommands__ladder_command_add_duplicate=El comando duplicado '%1' no se añadió a la escalera '%2'. +ranks_commandCommands__ladder_command_add_success=Se añadió el comando '%1' a la escalera '%2'. + +ranks_commandCommands__ladder_command_remove_sucess=Se eliminó el comando '%1' de la escalera '%2'. +ranks_commandCommands__ladder_command_remove_failed=La escalera no contiene ese comando. No se realizó ningún cambio. + +ranks_commandCommands__ladder_command_list_contains_none=La escalera '%1' no contiene comandos. +ranks_commandCommands__ladder_command_list_cmd_header=Comandos de RankUp para la escalera %1 + +ranks_LadderCommands__ladder_already_exists=Ya existe una escalera con el nombre '%1'. +ranks_LadderCommands__ladder_creation_error=Se produjo un error al crear tu escalera '%1'. &8Consulta la consola para obtener detalles. +ranks_LadderCommands__ladder_created=La escalera '%1' ha sido creada. +ranks_LadderCommands__ladder_could_not_save=No se pudo guardar la escalera. +ranks_LadderCommands__ladder_does_not_exist=La escalera '%1' no existe. +ranks_LadderCommands__rank_does_not_exist=El rango '%1' no existe. +ranks_LadderCommands__ladder_already_has_rank=La escalera '%1' ya contiene el rango '%2'. +ranks_LadderCommands__ladder_added_rank=Se añadió el rango '%1' a la escalera '%2' en la posición %3. +ranks_LadderCommands__ladder_deleted=La escalera '%1' ha sido eliminada. +ranks_LadderCommands__ladder_cannot_delete_default=No puedes eliminar la escalera predeterminada. Es necesaria. +ranks_LadderCommands__ladder_cannot_delete_prestiges=No puedes eliminar la escalera de prestigio. Es necesaria. +ranks_LadderCommands__ladder_cannot_delete_with_ranks=No se puede eliminar una escalera si todavía tiene rangos vinculados a ella. Elimina todos los rangos y vuelve a intentarlo. +ranks_LadderCommands__ladder_error=Se produjo un error al eliminar tu escalera. &8Consulta la consola para obtener detalles. +ranks_LadderCommands__ladder_error_adding=Se produjo un error al añadir un rango a tu escalera. &8Consulta la consola para obtener detalles. +ranks_LadderCommands__ladder_error_removing=Se produjo un error al eliminar un rango de tu escalera. &8Consulta la consola para obtener detalles. +ranks_LadderCommands__ladder_error_saving=Error al guardar la escalera. +ranks_LadderCommands__move_rank_notice=Intentando eliminar el rango especificado de su escalera original, luego se añadirá de nuevo a la escalera de destino en la ubicación especificada. El rango no se perderá. + +ranks_LadderCommands__ladder_has_ranks=&7Esta escalera contiene los siguientes rangos: +ranks_LadderCommands__ladder_default_rank=&b(Rango predeterminado) &7- +ranks_LadderCommands__ladder_see_ranks_list=&3Ver &f/ranks list &b[nombre de la escalera] &3para obtener más detalles sobre los rangos. +ranks_LadderCommands__ladder_has_no_perms=&3La escalera '&7%1&3' no contiene permisos ni grupos de permisos. +ranks_LadderCommands__ladder_set_rank_cost_multiplier=&3La escalera '&7%1&3' se guardó. El multiplicador de costo de rango es ahora [%2]; era [%3]. +ranks_LadderCommands__ladder_rank_cost_multiplier_no_change=&3La escalera '&7%1&3' no se actualizó. El multiplicador de costo de rango suministrado no cambió. [%2] +ranks_LadderCommands__ladder_rank_cost_multiplier_out_of_range=&3El multiplicador de costo de rango está fuera de rango. Debe estar entre -100% y 100%. [%1] +ranks_LadderCommands__ladder_apply_rank_cost_multiplier_no_change=&3La escalera '&7%1&3' no se actualizó. El multiplicador de costo de rango aplicado a esta escalera no cambió. [%2] +ranks_LadderCommands__ladder_apply_rank_cost_multiplier_saved=&3La escalera '&7%1&3' se guardó. La aplicación del multiplicador de costo de rango a esta escalera es ahora [%2]; era [%3]. + +ranks_rankCommands__rank_already_exists=&3El rango llamado &7%1 &3ya existe. Prueba con un nombre diferente. +ranks_rankCommands__rank_name_required=&3Se requiere un nombre de rango y no puede contener códigos de formato. +ranks_rankCommands__ladder_does_not_exist=&3Una escalera con el nombre de '&7%1&3' no existe. +ranks_rankCommands__ladder_has_no_ranks=&3La escalera '&7%1&3' no tiene ningún rango. +ranks_rankCommands__ladder_has_no_ranks_text=&3--- Esta escalera no tiene rangos --- +ranks_rankCommands__rank_does_not_exist=&3El rango '&7%1&3' no existe. +ranks_rankCommands__rank_cannot_be_created=&3No se pudo crear el rango. +ranks_rankCommands__rank_created_successfully=&3Tu nuevo rango, '&7%1&3', fue creado en la escalera '&7%2&3', usando el valor de etiqueta '&7%3&3' +ranks_rankCommands__error_saving_ladder=&3La escalera '&7%1&3' no se pudo guardar en el disco. Comprueba la consola para obtener detalles. +ranks_rankCommands__error_writting_ladder=&3La escalera '&7%1&3' no se pudo guardar en el disco. Comprueba la consola para obtener detalles. + +ranks_rankCommands__auto_config_preexisting_warning=&3Estás intentando ejecutar &7/ranks autoConfigure&3 con rangos o minas ya configurados. Cantidad de rangos = &7%1&3. Cantidad de minas = &7%2&3. Por favor, ejecuta este comando con la palabra clave &7help&3 para obtener más información y otras opciones de personalización: &7/ranks autoConfigure help&3. Es mejor ejecutar este comando desde la &7consola&3 debido al volumen de datos que genera. Añade la opción '&7force&3' para forzar la ejecución de este proceso. Si hay un conflicto con un rango o mina preexistente, este proceso hará todo lo posible para fusionar los nuevos rangos y minas con lo que ya existe. Hay el riesgo de que algo no se fusione correctamente. Al fusionar, todos los bloques serán reemplazados, pero en la consola se imprimirá la lista de bloques originales como referencia si quieres recrearlos. Por favor, haz una copia de seguridad de tu directorio &7plugins/Prison/&3 antes de ejecutar para estar seguro. +ranks_rankCommands__auto_config_force_warning=&a¡Advertencia! &3Ejecutar autoConfigure con &7force&3 habilitado. No se hace responsable si las minas o los rangos chocan. +ranks_rankCommands__auto_config_invalid_options=&3Se detectaron opciones no válidas. {br}Usa %1&3. {br}&3Las opciones restantes desconocidas fueron: [&7%2&3] +ranks_rankCommands__auto_config_skip_rank_warning=&a¡Advertencia! &3El rango &7%1 &3ya existe y se está omitiendo junto con la generación de la mina si está habilitada, junto con todas las demás funciones. + +ranks_rankCommands__auto_config_no_ranks_created=Rangos autoConfigure: No se crearon rangos. +ranks_rankCommands__auto_config_ranks_created=Rangos autoConfigure: Se crearon %1 rangos. +ranks_rankCommands__auto_config_no_rank_cmds_created=Rangos autoConfigure: No se crearon comandos de rango. +ranks_rankCommands__auto_config_ladder_rank_cost_multiplier_info=La escalera 'prestigios' se ha habilitado para aplicar un Multiplicador de Costo de Rango Base del %1 que se aplicará a 'todos' los costos de rango. Este multiplicador se incrementará con cada rango en la escalera. +ranks_rankCommands__auto_config_ladder_rank_cost_multiplier_command_example=El Multiplicador de Costo de Rango Base se puede ajustar o desactivar con el comando: '/ranks ladder rankCostMultiplier +ranks_rankCommands__auto_config_rank_cmds_created=Rangos autoConfigure: Se crearon %1 comandos de rango. + +ranks_rankCommands__auto_config_no_mines_created=Rangos autoConfigure: No se crearon minas. +ranks_rankCommands__auto_config_mines_created=Rangos autoConfigure: Se crearon %1 minas. + +ranks_rankCommands__auto_config_no_linkage=Rangos autoConfigure: No se vincularon minas y no se vincularon rangos. +ranks_rankCommands__auto_config_linkage_count=Rangos autoConfigure: Se vincularon %1 rangos y minas. + +ranks_rankCommands__rank_cannot_remove=No puedes eliminar este rango porque es el único rango en la escalera predeterminada. +ranks_rankCommands__rank_was_removed=El rango '%1' ha sido eliminado con éxito. +ranks_rankCommands__rank_delete_error=El rango '%1' no se pudo eliminar debido a un error. + +ranks_rankCommands__ranks_list_header=&3Rangos en la escalera &7%1 &3 +ranks_rankCommands__ranks_list_ladder_cost_multplier=&3 Multiplicador de Costo de Rango por Rango: &7%1 +ranks_rankCommands__ranks_list_ladder_apply_ranks_cost_multplier=&3 ¿Aplicar multiplicadores de costo de rango globales a este rango? &7%1 +ranks_rankCommands__ranks_list_ladder_edit_cost_multplier=Editar el Multiplicador de Costo de Rango de esta Escalera. + +ranks_rankCommands__ranks_list_click_to_edit=&7Haz clic en el nombre de un rango para ver más información. +ranks_rankCommands__ranks_list_command_count= &cCmds: &3%1 +ranks_rankCommands__ranks_list_currency= &3Moneda: &2%1 +ranks_rankCommands__ranks_list_click_to_view=&7Haz clic para ver la información. +ranks_rankCommands__ranks_list_click_to_view2=&7Haz clic para ver. +ranks_rankCommands__ranks_list_create_new_rank=&7Crear un nuevo rango. +ranks_rankCommands__ranks_list_you_may_try=&8También puedes probar + +ranks_rankCommands__ranks_info_header=Rango %1 +ranks_rankCommands__ranks_info_name=&3Nombre del Rango: &7%1 +ranks_rankCommands__ranks_info_tag=&3Etiqueta del Rango: &7%1 &3Sin formato: &7\Q%2\E +ranks_rankCommands__ranks_info_ladder=&3Escalera: &7%1 +ranks_rankCommands__ranks_info_not_linked_to_mines=&3Este rango no está vinculado a ninguna mina +ranks_rankCommands__ranks_info_linked_mines=&3Minas vinculadas a este rango: %1 +ranks_rankCommands__ranks_info_cost=&3Costo: &7$%1 +ranks_rankCommands__ranks_info_currency=&3Moneda: &7<&a%1&7> +ranks_rankCommands__ranks_info_players_with_rank=&7Jugadores con este rango: %1 +ranks_rankCommands__ranks_info_rank_id=&6ID de Rango: &7%1 +ranks_rankCommands__ranks_info_rank_delete_message=&7[&c-&7] Eliminar +ranks_rankCommands__ranks_info_rank_delete_tool_tip=&7Haz clic para eliminar este rango.\n&cEsta acción no se puede deshacer. + +ranks_rankCommands__rank_set_cost_success=Se ha establecido correctamente el costo del rango '%1' en %2 + +ranks_rankCommands__set_currency_not_specified=Se debe especificar un nombre de moneda, o debe ser 'ninguno'. '%1' no es válido. +ranks_rankCommands__set_currency_no_currency_to_clear=El rango '%1' no tiene una moneda, por lo que no se puede borrar. +ranks_rankCommands__set_currency_cleared=Se ha eliminado correctamente la moneda para el rango '%1'. Este rango ya no tiene una moneda personalizada. +ranks_rankCommands__set_currency_no_active_support=Ninguna economía activa admite la moneda llamada '%1'. +ranks_rankCommands__set_currency_successful=Se ha establecido correctamente la moneda para el rango '%1' en %2 + +ranks_rankCommands__set_tag_invalid=&cEl nombre de la etiqueta debe ser un valor válido. Para eliminar, use un valor de &aninguno&c. +ranks_rankCommands__set_tag_no_change=&cEl nuevo nombre de la etiqueta es el mismo que el anterior. No se ha realizado ningún cambio. +ranks_rankCommands__set_tag_cleared=&cEl nombre de la etiqueta se ha eliminado para el rango %1. +ranks_rankCommands__set_tag_success=&cEl nombre de la etiqueta se ha cambiado a %1 para el rango %2. + +ranks_rankCommands__player_must_be_online=&3Debes ser un jugador en el juego para ejecutar este comando, y/o el jugador debe estar en línea. +ranks_rankCommands__player_ladder_info=&7Escalera: &b%1 &7Rango Actual: &b%2 +ranks_rankCommands__player_ladder_highest_rank= ¡Es el rango más alto! +ranks_rankCommands__player_ladder_next_rank=&7 Próximo rango: &b%1&7 &c$&b%2 +ranks_rankCommands__player_ladder_next_rank_currency=&7 Moneda: &2%1 +ranks_rankCommands__player_balance_default=&7El saldo actual de &b%1 &7es &b%2 +ranks_rankCommands__player_balance_others=&7El saldo actual de &b%1 &7es &b%2 &2%3 +ranks_rankCommands__player_perms_offline=&7 Aviso: &3El jugador está desconectado, por lo que los permisos no están disponibles ni son precisos. +ranks_rankCommands__player_sellall_multiplier=&7 Multiplicador de Venta: &b%1 %2 +ranks_rankCommands__player_not_accurate=&5(&2No Preciso&5) +ranks_rankCommands__player_admin_only=&8[Solo Admin] +ranks_rankCommands__player_past_names=&7Nombres de Jugadores Anteriores y Fecha de Cambio: +ranks_rankCommands__player_perms=&7Permisos de Jugador: +ranks_rankCommands__player_op=&cOP +ranks_rankCommands__player_player=&3Jugador +ranks_rankCommands__player_online=&3En Línea +ranks_rankCommands__player_offline=&3Desconectado +ranks_rankCommands__player_prison_offline_player=&3PrisiónJugadorDesconectado +ranks_rankCommands__player_prison_player=&3PrisiónJugador +ranks_rankCommands__player_no_ranks_found=&3No se encontraron rangos para &c%1 + +ranks_rankCommands__players_invalid_ladder=La escalera '%1' no existe, o no era 'TODOS'. +ranks_rankCommands__players_invalid_action=La acción '%1' es inválida. [jugadores, todos, completo] + +ranks_rankCommands__topn_forced_reload_successful=La recarga forzada de topN fue exitosa. +ranks_rankCommands__topn_forced_reload_failure=La recarga forzada de topN falló. +ranks_rankCommands__topn_debug_saved_success=El modo de depuración topN: todos los datos topN guardados en Prison/data_storage/prisonTopN.json y recargados para estadísticas de rendimiento. \ No newline at end of file diff --git a/prison-core/src/main/resources/lang/sellall/es_ES.properties b/prison-core/src/main/resources/lang/sellall/es_ES.properties new file mode 100644 index 000000000..3b42bef6c --- /dev/null +++ b/prison-core/src/main/resources/lang/sellall/es_ES.properties @@ -0,0 +1,74 @@ +# NOTE: A messages__version is an arbitrary integer that will be manually incremented within Prison +# when there are changes to these messages. This value represents when message content is +# changed, fixed, or added to. This value may not be increased if the change is very small and +# insignificant, such as a space or a couple of letters. +# +# messages__auto_refresh=true indicates that this file will automatically be replaced if +# Prison detects a messages__version difference. The old file will be deleted (renamed) and +# a new copy will be placed in the directory to be used. If this value is set to false, then +# Prison will not refresh this file and there could be issues with the display of other messages. +# If auto refresh is set to false, we are not held responsible for possible issues that can +# arise from inaccurate messages. If set to false, then you are responsible for maintaining +# the messages on your own. +# +# If you make changes to this file, and you have messages__auto_refresh=false, then those +# changes will be replaced when this file is updated. Since the old file is renamed, and +# not deleted, you can manually merge your changes back in to the new update. The old +# renamed files will never be deleted by prison; you can remove them when you feel like it +# is safe to do so. +# +# 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 +# like to share, please contact a staff member on our Discord server. +#Thanks for your contributions! +# + +## +## Prison Supports Unicode (UTF-8) encoding in these properties files. BUt you must +## follow these instructions to ensure everything works properly. +## +## 1. You should only edit these files using a UTF-8 editor. On windows use NotePad, not WordPad. +## WordPad will save as plain text. To confirm the save was successful: save, close the editor, +## then reopen to confirm the encoding was preserved. +## +## 2. When running on Windows, you must enable utf-8 encoding in minecraft's console. Windows +## defaults to a characterpage 1252. To enable window's use of utf-8, you need to change the +## encoding prior to launching spigot/paper: +## chcp 65001 +## +## Full example of a windows script, which hooks for java debugging: +## rem Note: chcp 65001 enables utf-8 in windows, when normally windows uses characterpage 1252 +## chcp 65001 +## java -Dfile.encoding="UTF-8" -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 -Xms1g -Xmx4g -jar spigot-1.8.8.jar nogui --log-strip-color +## pause +## +## 3. When viewing the logs/latest.log files you must use an editor such as NotePad instead of WordPad. +## +## 4. Unicode is properly displayed in game, in console, in the logs, and with paste.helpch.at when using +## /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 + +sellall_function__message=&dEjemplo &7Mensaje + +sellall_spigot_utils__money_earned=&3Has ganado &a$%1 +sellall_spigot_utils__only_sellall_signs_are_enabled=&3Solo puedes vender a través de letreros. El comando está desactivado. +sellall_spigot_utils__rate_limit_exceeded=&3Despacio. Se ha excedido el límite de uso. +sellall_spigot_utils__shop_is_empty=&3Lo siento, esta tienda de sellall está vacía. +sellall_spigot_utils__you_have_nothing_to_sell=&3Lo siento, no tienes nada que vender. + +sellall_spigot_utils__sellall_is_disabled=&3Lo siento, sellall está deshabilitado. +sellall_spigot_utils__sellall_gui_is_disabled=&3Lo siento, el menú de sellall está deshabilitado. \ No newline at end of file diff --git a/prison-core/src/main/resources/lang/spigot/es_ES.properties b/prison-core/src/main/resources/lang/spigot/es_ES.properties new file mode 100644 index 000000000..341787a89 --- /dev/null +++ b/prison-core/src/main/resources/lang/spigot/es_ES.properties @@ -0,0 +1,324 @@ +# NOTE: A messages__version is an arbitrary integer that will be manually incremented within Prison +# when there are changes to these messages. This value represents when message content is +# changed, fixed, or added to. This value may not be increased if the change is very small and +# insignificant, such as a space or a couple of letters. +# +# messages__auto_refresh=true indicates that this file will automatically be replaced if +# Prison detects a messages__version difference. The old file will be deleted (renamed) and +# a new copy will be placed in the directory to be used. If this value is set to false, then +# Prison will not refresh this file and there could be issues with the display of other messages. +# If auto refresh is set to false, we are not held responsible for possible issues that can +# arise from inaccurate messages. If set to false, then you are responsible for maintaining +# the messages on your own. +# +# If you make changes to this file, and you have messages__auto_refresh=false, then those +# changes will be replaced when this file is updated. Since the old file is renamed, and +# not deleted, you can manually merge your changes back in to the new update. The old +# renamed files will never be deleted by prison; you can remove them when you feel like it +# is safe to do so. +# +# 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 +# like to share, please contact a staff member on our Discord server. +#Thanks for your contributions! +# + +## +## Prison Supports Unicode (UTF-8) encoding in these properties files. BUt you must +## follow these instructions to ensure everything works properly. +## +## 1. You should only edit these files using a UTF-8 editor. On windows use NotePad, not WordPad. +## WordPad will save as plain text. To confirm the save was successful: save, close the editor, +## then reopen to confirm the encoding was preserved. +## +## 2. When running on Windows, you must enable utf-8 encoding in minecraft's console. Windows +## defaults to a characterpage 1252. To enable window's use of utf-8, you need to change the +## encoding prior to launching spigot/paper: +## chcp 65001 +## +## Full example of a windows script, which hooks for java debugging: +## rem Note: chcp 65001 enables utf-8 in windows, when normally windows uses characterpage 1252 +## chcp 65001 +## java -Dfile.encoding="UTF-8" -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 -Xms1g -Xmx4g -jar spigot-1.8.8.jar nogui --log-strip-color +## pause +## +## 3. When viewing the logs/latest.log files you must use an editor such as NotePad instead of WordPad. +## +## 4. Unicode is properly displayed in game, in console, in the logs, and with paste.helpch.at when using +## /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 + +## Haga clic para hacer algo +spigot_gui_lore_click_to_add=Haz clic para agregar. +spigot_gui_lore_click_to_add_backpack=Haz clic para agregar una mochila. +#spigot_gui_lore_click_to_cancel=Haz clic para cancelar. +#spigot_gui_lore_click_to_close=Haz clic para cerrar. +#spigot_gui_lore_click_to_confirm=Haz clic para confirmar. +#spigot_gui_lore_click_to_decrease=Haz clic para disminuir. +#spigot_gui_lore_click_to_delete=Haz clic para eliminar. +#spigot_gui_lore_click_to_disable=Haz clic para deshabilitar. +#spigot_gui_lore_click_to_edit=Haz clic para editar. +#spigot_gui_lore_click_to_enable=Haz clic para habilitar. +#spigot_gui_lore_click_to_increase=Haz clic para aumentar. +spigot_gui_lore_click_to_manage_rank=Haz clic para administrar el rango. +#spigot_gui_lore_click_to_open=Haz clic para abrir. +spigot_gui_lore_click_to_rankup=Haz clic para subir de rango. +spigot_gui_lore_click_to_rename=Haz clic para renombrar. +spigot_gui_lore_click_to_select=Haz clic para seleccionar. +spigot_gui_lore_click_to_start_block_setup=Haz clic para agregar un bloque. +spigot_gui_lore_click_to_teleport=Haz clic para teleportar. +spigot_gui_lore_click_to_use=Haz clic para usar. + +## Haga clic izquierdo para hacer algo. +#spigot_gui_lore_click_left_to_confirm=Haz clic izquierdo para confirmar. +#spigot_gui_lore_click_left_to_reset=Haz clic izquierdo para reiniciar. +#spigot_gui_lore_click_left_to_open=Haz clic izquierdo para abrir. +#spigot_gui_lore_click_left_to_edit=Haz clic izquierdo para editar. + +## Haga clic derecho para hacer algo. +#spigot_gui_lore_click_right_to_cancel=Haz clic derecho para cancelar. +#spigot_gui_lore_click_right_to_delete=Haz clic derecho para eliminar. +#spigot_gui_lore_click_right_to_disable=Haz clic derecho para deshabilitar. +#spigot_gui_lore_click_right_to_enable=Haz clic derecho para habilitar. +#spigot_gui_lore_click_right_to_toggle=Haz clic derecho para cambiar. + +## Cambio de turno y haga clic derecho para hacer algo +#spigot_gui_lore_click_right_and_shift_to_delete=Cambio de turno y haz clic derecho para eliminar. +#spigot_gui_lore_click_right_and_shift_to_disable=Cambio de turno y haz clic derecho para deshabilitar. +#spigot_gui_lore_click_right_and_shift_to_toggle=Cambio de turno y haz clic derecho para cambiar. + +## Títulos o nombres de datos. +spigot_gui_lore_backpack_id=ID de la mochila: +spigot_gui_lore_blocks=Bloques: +spigot_gui_lore_blocktype=Tipo de bloque: +spigot_gui_lore_chance=Probabilidad: +spigot_gui_lore_command=Comando: +spigot_gui_lore_currency=Moneda: +#spigot_gui_lore_delay=Retraso: +spigot_gui_lore_id=ID: +spigot_gui_lore_info=Información: +spigot_gui_lore_minename=Nombre de la mina: +#spigot_gui_lore_multiplier=Multiplicador: +spigot_gui_lore_name=Nombre: +spigot_gui_lore_owner=Propietario: +spigot_gui_lore_percentage=Porcentaje: +#spigot_gui_lore_permission=Permiso: +spigot_gui_lore_players_at_rank=Jugadores en rango: +#spigot_gui_lore_prestige_name=Nombre de prestigio: +#spigot_gui_lore_price=Precio: +spigot_gui_lore_radius=Radio: +spigot_gui_lore_rank_tag=Etiqueta de rango: +spigot_gui_lore_reset_time=Tiempos de reinicio: +spigot_gui_lore_size=Tamaño: +spigot_gui_lore_show_item=Mostrar artículo: +spigot_gui_lore_spawnpoint=Punto de aparición: +spigot_gui_lore_volume=Volumen: +#spigot_gui_lore_value=Valor: +spigot_gui_lore_world=Mundo: + +## Acciones simples o estado. +spigot_gui_lore_disabled=Desactivado. +spigot_gui_lore_enabled=Activado. +spigot_gui_lore_locked=¡Bloqueado! +#spigot_gui_lore_next_page=Página siguiente. +#spigot_gui_lore_prior_page=Página anterior. +spigot_gui_lore_rankup=Subir de rango. +spigot_gui_lore_selected=Seleccionado. +spigot_gui_lore_unlocked=Desbloqueado! + +## Descripciones. +spigot_gui_lore_add_backpack_instruction_1=Agrega al menos un elemento +spigot_gui_lore_add_backpack_instruction_2=Si no lo haces, la mochila +spigot_gui_lore_add_backpack_instruction_3=no se guardará. +spigot_gui_lore_prestige_warning_1=El prestigio restablecerá: +spigot_gui_lore_prestige_warning_2=- Rango. +spigot_gui_lore_prestige_warning_3=- Saldo. +spigot_gui_lore_ranks_setup_1=¡No hay rangos! +spigot_gui_lore_ranks_setup_2=Si deseas continuar la configuración. +spigot_gui_lore_ranks_setup_3=Todos los rangos y minas de A a Z se realizarán +spigot_gui_lore_ranks_setup_4=¡Con valores &apredeterminados&3! +spigot_gui_lore_ranks_setup_5=También puedes usar: +spigot_gui_lore_ranks_setup_6=/ranks autoConfigure full ! +spigot_gui_lore_ranks_setup_7=Reemplace X con el precio inicial y +spigot_gui_lore_ranks_setup_8=el multiplicador, precio predeterminado = 50000, multiplicador = 1.5. +spigot_gui_lore_sellall_delay_use_1=Breve retraso antes de usar nuevamente +spigot_gui_lore_sellall_delay_use_2=el comando &3/sellall sell &8. +spigot_gui_lore_set_mine_delay_instruction_1=Establece un retraso de mina +spigot_gui_lore_set_mine_delay_instruction_2=antes de restablecer cuando +spigot_gui_lore_set_mine_delay_instruction_3=llegue a cero bloques. +spigot_gui_lore_show_item_description_1=Este es el artículo +spigot_gui_lore_show_item_description_2=mostrado en la GUI del jugador +spigot_gui_lore_show_item_description_3=o /mines GUI. +spigot_gui_lore_skip_reset_instruction_1=Salta el reinicio si +spigot_gui_lore_skip_reset_instruction_2=no se han extraído suficientes bloques +spigot_gui_lore_skip_reset_instruction_3=. + +## Nombres de botones o descripciones de una sola línea. +spigot_gui_lore_autofeatures_button_description=Gestionar funciones automáticas. +spigot_gui_lore_backpacks_button_description=Gestionar mochilas. +spigot_gui_lore_disable_notifications=Deshabilitar notificaciones. +spigot_gui_lore_enable_radius_mode=Activar el modo de radio. +spigot_gui_lore_enable_within_mode=Activar el modo dentro. +spigot_gui_lore_mines_button_description=Gestionar minas. +spigot_gui_lore_no_multipliers=[!] ¡No hay multiplicadores! +spigot_gui_lore_ranks_button_description=Administrador de GUI de rangos. +spigot_gui_lore_rankup_if_enough_money=Si tienes suficiente dinero. +spigot_gui_lore_sellall_button_description=Gestionar SellAll. +spigot_gui_lore_sellall_edit_info=Editar moneda de SellAll. +spigot_gui_lore_tp_to_mine=Haz clic para teleportar a la mina. + +## Mensajes +spigot_message_missing_permission=¡Lo siento, no tienes permiso para usar eso! +spigot_message_chat_event_time_end=¡Se acabó el tiempo, evento cancelado! +spigot_message_event_cancelled=Evento cancelado. +spigot_message_command_wrong_format=Lo siento, el formato del comando es incorrecto. +spigot_message_console_error=Lo siento, debes ser un jugador para usar eso. + +## Mensajes de escalera +spigot_message_ladder_default_empty=Lo siento, la escalera predeterminada está vacía. + +## Mensajes de minas +spigot_message_mines_disabled=Lo siento, las minas están desactivadas. +spigot_message_mines_name_chat_1=Por favor, escribe el &6mineName &7que te gustaría usar y &6submit&7. +spigot_message_mines_name_chat_2=Escribe &cclose &7para cancelar o espera &c30 segundos&7. +spigot_message_mines_name_chat_cancelled=Renombrar mina &ccerrado&7, ¡nada cambió! +spigot_message_mines_item_show_edit_success=Elemento de muestra de mina editado con éxito. +spigot_message_mines_or_gui_disabled=Lo siento, las minas o las GUI están deshabilitadas. + +## Mensajes de mochila +spigot_message_backpack_cant_own=Lo siento, no puedes tener mochilas. +spigot_message_backpack_delete_error=Lo siento, no se puede eliminar la mochila. +spigot_message_backpack_delete_success=Mochila eliminada con éxito. +spigot_message_backpack_format_error=Lo siento, el formato del comando no es correcto, tal vez falten algunos argumentos. +spigot_message_backpack_limit_decrement_fail=El límite de la mochila no puede ser negativo. +spigot_message_backpack_limit_edit_success=Límite de mochila editado con éxito. +spigot_message_backpack_limit_not_number=Lo siento, el límite de la mochila no es un número. +spigot_message_backpack_limit_reached=Lo siento, no puedes tener más mochilas. +spigot_message_backpack_missing_playername=Lo siento, por favor agrega un nombre de jugador válido. +spigot_message_backpack_resize_success=Si la mochila existe, se redimensionó con éxito. +spigot_message_backpack_size_must_be_multiple_of_9=¡El tamaño de la mochila debe ser un múltiplo de 9 y no exceder 64! + + +## Mensajes de prestigio +spigot_message_prestiges_disabled=Lo siento, los prestigios están desactivados. +spigot_message_prestiges_empty=Lo siento, no hay prestigios. +spigot_message_prestiges_or_gui_disabled=Lo siento, los prestigios o las GUI están deshabilitados. +spigot_message_prestiges_confirm=Confirmar&7: Escribe la palabra &aconfirm&7 para confirmar. +spigot_message_prestiges_cancel=Cancelar&7: Escribe la palabra &ccancel&7 para cancelar, &ctienes 30 segundos. +spigot_message_prestiges_cancelled=Prestigio cancelado. +spigot_message_prestiges_cancelled_wrong_keyword=Prestigio &ccancelado&7, no escribiste la palabra: &aconfirm&7. + +## Mensajes de rangos +spigot_message_ranks_disabled=Lo siento, los rangos están desactivados. +spigot_message_ranks_or_gui_disabled=Lo siento, los rangos o las GUI están deshabilitados. +spigot_message_ranks_tag_chat_rename_1=Por favor, introduce la &6tag &7que te gustaría usar y &6submit&7. +spigot_message_ranks_tag_chat_rename_2=Introduce &cclose &7para cancelar o espera &c30 segundos&7. +spigot_message_ranks_tag_chat_cancelled=Rename tag &ccerrado&7, ¡nada cambió! + +## Mensajes de SellAll +spigot_message_sellall_auto_already_enabled=Sellall AutoSell ya esta habilitado. +spigot_message_sellall_auto_already_disabled=SellAll AutoSell ya esta deshabilitado. +spigot_message_sellall_auto_disabled=AutoSell se ha deshabilitado. +spigot_message_sellall_auto_disabled_cant_use=Lo siento, debes habilitar AutoSell para usar esto. +spigot_message_sellall_auto_enabled=AutoSell se ha habilitado. +spigot_message_sellall_auto_perusertoggleable_enabled=Sellall AutoSell perUserToggleable está habilitado. +spigot_message_sellall_auto_perusertoggleable_disabled=Sellall AutoSell perUserToggleable está deshabilitado. +spigot_message_sellall_auto_perusertoggleable_already_enabled=Sellall AutoSell perUserToggleable ya esta habilitado. +spigot_message_sellall_auto_perusertoggleable_already_disabled=Sellall AutoSell perUserToggleable ya esta deshabilitado. +spigot_message_sellall_boolean_input_invalid=El valor booleano no es válido (los valores válidos son Verdadero o Falso). +spigot_message_sellall_cant_find_item_config=Lo siento, no puedo encontrar tu artículo en la configuración. +spigot_message_sellall_currency_chat_1=&3¡Inicio de la configuración de una nueva moneda para SellAll! +spigot_message_sellall_currency_chat_2=Escribe &ccancel &7para cancelar. +spigot_message_sellall_currency_chat_3=Escribe &3default &7para establecer la moneda predeterminada. +spigot_message_sellall_currency_chat_4=Escribe el &anombre de la moneda &7para establecer la nueva moneda. +spigot_message_sellall_currency_edit_success=Moneda de SellAll editada con éxito. +spigot_message_sellall_currency_not_found=Lo siento, moneda no encontrada. +spigot_message_sellall_hand_disabled=SellAll Hand desactivado con éxito. +spigot_message_sellall_hand_enabled=SellAll Hand habilitado con éxito. +spigot_message_sellall_hand_is_disabled=SellAll Hand está desactivado. +spigot_message_sellall_item_add_success=Artículo agregado con éxito. +spigot_message_sellall_item_already_added=Ya has agregado este artículo, por favor usa el comando de edición en su lugar. +spigot_message_sellall_item_delete_success=Artículo eliminado con éxito. +spigot_message_sellall_item_edit_success=SellAll Item editado con éxito. +spigot_message_sellall_item_id_not_found=Lo siento, nombre de artículo/ID no válido. +spigot_message_sellall_item_missing_name=Agrega el argumento de nombre de artículo/ID por favor. +spigot_message_sellall_item_missing_price=Agrega el argumento de valor de artículo por favor. +spigot_message_sellall_item_not_found=Artículo de SellAll no encontrado en la configuración. +spigot_message_sellall_default_values_success=Valores predeterminados de SellAll establecidos con éxito. +spigot_message_sellall_delay_already_enabled=SellAll Delay ya esta habilitado. +spigot_message_sellall_delay_already_disabled=SellAll Delay ya esta deshabilitado. +spigot_message_sellall_delay_disabled=SellAll Delay deshabilitado con éxito. +spigot_message_sellall_delay_disabled_cant_use=Lo siento, por favor habilita SellAll Delay para usar esto. +spigot_message_sellall_delay_edit_success=Sellall Delay editado con éxito. +spigot_message_sellall_delay_enabled=SellAll Delay habilitado con éxito. +spigot_message_sellall_delay_not_number=El número de SellAll Delay no es válido. +#spigot_message_sellall_delay_wait=Sellall delay is enabled, please slow down. +spigot_message_sellall_gui_disabled=La GUI de SellAll está desactivada. +#spigot_message_sellall_money_earned=You earned &a$ +spigot_message_sellall_multiplier_add_success=SellAll Multiplier añadido con éxito. +spigot_message_sellall_multiplier_are_disabled=Lo siento, los multiplicadores de SellAll están desactivados. +spigot_message_sellall_multiplier_cant_find=Lo siento, no se puede encontrar el multiplicador de SellAll. +spigot_message_sellall_multiplier_delete_success=SellAll Multiplier eliminado con éxito. +spigot_message_sellall_multiplier_disabled=Multiplicadores de SellAll desactivados con éxito. +spigot_message_sellall_multiplier_edit_success=SellAll Multiplier editado con éxito. +#spigot_message_sellall_sell_empty=Sorry, there aren't items in the SellAll shop. +#spigot_message_sellall_sell_nothing_sellable=Sorry but you've nothing to sell. +#spigot_message_sellall_sell_sign_only=You can use SellAll Sell only with Signs. +spigot_message_sellall_sell_sign_notify=Has vendido con éxito a través de un cartel. +spigot_message_sellall_trigger_already_disabled=SellAll Trigger ya esta deshabilitado. +spigot_message_sellall_trigger_already_enabled=SellAll Trigger ya esta habilitado. +spigot_message_sellall_trigger_disabled=SellAll Trigger deshabilitado con éxito. +spigot_message_sellall_trigger_enabled=SellAll Trigger habilitado con éxito. +spigot_message_sellall_trigger_is_disabled=Lo siento, SellAll Trigger está desactivado. +spigot_message_sellall_trigger_item_add_success=Disparador de artículo SellAll añadido con éxito. +spigot_message_sellall_trigger_item_cant_find=Disparador de artículo SellAll no encontrado en la configuración. +spigot_message_sellall_trigger_item_delete_success=Disparador de artículo SellAll eliminado con éxito. +spigot_message_sellall_trigger_item_missing=Agrega el nombre/ID del artículo al comando. + +## Mensajes de GUI +spigot_message_gui_backpack_disabled=No se puede abrir la GUI, las mochilas están desactivadas. +spigot_message_gui_backpack_empty=Lo siento, no hay mochilas que mostrar. +spigot_message_gui_backpack_too_many=Lo siento, hay demasiadas mochilas y la GUI no puede mostrarlas. +spigot_message_gui_close_success=GUI cerrada con éxito. +spigot_message_gui_error=No se puede abrir la GUI, deshabilitada o con error. +spigot_message_gui_error_empty=No se puede abrir la GUI, está vacía. +spigot_message_gui_ladder_empty=Lo siento, no hay escaleras que mostrar. [%1] +spigot_message_gui_ladder_too_many=Lo siento, hay demasiadas escaleras y la GUI no puede mostrarlas. +spigot_message_gui_mines_empty=Lo siento, no hay minas que mostrar. +spigot_message_gui_mines_too_many=Lo siento, hay demasiadas minas para que la GUI las muestre. +spigot_message_gui_prestiges_empty=Lo siento, no hay prestigios que mostrar. +spigot_message_gui_prestiges_too_many=Lo siento, hay demasiados prestigios y la GUI no puede mostrarlos. +spigot_message_gui_ranks_empty=Lo siento, no hay rangos en esta escalera para mostrar. +spigot_message_gui_ranks_rankup_commands_empty=Lo siento, no hay comandos de subida de rango para mostrar. +spigot_message_gui_ranks_rankup_commands_too_many=Lo siento, hay demasiados comandos de subida de rango y la GUI no puede mostrarlos. +spigot_message_gui_ranks_too_many=Lo siento, hay demasiados rangos y la GUI no puede mostrarlos. +spigot_message_gui_reload_success=¡GUI recargada con éxito! +#spigot_message_gui_sellall_disabled=Sorry, SellAll is disabled. +spigot_message_gui_sellall_empty=Lo siento, no hay nada que mostrar. +spigot_message_gui_too_high=Lo siento, pero el valor es demasiado alto (por encima del máximo posible). +spigot_message_gui_too_low_value=Lo siento, pero el valor es demasiado bajo (por debajo del mínimo posible). + + +spigot_blockbreak_mines__mine_is_being_reset__please_wait=La mina %1 se está restableciendo... por favor espera. + +spigot_blockbreak_core__validate_event__your_tool_is_worn_out=&cTu herramienta está desgastada y no se puede usar. + +spigot_auto_manager__inventory_is_full=&c¡ADVERTENCIA! ¡Tu inventario está lleno! +spigot_auto_manager__is_full_dropping_item__ignore__not_useds=&c¡ADVERTENCIA! ¡Tu inventario está lleno y estás dejando caer objetos! +spigot_auto_manager__inventory_is_full_losing_items=&c¡ADVERTENCIA! ¡Tu inventario está lleno y estás perdiendo objetos! + +spigot_minebombs__cooldown_delay=No puedes usar otra Bomba de Mina de Prisión durante %1 segundos. \ No newline at end of file From 8f4507c28a9cec3025a7ba65c0186e5647c22c41 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 24 Sep 2024 04:44:20 -0400 Subject: [PATCH 198/323] Player: the code that gets a player object based upon a name has been altered to address a few issues. --- docs/changelog_v3.3.x.md | 7 +++- .../prison/commands/BaseCommands.java | 36 +++++++++++++++---- .../prison/spigot/SpigotPlatform.java | 19 +++++++--- 3 files changed, 49 insertions(+), 13 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 04acb748b..3cfb7cdeb 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.19c 2024-09-22 +# 3.3.0-alpha.19c 2024-09-24 + + + + +* **Player: the code that gets a player object based upon a name has been altered to address a few issues.** * **WorldGuard Regions: Updated the configs to include placeholders for the world, and updated the code to support it too.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/commands/BaseCommands.java b/prison-core/src/main/java/tech/mcprison/prison/commands/BaseCommands.java index 48de15a3e..fd5ced701 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/commands/BaseCommands.java +++ b/prison-core/src/main/java/tech/mcprison/prison/commands/BaseCommands.java @@ -50,24 +50,46 @@ public Player getPlayer( CommandSender sender, String playerName ) { public Player getPlayer( CommandSender sender, String playerName, UUID uuid ) { Player result = null; - playerName = playerName != null && !playerName.trim().isEmpty() ? - playerName : sender != null ? sender.getName() : null; - - //Output.get().logInfo("RanksCommands.getPlayer :: playerName = " + playerName ); + boolean console = "CONSOLE".equalsIgnoreCase( sender.getName() ); + if ( !console ) { + playerName = sender.getName(); + } if ( playerName != null ) { Optional opt = Prison.get().getPlatform().getPlayer( playerName ); if ( !opt.isPresent() ) { opt = Prison.get().getPlatform().getOfflinePlayer( playerName ); } - if ( !opt.isPresent() ) { - opt = Prison.get().getPlatform().getOfflinePlayer( uuid ); + if ( opt.isPresent() ) { + result = opt.get(); } + } + if ( result == null && uuid != null ) { + Optional opt = Prison.get().getPlatform().getOfflinePlayer( uuid ); if ( opt.isPresent() ) { result = opt.get(); } - } + +// playerName = playerName != null && !playerName.trim().isEmpty() ? +// playerName : sender != null ? sender.getName() : null; +// +// //Output.get().logInfo("RanksCommands.getPlayer :: playerName = " + playerName ); +// +// // Do not try to get the player name if +// if ( playerName != null ) { +// Optional opt = Prison.get().getPlatform().getPlayer( playerName ); +// if ( !opt.isPresent() ) { +// opt = Prison.get().getPlatform().getOfflinePlayer( playerName ); +// } +// if ( !opt.isPresent() ) { +// opt = Prison.get().getPlatform().getOfflinePlayer( uuid ); +// } +// if ( opt.isPresent() ) { +// result = opt.get(); +// } +// +// } return result; } 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 b4d3b033e..d22c14ccd 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 @@ -304,14 +304,23 @@ public boolean saveRankPlayer( RankPlayer rPlayer ) { @Override public Optional getPlayer(String name) { + SpigotPlayer player = null; - org.bukkit.entity.Player playerBukkit = Bukkit.getPlayer(name); - - if ( name != null && playerBukkit != null && !playerBukkit.getName().equalsIgnoreCase( name ) ) { - playerBukkit = null; + if ( !"CONSOLE".equalsIgnoreCase( name ) ) { + + org.bukkit.entity.Player playerBukkit = Bukkit.getPlayer(name); + + if ( name != null && playerBukkit != null && !playerBukkit.getName().equalsIgnoreCase( name ) ) { + playerBukkit = null; + } + + if ( playerBukkit != null ) { + player = new SpigotPlayer( playerBukkit ); + } } - return Optional.ofNullable( playerBukkit == null ? null : new SpigotPlayer(playerBukkit) ); + return Optional.ofNullable( player ); +// return Optional.ofNullable( playerBukkit == null ? null : new SpigotPlayer(playerBukkit) ); // return Optional.ofNullable( // players.stream().filter(player -> player.getName().equalsIgnoreCase( name)).findFirst() From d47a84fdcc5e86390618c8b97d518f902a7fd8e4 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 24 Sep 2024 04:53:53 -0400 Subject: [PATCH 199/323] WorldGuard Regions: Enable the commands to be able to be ran from the console and through online players. Disabled the Mine-Area commands related to the WorldGuard regions because mine areas are not yet implemented. --- docs/changelog_v3.3.x.md | 2 + .../prison/mines/commands/MinesCommands.java | 233 ++++++++++++------ 2 files changed, 163 insertions(+), 72 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 3cfb7cdeb..c03d16fd8 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.19c 2024-09-24 +* **WorldGuard Regions: Enable the commands to be able to be ran from the console and through online players.** +Disabled the Mine-Area commands related to the WorldGuard regions because mine areas are not yet implemented. * **Player: the code that gets a player object based upon a name has been altered to address a few issues.** 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 7f5833673..1c26fb8c6 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 @@ -5332,11 +5332,13 @@ public void commandWorldGuardRegionsMineInfo(CommandSender sender, + "specified and ran from console, it will only list the " + "commands and will not try to run them.") String playerName, @Arg(name = "options", def = "view", - description = "Options: default 'view' [view, run]. The option 'view' will generate the " + description = "Options: default 'view' [view, run, world-name]. The option 'view' will generate the " + "list of commands and display them in the console. The 'run' will submit them " + "to be ran as the player, who must be online. They will be " + "teleported to the mine's spawn point to ensure they are in the correct " - + "world.") @Wildcard String options) { + + "world. If running from console, you must supply the world name, or these " + + "commands cannot be ran from the console. " + ) @Wildcard String options) { String cmd = "mineInfo"; @@ -5357,11 +5359,13 @@ public void commandWorldGuardRegionsMineDefine(CommandSender sender, + "specified and ran from console, it will only list the " + "commands and will not try to run them.") String playerName, @Arg(name = "options", def = "view", - description = "Options: default 'view' [view, run]. The option 'view' will generate the " + description = "Options: default 'view' [view, run, world-name]. The option 'view' will generate the " + "list of commands and display them in the console. The 'run' will submit them " + "to be ran as the player, who must be online. They will be " + "teleported to the mine's spawn point to ensure they are in the correct " - + "world.") @Wildcard String options) { + + "world. If running from console, you must supply the world name, or these " + + "commands cannot be ran from the console. " + ) @Wildcard String options) { String cmd = "mineDefine"; @@ -5381,11 +5385,13 @@ public void commandWorldGuardRegionsMineRedfine(CommandSender sender, + "specified and ran from console, it will only list the " + "commands and will not try to run them.") String playerName, @Arg(name = "options", def = "view", - description = "Options: default 'view' [view, run]. The option 'view' will generate the " + description = "Options: default 'view' [view, run, world-name]. The option 'view' will generate the " + "list of commands and display them in the console. The 'run' will submit them " + "to be ran as the player, who must be online. They will be " + "teleported to the mine's spawn point to ensure they are in the correct " - + "world.") @Wildcard String options) { + + "world. If running from console, you must supply the world name, or these " + + "commands cannot be ran from the console. " + ) @Wildcard String options) { String cmd = "mineRedefine"; @@ -5406,11 +5412,13 @@ public void commandWorldGuardRegionsMineSelect(CommandSender sender, + "specified and ran from console, it will only list the " + "commands and will not try to run them.") String playerName, @Arg(name = "options", def = "view", - description = "Options: default 'view' [view, run]. The option 'view' will generate the " + description = "Options: default 'view' [view, run, world-name]. The option 'view' will generate the " + "list of commands and display them in the console. The 'run' will submit them " + "to be ran as the player, who must be online. They will be " + "teleported to the mine's spawn point to ensure they are in the correct " - + "world.") @Wildcard String options) { + + "world. If running from console, you must supply the world name, or these " + + "commands cannot be ran from the console. " + ) @Wildcard String options) { String cmd = "mineSelect"; @@ -5459,13 +5467,12 @@ public void commandWorldGuardRegionsGlobalDefine(CommandSender sender, + "specified and ran from console, it will only list the " + "commands and will not try to run them.") String playerName, @Arg(name = "options", def = "view", - description = "Options: default 'view' [view, run, world-name]. " - + "The option 'view' will generate the " + description = "Options: default 'view' [view, run, world-name]. The option 'view' will generate the " + "list of commands and display them in the console. The 'run' will submit them " + "to be ran as the player, who must be online. They will be " + "teleported to the mine's spawn point to ensure they are in the correct " + "world. If running from console, you must supply the world name, or these " - + "commands cannot be ran from the console." + + "commands cannot be ran from the console. " ) @Wildcard String options) { String cmd = "globalDefine"; @@ -5507,10 +5514,10 @@ public void commandWorldGuardRegionsGlobalMobSpawningDeny(CommandSender sender, } - @Command(identifier = "mines worldguard region mineAreaInfo", - description = "WorldGuard Regions: info on the mine area's region. " - + "&6NOTE: mine areas have not been added to prison yet, so this will do nothing.", - onlyPlayers = false, permissions = "mines.set") +// @Command(identifier = "mines worldguard region mineAreaInfo", +// description = "WorldGuard Regions: info on the mine area's region. " +// + "&6NOTE: mine areas have not been added to prison yet, so this will do nothing.", +// onlyPlayers = false, permissions = "mines.set") public void commandWorldGuardRegionsMineAreaInfo(CommandSender sender, @Arg(name = "mineName", description = "mine name") String mineName, @Arg(name = "playerName", def = "view", @@ -5519,11 +5526,13 @@ public void commandWorldGuardRegionsMineAreaInfo(CommandSender sender, + "specified and ran from console, it will only list the " + "commands and will not try to run them.") String playerName, @Arg(name = "options", def = "view", - description = "Options: default 'view' [view, run]. The option 'view' will generate the " + description = "Options: default 'view' [view, run, world-name]. The option 'view' will generate the " + "list of commands and display them in the console. The 'run' will submit them " + "to be ran as the player, who must be online. They will be " + "teleported to the mine's spawn point to ensure they are in the correct " - + "world.") @Wildcard String options) { + + "world. If running from console, you must supply the world name, or these " + + "commands cannot be ran from the console. " + ) @Wildcard String options) { String cmd = "mineAreaInfo"; @@ -5534,10 +5543,10 @@ public void commandWorldGuardRegionsMineAreaInfo(CommandSender sender, worldGuardRegions( sender, wgSetting, mineName, playerName, options, cmd ); } - @Command(identifier = "mines worldguard region mineAreaDefine", - description = "WorldGuard Regions: define the mine area's region. " - + "&6NOTE: mine areas have not been added to prison yet, so this will do nothing.", - onlyPlayers = false, permissions = "mines.set") +// @Command(identifier = "mines worldguard region mineAreaDefine", +// description = "WorldGuard Regions: define the mine area's region. " +// + "&6NOTE: mine areas have not been added to prison yet, so this will do nothing.", +// onlyPlayers = false, permissions = "mines.set") public void commandWorldGuardRegionsMineAreaDefine(CommandSender sender, @Arg(name = "mineName", description = "mine name") String mineName, @Arg(name = "playerName", def = "view", @@ -5546,11 +5555,13 @@ public void commandWorldGuardRegionsMineAreaDefine(CommandSender sender, + "specified and ran from console, it will only list the " + "commands and will not try to run them.") String playerName, @Arg(name = "options", def = "view", - description = "Options: default 'view' [view, run]. The option 'view' will generate the " + description = "Options: default 'view' [view, run, world-name]. The option 'view' will generate the " + "list of commands and display them in the console. The 'run' will submit them " + "to be ran as the player, who must be online. They will be " + "teleported to the mine's spawn point to ensure they are in the correct " - + "world.") @Wildcard String options) { + + "world. If running from console, you must supply the world name, or these " + + "commands cannot be ran from the console. " + ) @Wildcard String options) { String cmd = "mineAreaDefine"; @@ -5561,10 +5572,10 @@ public void commandWorldGuardRegionsMineAreaDefine(CommandSender sender, worldGuardRegions( sender, wgSetting, mineName, playerName, options, cmd ); } - @Command(identifier = "mines worldguard region mineAreaRedefine", - description = "WorldGuard Regions: redefine the mine area's region. " - + "&6NOTE: mine areas have not been added to prison yet, so this will do nothing.", - onlyPlayers = false, permissions = "mines.set") +// @Command(identifier = "mines worldguard region mineAreaRedefine", +// description = "WorldGuard Regions: redefine the mine area's region. " +// + "&6NOTE: mine areas have not been added to prison yet, so this will do nothing.", +// onlyPlayers = false, permissions = "mines.set") public void commandWorldGuardRegionsMineAreaRedefine(CommandSender sender, @Arg(name = "mineName", description = "mine name") String mineName, @Arg(name = "playerName", def = "view", @@ -5573,11 +5584,13 @@ public void commandWorldGuardRegionsMineAreaRedefine(CommandSender sender, + "specified and ran from console, it will only list the " + "commands and will not try to run them.") String playerName, @Arg(name = "options", def = "view", - description = "Options: default 'view' [view, run]. The option 'view' will generate the " + description = "Options: default 'view' [view, run, world-name]. The option 'view' will generate the " + "list of commands and display them in the console. The 'run' will submit them " + "to be ran as the player, who must be online. They will be " + "teleported to the mine's spawn point to ensure they are in the correct " - + "world.") @Wildcard String options) { + + "world. If running from console, you must supply the world name, or these " + + "commands cannot be ran from the console. " + ) @Wildcard String options) { String cmd = "mineAreaRedefine"; @@ -5589,10 +5602,10 @@ public void commandWorldGuardRegionsMineAreaRedefine(CommandSender sender, } - @Command(identifier = "mines worldguard region mineAreaSelect", - description = "WorldGuard Regions: select the mine area's region. " - + "&6NOTE: mine areas have not been added to prison yet, so this will do nothing.", - onlyPlayers = false, permissions = "mines.set") +// @Command(identifier = "mines worldguard region mineAreaSelect", +// description = "WorldGuard Regions: select the mine area's region. " +// + "&6NOTE: mine areas have not been added to prison yet, so this will do nothing.", +// onlyPlayers = false, permissions = "mines.set") public void commandWorldGuardRegionsMineAreaSelect(CommandSender sender, @Arg(name = "mineName", description = "mine name") String mineName, @Arg(name = "playerName", def = "view", @@ -5601,11 +5614,13 @@ public void commandWorldGuardRegionsMineAreaSelect(CommandSender sender, + "specified and ran from console, it will only list the " + "commands and will not try to run them.") String playerName, @Arg(name = "options", def = "view", - description = "Options: default 'view' [view, run]. The option 'view' will generate the " + description = "Options: default 'view' [view, run, world-name]. The option 'view' will generate the " + "list of commands and display them in the console. The 'run' will submit them " + "to be ran as the player, who must be online. They will be " + "teleported to the mine's spawn point to ensure they are in the correct " - + "world.") @Wildcard String options) { + + "world. If running from console, you must supply the world name, or these " + + "commands cannot be ran from the console. " + ) @Wildcard String options) { String cmd = "mineAreaSelect"; @@ -5635,13 +5650,17 @@ public void worldGuardRegions( CommandSender sender, String wbSetting, boolean run = false; String world = null; - if ( mine == null && !"*global*".equalsIgnoreCase(mineName) ) { + if ( mine != null ) { + world = mine.getWorldName(); + } + else if ( mine == null && !"*global*".equalsIgnoreCase(mineName) ) { sender.sendMessage( "A valid mine name is required. Try again.");; return; } - // First check to make sure the playerName does not contain the world parameter: - if ( playerName != null ) { + // First check to make sure the playerName does not contain the world parameter, + // but only if world was not set from the mine name. + if ( world == null && playerName != null ) { Optional wOpt = Prison.get().getPlatform().getWorld( playerName ); if ( wOpt.isPresent() ) { // Player name is a world name, so use it: @@ -5649,34 +5668,7 @@ public void worldGuardRegions( CommandSender sender, String wbSetting, playerName = ""; } } - - - if ( playerName.equalsIgnoreCase("run") ) { - - if ( sender.isPlayer() ) { - run = true; - player = sender.getPlatformPlayer(); - } - else { - sender.sendMessage( "A valid player name must be provided if this command is ran from the console."); - } - } - else if ( playerName.equalsIgnoreCase( "view" ) || options.toLowerCase().contains( "view" ) ) { - run = false; - } - else { - player = getPlayer( sender, playerName ); - - if ( player == null ) { - } - - if ( options.toLowerCase().contains( "run" ) ) { - run = true; - } - } - - if ( options != null ) { - + if ( world == null ) { // If a world name is supplied, then it should be what's left after you remove any possible // values for 'view' or 'run'. String worldName = options.replace("view", "").replace("run", "").trim(); @@ -5692,6 +5684,92 @@ else if ( playerName.equalsIgnoreCase( "view" ) || options.toLowerCase().contain } } + // Check to see if run has been specified: + if ( playerName.equalsIgnoreCase("run") ) { + run = true; + playerName = null; + } + else if ( playerName.equalsIgnoreCase("view") ) { + run = false; + playerName = null; + } + else if ( options != null ) { + String[] opts = options.split( " " ); + String newOpt = ""; + + for (String opt : opts) { + if ( opt.equalsIgnoreCase( "run" ) ) { + run = true; + } + else if ( opt.equalsIgnoreCase( "view" ) ) { + run = false; + } + else if ( world == null ) { + Optional wOpt = Prison.get().getPlatform().getWorld( opt ); + if ( wOpt.isPresent() ) { + // Set the world name: + world = opt; + } + } + else { + newOpt += opt + " "; + } + } + + options = newOpt.trim(); + } + + + + if ( sender.isPlayer() ) { + player = sender.getPlatformPlayer(); + } + else { + player = getPlayer( sender, playerName ); + } + + +// if ( playerName.equalsIgnoreCase("run") ) { +// +// if ( sender.isPlayer() ) { +// run = true; +// player = sender.getPlatformPlayer(); +// } +// else { +// sender.sendMessage( "A valid player name must be provided if this command is ran from the console."); +// } +// } +// else if ( playerName.equalsIgnoreCase( "view" ) || options.toLowerCase().contains( "view" ) ) { +// run = false; +// } +// else { +// player = getPlayer( sender, playerName ); +// +// if ( player == null ) { +// } +// +// if ( options.toLowerCase().contains( "run" ) ) { +// run = true; +// } +// } + +// if ( options != null ) { +// +// // If a world name is supplied, then it should be what's left after you remove any possible +// // values for 'view' or 'run'. +// String worldName = options.replace("view", "").replace("run", "").trim(); +// +// if ( worldName != null && worldName.length() > 0 ) { +// Optional wOpt = Prison.get().getPlatform().getWorld( worldName ); +// if ( wOpt.isPresent() ) { +// // Player name is a world name, so use it: +// world = worldName; +// +// // Do not change options... it's not used anymore: +// } +// } +// } + String mode = run ? "Running" : "Viewing"; ChatDisplay display = new ChatDisplay("WorldGuard Region Commands - " + mode); @@ -5764,23 +5842,34 @@ else if ( "*global*".equalsIgnoreCase(mineName) ) { .replace("{region-group-permission}", regionGroupPerms) .replace("{world}", worldPlaceholder); + if ( msg.startsWith( "/" ) ) { + msg = msg.substring( 1 ); + } + cmds.add( msg ); display.addText( "&4 %s", msg ); } + display.send( sender ); + if ( run ) { // submit the commands in cmds: for (String cmd : cmds) { - - Prison.get().getPlatform().dispatchCommand(player, cmd); - } - + + sender.sendMessage( "&3Running: &7" + cmd ); + if ( player != null ) { + + Prison.get().getPlatform().dispatchCommand(player, cmd); + } + else { + // Player was not defined, so try to run everything as console: + Prison.get().getPlatform().dispatchCommand( cmd ); + } + } } - display.send( sender ); - } else { sender.sendMessage( From afe2f3b55a76d021bd508c035c26fcc155a5e860 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 26 Sep 2024 03:24:45 -0400 Subject: [PATCH 200/323] File storage: Prison was changed a few weeks ago to precheck some of the critical folder structures to ensure they are there. That change was causing problems when creating a new instance of prison since the old code would fail if the directories were already there, which made no sense. --- docs/changelog_v3.3.x.md | 8 ++++++- .../prison/commands/BaseCommands.java | 3 ++- .../mcprison/prison/file/FileDatabase.java | 21 ++++++++++--------- .../mcprison/prison/file/FileStorage.java | 19 ++++++++--------- 4 files changed, 29 insertions(+), 22 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index c03d16fd8..68fbc70e2 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.19c 2024-09-24 +# 3.3.0-alpha.19c 2024-09-26 + + + + +* **File storage: Prison was changed a few weeks ago to precheck some of the critical folder structures to ensure they are there.** +That change was causing problems when creating a new instance of prison since the old code would fail if the directories were already there, which made no sense. * **WorldGuard Regions: Enable the commands to be able to be ran from the console and through online players.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/commands/BaseCommands.java b/prison-core/src/main/java/tech/mcprison/prison/commands/BaseCommands.java index fd5ced701..895bcceaa 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/commands/BaseCommands.java +++ b/prison-core/src/main/java/tech/mcprison/prison/commands/BaseCommands.java @@ -50,7 +50,8 @@ public Player getPlayer( CommandSender sender, String playerName ) { public Player getPlayer( CommandSender sender, String playerName, UUID uuid ) { Player result = null; - boolean console = "CONSOLE".equalsIgnoreCase( sender.getName() ); + boolean console = sender == null ? true : "CONSOLE".equalsIgnoreCase( sender.getName() ); + if ( !console ) { playerName = sender.getName(); } diff --git a/prison-core/src/main/java/tech/mcprison/prison/file/FileDatabase.java b/prison-core/src/main/java/tech/mcprison/prison/file/FileDatabase.java index 93485f5b4..a5354cce6 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/file/FileDatabase.java +++ b/prison-core/src/main/java/tech/mcprison/prison/file/FileDatabase.java @@ -81,10 +81,11 @@ public Optional getCollection(String name) /** *

This function will create a new FileCollection on the file system (a directory). - * It will generate the new directory with the provided name. If there is already - * a directory by that name, then this function will fail and it will log a - * warning. If successful, then it will add a File entry Collection to the - * collectionMap. + * It will generate the new directory with the provided name, and all parents. + * If successful, then it will add a File entry Collection to the collectionMap. + *

+ * + *

If the directory already exists, then all is good (return true) and move on. *

* * @param name @@ -96,13 +97,13 @@ public boolean createCollection(String name) { File collDir = new File(dbDir, name); if (!collDir.exists()) { - results = collDir.mkdir(); - collectionMap.put(name, new FileCollection(collDir)); - } else { - String message = "The attempt to create a new FileCollection named " + name + - " failed because a directory on the file system already exists by that name."; - Output.get().logWarn( message ); + results = collDir.mkdirs(); + } + else { + // the directory already exist... who cares? Let's use it: + results = true; } + collectionMap.put(name, new FileCollection(collDir)); return results; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/file/FileStorage.java b/prison-core/src/main/java/tech/mcprison/prison/file/FileStorage.java index 52ee63ea9..a1b554458 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/file/FileStorage.java +++ b/prison-core/src/main/java/tech/mcprison/prison/file/FileStorage.java @@ -100,10 +100,8 @@ public Optional getDatabase(String name) { /** *

This function will create a new FileDatabase on the file system (a directory). - * It will generate the new directory with the provided name. If there is already - * a directory by that name, then this function will fail and it will log a - * warning. If successful, then it will add a FileDatabase entry to the - * databaseMap. + * It will generate the new directory with the provided name. + * If successful, then it will add a FileDatabase entry to the databaseMap. *

* * @param name @@ -115,13 +113,14 @@ public boolean createDatabase(String name) { File directory = new File(rootDir, name); if (!directory.exists()) { - results = directory.mkdir(); - databaseMap.put(name, new FileDatabase(directory)); - } else { - String message = "The attempt to create a new FileDatabase named " + name + - " failed because a directory on the file system already exists by that name."; - Output.get().logWarn( message ); + results = directory.mkdirs(); + } + else { + // directory already exists, so use it: + results = true; } + databaseMap.put(name, new FileDatabase(directory)); + return results; } From 6e922e1097e5fafb738ffca17c032990b5c7b9b1 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 26 Sep 2024 03:27:49 -0400 Subject: [PATCH 201/323] Prison modules: Added an element count which reflects how many elements are loaded for each module. Examples would be ranks and mines, or number of prison utilities that were enabled. --- docs/changelog_v3.3.x.md | 2 + .../tech/mcprison/prison/modules/Module.java | 13 +++++ .../mcprison/prison/mines/PrisonMines.java | 21 ++++++++- .../mcprison/prison/ranks/PrisonRanks.java | 21 +++++++++ .../prison/sellall/PrisonSellall.java | 21 +++++++++ .../spigot/utils/PrisonUtilsModule.java | 47 ++++++++++++++++++- 6 files changed, 123 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 68fbc70e2..ee708900a 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.19c 2024-09-26 +* ***Prison modules: Added an element count which reflects how many elements are loaded for each module.** + Examples would be ranks and mines, or number of prison utilities that were enabled. * **File storage: Prison was changed a few weeks ago to precheck some of the critical folder structures to ensure they are there.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/modules/Module.java b/prison-core/src/main/java/tech/mcprison/prison/modules/Module.java index 65a982a9e..f83ffe829 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/modules/Module.java +++ b/prison-core/src/main/java/tech/mcprison/prison/modules/Module.java @@ -189,5 +189,18 @@ public ModuleStatus getStatus() { public File getModuleDataFolder() { return moduleDataFolder; } + + + /** + * For modules that have elements, this will return the count. If a module has no + * elements, then it will return a -1. Otherwise a zero would indicate that a module + * should have elements, but it currently has none. + * + * Example would be ranks and mines. For these, if it returns a zero, then they have + * no ranks or mines defined. If it return a -1 then the module is not active. + * + * @return + */ + abstract public int getElementCount(); } 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 dced8dfd7..21223d8e4 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 @@ -317,7 +317,26 @@ public void cancelResetAllMines() { getMineManager().cancelResetAllMines();; } - + /** + * For modules that have elements, this will return the count. If a module has no + * elements, then it will return a -1. Otherwise a zero would indicate that a module + * should have elements, but it currently has none. + * + * Example would be ranks and mines. For these, if it returns a zero, then they have + * no ranks or mines defined. If it return a -1 then the module is not active. + * + * @return + */ + public int getElementCount() { + int results = isEnabled() ? 0 : -1; + + if ( isEnabled() ) { + results = getMines().size(); + } + + return results; + } + public JsonFileIO getJsonFileIO() { 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 f8100ba48..927ec61c8 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 @@ -586,4 +586,25 @@ public int getPlayersCount() { public LocaleManager getRanksMessages() { return localeManager; } + + + /** + * For modules that have elements, this will return the count. If a module has no + * elements, then it will return a -1. Otherwise a zero would indicate that a module + * should have elements, but it currently has none. + * + * Example would be ranks and mines. For these, if it returns a zero, then they have + * no ranks or mines defined. If it return a -1 then the module is not active. + * + * @return + */ + public int getElementCount() { + int results = isEnabled() ? 0 : -1; + + if ( isEnabled() ) { + results = getRankCount(); + } + + return results; + } } diff --git a/prison-sellall/src/main/java/tech/mcprison/prison/sellall/PrisonSellall.java b/prison-sellall/src/main/java/tech/mcprison/prison/sellall/PrisonSellall.java index 6f7e06814..8237434f5 100644 --- a/prison-sellall/src/main/java/tech/mcprison/prison/sellall/PrisonSellall.java +++ b/prison-sellall/src/main/java/tech/mcprison/prison/sellall/PrisonSellall.java @@ -91,4 +91,25 @@ public LocaleManager getSellallMessages() { return localeManager; } + /** + * For modules that have elements, this will return the count. If a module has no + * elements, then it will return a -1. Otherwise a zero would indicate that a module + * should have elements, but it currently has none. + * + * Example would be ranks and mines. For these, if it returns a zero, then they have + * no ranks or mines defined. If it return a -1 then the module is not active. + * + * @return + */ + public int getElementCount() { + int results = isEnabled() ? 0 : -1; + + // May need to hook in to the number of shop items... but that currently is not available through this module. +// if ( isEnabled() ) { +// results = get; +// } + + return results; + } + } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsModule.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsModule.java index 6778a9bd1..068ba12d8 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsModule.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsModule.java @@ -12,8 +12,9 @@ public class PrisonUtilsModule { public static final String MODULE_NAME = "Utils"; + private int modulesEnabled = 0; + private YamlConfiguration modulesConf; - public PrisonUtilsModule(String version, YamlConfiguration modulesConf) { super(MODULE_NAME, version, 3); @@ -30,6 +31,8 @@ public String getBaseCommands() { @Override public void enable() { + int modulesEnabled = 0; + if ( isEnabled( "utils.enabled", true ) ) { if ( isEnabled( "utils.repair.enabled", true ) ) { @@ -41,6 +44,7 @@ public void enable() { Prison.get().getCommandHandler().registerCommands( utils ); + modulesEnabled++; } if ( isEnabled( "utils.messages.enabled", true ) ) { @@ -52,6 +56,7 @@ public void enable() { Prison.get().getCommandHandler().registerCommands( utils ); + modulesEnabled++; } if ( isEnabled( "utils.mining.enabled", true ) ) { @@ -63,6 +68,7 @@ public void enable() { Prison.get().getCommandHandler().registerCommands( utils ); + modulesEnabled++; } if ( isEnabled( "utils.healing.enabled", true ) ) { @@ -72,6 +78,8 @@ public void enable() { utils.setEnableHealingBreath( isEnabled("utils.healing.breath", true)); Prison.get().getCommandHandler().registerCommands( utils ); + + modulesEnabled++; } @@ -84,6 +92,7 @@ public void enable() { Prison.get().getCommandHandler().registerCommands( utils ); + modulesEnabled++; } @@ -97,6 +106,7 @@ public void enable() { Prison.get().getCommandHandler().registerCommands( utils ); + modulesEnabled++; } if ( isEnabled( "utils.sounds.enabled", true ) ) { @@ -107,6 +117,7 @@ public void enable() { Prison.get().getCommandHandler().registerCommands( utils ); + modulesEnabled++; } if ( isEnabled( "utils.titles.enabled", true ) ) { @@ -122,6 +133,7 @@ public void enable() { Prison.get().getCommandHandler().registerCommands( utils ); + modulesEnabled++; } if ( isEnabled( "utils.bombs.enabled", true ) ) { @@ -136,9 +148,12 @@ public void enable() { Bukkit.getPluginManager().registerEvents( new PrisonBombListener( utils ), SpigotPrison.getInstance()); + modulesEnabled++; } } + + setModulesEnabled( modulesEnabled ); } @Override @@ -159,4 +174,34 @@ public YamlConfiguration getModulesConf() { private boolean isEnabled( String configPath, boolean defaultValue ) { return getModulesConf().getBoolean( configPath, defaultValue ); } + + /** + * For modules that have elements, this will return the count. If a module has no + * elements, then it will return a -1. Otherwise a zero would indicate that a module + * should have elements, but it currently has none. + * + * Example would be ranks and mines. For these, if it returns a zero, then they have + * no ranks or mines defined. If it return a -1 then the module is not active. + * + * @return + */ + public int getElementCount() { + int results = isEnabled() ? 0 : -1; + + if ( isEnabled() ) { + results = getModulesEnabled(); + } + + return results; + } + + + public int getModulesEnabled() { + return modulesEnabled; + } + public void setModulesEnabled(int modulesEnabled) { + this.modulesEnabled = modulesEnabled; + } + + } From a7c6fbeb36cc1fc333e0a8adc50e005573b63bfe Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 26 Sep 2024 03:31:55 -0400 Subject: [PATCH 202/323] Mine Bombs: When loading the default bombs, this change now prevents the display of "warnings" which are actually normal because the settings for the wrong spigot platform must be removed. This now uses the check to see if the mine module has been enabled, and if it has mines, if not, then it will not purge any of the mine constraints since the server is probably under construction and they should not be purged until the mines have been setup. --- docs/changelog_v3.3.x.md | 4 + .../bombs/MineBombDefaultConfigSettings.java | 194 +++++++++--------- .../tech/mcprison/prison/bombs/MineBombs.java | 23 ++- 3 files changed, 123 insertions(+), 98 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index ee708900a..63b4f4cdb 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.19c 2024-09-26 +* **Mine Bombs: When loading the default bombs, this change now prevents the display of "warnings" which are actually normal because the settings for the wrong spigot platform must be removed.** +This now uses the check to see if the mine module has been enabled, and if it has mines, if not, then it will not purge any of the mine constraints since the server is probably under construction and they should not be purged until the mines have been setup. + + * ***Prison modules: Added an element count which reflects how many elements are loaded for each module.** Examples would be ranks and mines, or number of prison utilities that were enabled. 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 774f0faf7..0edaf20b6 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 @@ -12,6 +12,8 @@ public class MineBombDefaultConfigSettings { public void setupDefaultMineBombData(MineBombs mineBombs) { if ( mineBombs.getConfigData().getBombs().size() == 0 ) { + + boolean showWarnings = false; // XMaterial.WOODEN_PICKAXE; // XMaterial.STONE_PICKAXE; @@ -65,16 +67,16 @@ public void setupDefaultMineBombData(MineBombs mineBombs) mbd.getLore().add( "&4Lore line 2&r" ); mbd.getLore().add( "&aLore line &73&r" ); - mbd.addSoundEffects( mbeSound01.clone() ); - mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 30 ) ); - mbd.addSoundEffects( mbeSound03.clone() ); + mbd.addSoundEffects( mbeSound01.clone(), showWarnings ); + mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 30 ), showWarnings ); + mbd.addSoundEffects( mbeSound03.clone(), showWarnings ); - mbd.addVisualEffects( mbeExplode04.clone() ); - mbd.addVisualEffects( mbeExplode03.clone().setOffsetTicks( 30 ) ); + mbd.addVisualEffects( mbeExplode04.clone(), showWarnings ); + mbd.addVisualEffects( mbeExplode03.clone().setOffsetTicks( 30 ), showWarnings ); - mbd.addVisualEffects( mbeExplode06a.clone() ); - mbd.addVisualEffects( mbeExplode10.clone() ); - mbd.addVisualEffects( mbeExplode06.clone() ); + mbd.addVisualEffects( mbeExplode06a.clone(), showWarnings ); + mbd.addVisualEffects( mbeExplode10.clone(), showWarnings ); + mbd.addVisualEffects( mbeExplode06.clone(), showWarnings ); mbd.setCooldownTicks( 10 ); @@ -96,15 +98,15 @@ public void setupDefaultMineBombData(MineBombs mineBombs) mbd.setToolInHandName( "DIAMOND_PICKAXE" ); mbd.setToolInHandFortuneLevel( 3 ); - mbd.addSoundEffects( mbeSound01.clone() ); - mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 30 ) ); - mbd.addSoundEffects( mbeSound03.clone() ); + mbd.addSoundEffects( mbeSound01.clone(), showWarnings ); + mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 30 ), showWarnings ); + mbd.addSoundEffects( mbeSound03.clone(), showWarnings ); - mbd.addVisualEffects( mbeExplode04.clone() ); - mbd.addVisualEffects( mbeExplode03.clone().setOffsetTicks( 30 ) ); + mbd.addVisualEffects( mbeExplode04.clone(), showWarnings ); + mbd.addVisualEffects( mbeExplode03.clone().setOffsetTicks( 30 ), showWarnings ); - mbd.addVisualEffects( mbeExplode10.clone() ); - mbd.addVisualEffects( mbeExplode06.clone() ); + mbd.addVisualEffects( mbeExplode10.clone(), showWarnings ); + mbd.addVisualEffects( mbeExplode06.clone(), showWarnings ); mbd.setCooldownTicks( 60 ); @@ -127,16 +129,16 @@ public void setupDefaultMineBombData(MineBombs mineBombs) mbd.setToolInHandName( "DIAMOND_PICKAXE" ); mbd.setToolInHandFortuneLevel( 3 ); - mbd.addSoundEffects( mbeSound01.clone() ); - mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 30 ) ); - mbd.addSoundEffects( mbeSound03.clone().setVolumne( 2.0f ) ); + mbd.addSoundEffects( mbeSound01.clone(), showWarnings ); + mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 30 ), showWarnings ); + mbd.addSoundEffects( mbeSound03.clone().setVolumne( 2.0f ), showWarnings ); - mbd.addVisualEffects( mbeExplode04.clone() ); - mbd.addVisualEffects( mbeExplode03.clone().setOffsetTicks( 30 ) ); + mbd.addVisualEffects( mbeExplode04.clone(), showWarnings ); + mbd.addVisualEffects( mbeExplode03.clone().setOffsetTicks( 30 ), showWarnings ); - mbd.addVisualEffects( mbeExplode10.clone() ); - mbd.addVisualEffects( mbeExplode06.clone() ); - mbd.addVisualEffects( mbeExplode06a.clone() ); + mbd.addVisualEffects( mbeExplode10.clone(), showWarnings ); + mbd.addVisualEffects( mbeExplode06.clone(), showWarnings ); + mbd.addVisualEffects( mbeExplode06a.clone(), showWarnings ); mbd.setCooldownTicks( 60 ); @@ -159,38 +161,38 @@ public void setupDefaultMineBombData(MineBombs mineBombs) mbd.setToolInHandName( "GOLDEN_PICKAXE" ); mbd.setToolInHandFortuneLevel( 13 ); - mbd.addSoundEffects( mbeSound01.clone() ); - mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 10 ).setVolumne( 0.25f ).setPitch( 0.25f ) ); - mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 20 ).setVolumne( 0.5f ).setPitch( 0.5f ) ); - mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 30 ).setVolumne( 1.0f ).setPitch( 0.75f ) ); - mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 40 ).setVolumne( 2.0f ).setPitch( 1.5f ) ); - mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 50 ).setVolumne( 5.0f ).setPitch( 2.5f ) ); - - mbd.addSoundEffects( mbeSound03.clone().setOffsetTicks( 0 ).setVolumne( 3.0f ) ); - mbd.addSoundEffects( mbeSound04.clone().setOffsetTicks( 5 ).setVolumne( 1.5f ) ); - mbd.addSoundEffects( mbeSound03.clone().setOffsetTicks( 10 ).setVolumne( 2.5f ) ); - mbd.addSoundEffects( mbeSound04.clone().setOffsetTicks( 15 ).setVolumne( 1.0f ) ); - mbd.addSoundEffects( mbeSound03.clone().setOffsetTicks( 20 ).setVolumne( 2.0f ) ); - mbd.addSoundEffects( mbeSound04.clone().setOffsetTicks( 25 ).setVolumne( 0.75f ) ); - mbd.addSoundEffects( mbeSound03.clone().setOffsetTicks( 30 ).setVolumne( 1.5f ) ); - mbd.addSoundEffects( mbeSound04.clone().setOffsetTicks( 35 ).setVolumne( 0.55f ) ); - mbd.addSoundEffects( mbeSound03.clone().setOffsetTicks( 40 ).setVolumne( 1.0f ) ); - mbd.addSoundEffects( mbeSound04.clone().setOffsetTicks( 45 ).setVolumne( 0.25f ) ); - mbd.addSoundEffects( mbeSound03.clone().setOffsetTicks( 50 ).setVolumne( 0.5f ) ); - mbd.addSoundEffects( mbeSound04.clone().setOffsetTicks( 55 ).setVolumne( 0.15f ) ); - - - mbd.addVisualEffects( mbeExplode06.clone() ); - mbd.addVisualEffects( mbeExplode06a.clone() ); - mbd.addVisualEffects( mbeExplode03.clone() ); - mbd.addVisualEffects( mbeExplode12.clone() ); - mbd.addVisualEffects( mbeExplode12.clone().setOffsetTicks( 30 ) ); - mbd.addVisualEffects( mbeExplode12.clone().setOffsetTicks( 60 ) ); - mbd.addVisualEffects( mbeExplode07.clone().setOffsetTicks( 60 ) ); - mbd.addVisualEffects( mbeExplode08.clone().setOffsetTicks( 90 ) ); - - mbd.addVisualEffects( mbeExplode10.clone() ); - mbd.addVisualEffects( mbeExplode06.clone().setOffsetTicks( 20 ) ); + mbd.addSoundEffects( mbeSound01.clone(), showWarnings ); + mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 10 ).setVolumne( 0.25f ).setPitch( 0.25f ), showWarnings ); + mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 20 ).setVolumne( 0.5f ).setPitch( 0.5f ), showWarnings ); + mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 30 ).setVolumne( 1.0f ).setPitch( 0.75f ), showWarnings ); + mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 40 ).setVolumne( 2.0f ).setPitch( 1.5f ), showWarnings ); + mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 50 ).setVolumne( 5.0f ).setPitch( 2.5f ), showWarnings ); + + mbd.addSoundEffects( mbeSound03.clone().setOffsetTicks( 0 ).setVolumne( 3.0f ), showWarnings ); + mbd.addSoundEffects( mbeSound04.clone().setOffsetTicks( 5 ).setVolumne( 1.5f ), showWarnings ); + mbd.addSoundEffects( mbeSound03.clone().setOffsetTicks( 10 ).setVolumne( 2.5f ), showWarnings ); + mbd.addSoundEffects( mbeSound04.clone().setOffsetTicks( 15 ).setVolumne( 1.0f ), showWarnings ); + mbd.addSoundEffects( mbeSound03.clone().setOffsetTicks( 20 ).setVolumne( 2.0f ), showWarnings ); + mbd.addSoundEffects( mbeSound04.clone().setOffsetTicks( 25 ).setVolumne( 0.75f ), showWarnings ); + mbd.addSoundEffects( mbeSound03.clone().setOffsetTicks( 30 ).setVolumne( 1.5f ), showWarnings ); + mbd.addSoundEffects( mbeSound04.clone().setOffsetTicks( 35 ).setVolumne( 0.55f ), showWarnings ); + mbd.addSoundEffects( mbeSound03.clone().setOffsetTicks( 40 ).setVolumne( 1.0f ), showWarnings ); + mbd.addSoundEffects( mbeSound04.clone().setOffsetTicks( 45 ).setVolumne( 0.25f ), showWarnings ); + mbd.addSoundEffects( mbeSound03.clone().setOffsetTicks( 50 ).setVolumne( 0.5f ), showWarnings ); + mbd.addSoundEffects( mbeSound04.clone().setOffsetTicks( 55 ).setVolumne( 0.15f ), showWarnings ); + + + mbd.addVisualEffects( mbeExplode06.clone(), showWarnings ); + mbd.addVisualEffects( mbeExplode06a.clone(), showWarnings ); + mbd.addVisualEffects( mbeExplode03.clone(), showWarnings ); + mbd.addVisualEffects( mbeExplode12.clone(), showWarnings ); + mbd.addVisualEffects( mbeExplode12.clone().setOffsetTicks( 30 ), showWarnings ); + mbd.addVisualEffects( mbeExplode12.clone().setOffsetTicks( 60 ), showWarnings ); + mbd.addVisualEffects( mbeExplode07.clone().setOffsetTicks( 60 ), showWarnings ); + mbd.addVisualEffects( mbeExplode08.clone().setOffsetTicks( 90 ), showWarnings ); + + mbd.addVisualEffects( mbeExplode10.clone(), showWarnings ); + mbd.addVisualEffects( mbeExplode06.clone().setOffsetTicks( 20 ), showWarnings ); mbd.setAutosell( true ); mbd.setGlowing( true ); @@ -236,19 +238,19 @@ public void setupDefaultMineBombData(MineBombs mineBombs) mbd.getPreventedMines().add( "d" ); mbd.getPreventedMines().add( "e" ); - mbd.addSoundEffects( mbeSound01.clone() ); - mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 30 ) ); - mbd.addSoundEffects( mbeSound03.clone() ); + mbd.addSoundEffects( mbeSound01.clone(), showWarnings ); + mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 30 ), showWarnings ); + mbd.addSoundEffects( mbeSound03.clone(), showWarnings ); - mbd.addVisualEffects( mbeExplode01.clone() ); - mbd.addVisualEffects( mbeExplode02.clone().setOffsetTicks( 30 ) ); - mbd.addVisualEffects( mbeExplode03.clone().setOffsetTicks( 10 ) ); - mbd.addVisualEffects( mbeExplode04.clone() ); + mbd.addVisualEffects( mbeExplode01.clone(), showWarnings ); + mbd.addVisualEffects( mbeExplode02.clone().setOffsetTicks( 30 ), showWarnings ); + mbd.addVisualEffects( mbeExplode03.clone().setOffsetTicks( 10 ), showWarnings ); + mbd.addVisualEffects( mbeExplode04.clone(), showWarnings ); - mbd.addVisualEffects( mbeExplode10.clone() ); - mbd.addVisualEffects( mbeExplode06.clone() ); - mbd.addVisualEffects( mbeExplode06a.clone() ); - mbd.addVisualEffects( mbeExplode11.clone().setOffsetTicks( 05 ) ); + mbd.addVisualEffects( mbeExplode10.clone(), showWarnings ); + mbd.addVisualEffects( mbeExplode06.clone(), showWarnings ); + mbd.addVisualEffects( mbeExplode06a.clone(), showWarnings ); + mbd.addVisualEffects( mbeExplode11.clone().setOffsetTicks( 05 ), showWarnings ); mbd.setCooldownTicks( 3 * 20 ); // 3 seconds mbd.setFuseDelayTicks( 15 * 20 ); // 15 seconds @@ -281,12 +283,12 @@ public void setupDefaultMineBombData(MineBombs mineBombs) mbd.setToolInHandFortuneLevel( 7 ); mbd.setRemovalChance( 100.0d ); - mbd.addSoundEffects( mbeSound01.clone() ); - mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 30 ) ); - mbd.addSoundEffects( mbeSound03.clone() ); + mbd.addSoundEffects( mbeSound01.clone(), showWarnings ); + mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 30 ), showWarnings ); + mbd.addSoundEffects( mbeSound03.clone(), showWarnings ); - mbd.addVisualEffects( mbeExplode04.clone() ); - mbd.addVisualEffects( mbeExplode02.clone().setOffsetTicks( 30 ) ); + mbd.addVisualEffects( mbeExplode04.clone(), showWarnings ); + mbd.addVisualEffects( mbeExplode02.clone().setOffsetTicks( 30 ), showWarnings ); mbd.setGlowing( true ); @@ -314,12 +316,12 @@ public void setupDefaultMineBombData(MineBombs mineBombs) mbd.setToolInHandFortuneLevel( 1 ); mbd.setRemovalChance( 25.0d ); - mbd.addSoundEffects( mbeSound01.clone() ); - mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 30 ) ); - mbd.addSoundEffects( mbeSound03.clone() ); + mbd.addSoundEffects( mbeSound01.clone(), showWarnings ); + mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 30 ), showWarnings ); + mbd.addSoundEffects( mbeSound03.clone(), showWarnings ); - mbd.addVisualEffects( mbeExplode04.clone() ); - mbd.addVisualEffects( mbeExplode02.clone().setOffsetTicks( 30 ) ); + mbd.addVisualEffects( mbeExplode04.clone(), showWarnings ); + mbd.addVisualEffects( mbeExplode02.clone().setOffsetTicks( 30 ), showWarnings ); mbd.setCooldownTicks( 20 ); mbd.setFuseDelayTicks( 15 * 20 ); // 15 seconds @@ -348,12 +350,12 @@ public void setupDefaultMineBombData(MineBombs mineBombs) mbd.setToolInHandFortuneLevel( 1 ); mbd.setRemovalChance( 50.0d ); - mbd.addSoundEffects( mbeSound01.clone() ); - mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 30 ) ); - mbd.addSoundEffects( mbeSound03.clone() ); + mbd.addSoundEffects( mbeSound01.clone(), showWarnings ); + mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 30 ), showWarnings ); + mbd.addSoundEffects( mbeSound03.clone(), showWarnings ); - mbd.addVisualEffects( mbeExplode04.clone() ); - mbd.addVisualEffects( mbeExplode02.clone().setOffsetTicks( 30 ) ); + mbd.addVisualEffects( mbeExplode04.clone(), showWarnings ); + mbd.addVisualEffects( mbeExplode02.clone().setOffsetTicks( 30 ), showWarnings ); mbd.setCooldownTicks( 20 ); mbd.setFuseDelayTicks( 15 * 20 ); // 15 seconds @@ -382,12 +384,12 @@ public void setupDefaultMineBombData(MineBombs mineBombs) mbd.setToolInHandFortuneLevel( 1 ); mbd.setRemovalChance( 50.0d ); - mbd.addSoundEffects( mbeSound01.clone() ); - mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 30 ) ); - mbd.addSoundEffects( mbeSound03.clone() ); + mbd.addSoundEffects( mbeSound01.clone(), showWarnings ); + mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 30 ), showWarnings ); + mbd.addSoundEffects( mbeSound03.clone(), showWarnings ); - mbd.addVisualEffects( mbeExplode04.clone() ); - mbd.addVisualEffects( mbeExplode02.clone().setOffsetTicks( 30 ) ); + mbd.addVisualEffects( mbeExplode04.clone(), showWarnings ); + mbd.addVisualEffects( mbeExplode02.clone().setOffsetTicks( 30 ), showWarnings ); mbd.setCooldownTicks( 20 ); mbd.setFuseDelayTicks( 15 * 20 ); // 15 seconds @@ -420,12 +422,12 @@ public void setupDefaultMineBombData(MineBombs mineBombs) mbd.setToolInHandFortuneLevel( 1 ); mbd.setRemovalChance( 50.0d ); - mbd.addSoundEffects( mbeSound01.clone() ); - mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 30 ) ); - mbd.addSoundEffects( mbeSound03.clone() ); + mbd.addSoundEffects( mbeSound01.clone(), showWarnings ); + mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 30 ), showWarnings ); + mbd.addSoundEffects( mbeSound03.clone(), showWarnings ); - mbd.addVisualEffects( mbeExplode04.clone() ); - mbd.addVisualEffects( mbeExplode02.clone().setOffsetTicks( 30 ) ); + mbd.addVisualEffects( mbeExplode04.clone(), showWarnings ); + mbd.addVisualEffects( mbeExplode02.clone().setOffsetTicks( 30 ), showWarnings ); mbd.setCooldownTicks( 20 ); mbd.setFuseDelayTicks( 15 * 20 ); // 15 seconds @@ -458,12 +460,12 @@ public void setupDefaultMineBombData(MineBombs mineBombs) mbd.setToolInHandFortuneLevel( 1 ); mbd.setRemovalChance( 50.0d ); - mbd.addSoundEffects( mbeSound01.clone() ); - mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 30 ) ); - mbd.addSoundEffects( mbeSound03.clone() ); + mbd.addSoundEffects( mbeSound01.clone(), showWarnings ); + mbd.addSoundEffects( mbeSound02.clone().setOffsetTicks( 30 ), showWarnings ); + mbd.addSoundEffects( mbeSound03.clone(), showWarnings ); - mbd.addVisualEffects( mbeExplode04.clone() ); - mbd.addVisualEffects( mbeExplode02.clone().setOffsetTicks( 30 ) ); + mbd.addVisualEffects( mbeExplode04.clone(), showWarnings ); + mbd.addVisualEffects( mbeExplode02.clone().setOffsetTicks( 30 ), showWarnings ); mbd.setCooldownTicks( 20 ); mbd.setFuseDelayTicks( 15 * 20 ); // 15 seconds 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 508c7950e..132e17718 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 @@ -9,6 +9,8 @@ import tech.mcprison.prison.file.JsonFileIO; import tech.mcprison.prison.internal.Player; import tech.mcprison.prison.internal.block.PrisonBlock; +import tech.mcprison.prison.modules.Module; +import tech.mcprison.prison.modules.ModuleElementType; import tech.mcprison.prison.output.LogLevel; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.util.Location; @@ -366,6 +368,7 @@ public void loadConfigJson() { if ( !configExists ) { + // The save file does not exist so regenerate the default bombs listing: getConfigData().getBombs().clear(); @@ -485,6 +488,16 @@ public void validateMineBombs() MineBombsConfigData config = getConfigData(); + + Module moduleMines = Prison.get().getModuleManager() == null ? + null : Prison.get().getModuleManager().getModule( ModuleElementType.MINE.name() ); + boolean hasMines = moduleMines == null ? + false : moduleMines.isEnabled() && moduleMines.getElementCount() > 0; + +// Module moduleRanks = Prison.get().getModuleManager().getModule( ModuleElementType.RANK.name() ); +// boolean hasRanks = moduleRanks.isEnabled() && moduleRanks.getElementCount() > 0; + + if ( config.getDataFormatVersion() > MineBombsConfigData.MINE_BOMB_DATA_FORMAT_VERSION || config.getDataFormatVersion() < 0 ) { config.setDataFormatVersion( MineBombsConfigData.MINE_BOMB_DATA_FORMAT_VERSION ); @@ -614,7 +627,10 @@ public void validateMineBombs() cleaned = true; } - if ( !Prison.get().getPlatform().isMineNameValid(cleanedMineName) ) { + // Only purge mines if the mines module is enabled and there are more than one mines. + // If enabled and no mines, then could be that its clean startup and mines have not yet + // been added, so do not purge any mines. + if ( hasMines && !Prison.get().getPlatform().isMineNameValid(cleanedMineName) ) { Output.get().log( "MineBomb %s: invalid mine name for allowedMines: %s Removed.", LogLevel.WARNING, bomb.getName(), cleanedMineName ); @@ -644,7 +660,10 @@ public void validateMineBombs() cleaned = true; } - if ( !Prison.get().getPlatform().isMineNameValid(cleanedMineName) ) { + // Only purge mines if the mines module is enabled and there are more than one mines. + // If enabled and no mines, then could be that its clean startup and mines have not yet + // been added, so do not purge any mines. + if ( hasMines && !Prison.get().getPlatform().isMineNameValid(cleanedMineName) ) { Output.get().log( "MineBomb %s: invalid mine name for prevented-Mines: %s Removed.", LogLevel.WARNING, bomb.getName(), cleanedMineName ); From d3bd78d9785d107a454fac31032a72bdc21e6c14 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 26 Sep 2024 03:33:30 -0400 Subject: [PATCH 203/323] Mines: Startup air block counts. Bypass processing if no mines exist. This prevents an error when starting prison for the first time before any mines can be defined. --- docs/changelog_v3.3.x.md | 4 ++++ .../data/OnStartupRefreshBlockBreakCountSyncTask.java | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 63b4f4cdb..386e1ab18 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.19c 2024-09-26 +* **Mines: Startup air block counts. Bypass processing if no mines exist.*** +This prevents an error when starting prison for the first time before any mines can be defined. + + * **Mine Bombs: When loading the default bombs, this change now prevents the display of "warnings" which are actually normal because the settings for the wrong spigot platform must be removed.** This now uses the check to see if the mine module has been enabled, and if it has mines, if not, then it will not purge any of the mine constraints since the server is probably under construction and they should not be purged until the mines have been setup. diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/OnStartupRefreshBlockBreakCountSyncTask.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/OnStartupRefreshBlockBreakCountSyncTask.java index a904d6bc3..625a09b3d 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/OnStartupRefreshBlockBreakCountSyncTask.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/OnStartupRefreshBlockBreakCountSyncTask.java @@ -194,6 +194,13 @@ public void run() { } // else // The 'this.mine.refreshAirCountSyncTaskBuildLocations()' is trivial... + + if ( mine == null ) { + // No mine is available, either they are all processed, or none exist on + // the server yet (new startup), so exit without resubmitting: + return; + } + { pages++; From c5030d1c7c0b5a42a1e15dcfe483bc6f0d754f79 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 26 Sep 2024 03:36:21 -0400 Subject: [PATCH 204/323] Sellall: The sellall initialization function was being called twice by error. As such, this prevents a duplicate message from appearing in the startup log. No problems were caused by calling initialize twice, but it was unneeded. --- docs/changelog_v3.3.x.md | 4 ++++ .../main/java/tech/mcprison/prison/spigot/SpigotPrison.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 386e1ab18..761b110c7 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.19c 2024-09-26 +* **Sellall: The sellall initialization function was being called twice by error.** +As such, this prevents a duplicate message from appearing in the startup log. No problems were caused by calling initialize twice, but it was unneeded. + + * **Mines: Startup air block counts. Bypass processing if no mines exist.*** This prevents an error when starting prison for the first time before any mines can be defined. 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 be5f5a172..40000bccb 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 @@ -520,7 +520,7 @@ public FileConfiguration getSellAllConfig(){ public FileConfiguration updateSellAllConfig() { // Let this like this or it won't update when you do /Sellall etc and will need a server restart. sellAllConfig = new SellAllConfig(); - sellAllConfig.initialize(); +// sellAllConfig.initialize(); // initialize() is called in the constructor, so this was doubling the messages. return sellAllConfig.getFileSellAllConfig(); } From 548f114532099bc5d6e622b14d668e032f38ebaf Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 26 Sep 2024 03:39:23 -0400 Subject: [PATCH 205/323] Prison Backpacks: Found that the startup messages for backpacks was using references to sellall configs, which was incorrect. The messages are now corrected. This error appeared as if sellall was being setup and configured twice, which it was not. --- docs/changelog_v3.3.x.md | 4 ++++ .../prison/spigot/configs/BackpacksConfig.java | 15 ++++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 761b110c7..5ba4b81fd 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.19c 2024-09-26 +* **Prison Backpacks: Found that the startup messages for backpacks was using references to sellall configs, which was incorrect.** +The messages are now corrected. This error appeared as if sellall was being setup and configured twice, which it was not. + + * **Sellall: The sellall initialization function was being called twice by error.** As such, this prevents a duplicate message from appearing in the startup log. No problems were caused by calling initialize twice, but it was unneeded. diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/configs/BackpacksConfig.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/configs/BackpacksConfig.java index 0cde03a9f..3a80228ae 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/configs/BackpacksConfig.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/configs/BackpacksConfig.java @@ -25,8 +25,10 @@ public BackpacksConfig(){ public void initialize(){ + String path = "/backpacks/backpacksconfig.yml"; + // Filepath - File file = new File(SpigotPrison.getInstance().getDataFolder() + "/backpacks/backpacksconfig.yml"); + File file = new File(SpigotPrison.getInstance().getDataFolder() + path ); // Check if the config exists fileMaker(file); @@ -48,10 +50,17 @@ public void initialize(){ if (changeCount > 0) { try { conf.save(file); - Output.get().logInfo( "&aThere were &b%d &anew values added for the language files " + "used by the SellAllConfig.yml file located at &b%s", changeCount, file.getAbsoluteFile() ); + Output.get().logInfo( "&aThere were &b%d &anew values added for the language files " + + "used by the '%s' file located at &b%s", + changeCount, + path, file.getAbsoluteFile() ); } catch (IOException e) { - Output.get().logInfo( "&4Failed to save &b%d &4new values for the language files " + "used by the SellAllConfig.yml file located at &b%s&4. " + "&a %s", changeCount, file.getAbsoluteFile(), e.getMessage() ); + Output.get().logInfo( "&4Failed to save &b%d &4new values for the language files " + + "used by the '%s' file located at &b%s&4. " + + "&a %s", + changeCount, + path, file.getAbsoluteFile(), e.getMessage() ); } } From b7e34cbc9eef653de41880aff84030a799df4019 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 26 Sep 2024 03:41:18 -0400 Subject: [PATCH 206/323] Sellall startup messages: Fixed some formatting issues that were causing a misrepresentation of the sellall configurations within the startup logs. --- docs/changelog_v3.3.x.md | 3 +++ .../commands/PrisonSpigotSellAllCommands.java | 23 +++++++++++++------ .../prison/spigot/configs/SellAllConfig.java | 13 ++++++++--- 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 5ba4b81fd..cd0d3f586 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.19c 2024-09-26 +* **Sellall startup messages: Fixed some formatting issues that were causing a misrepresentation of the sellall configurations within the startup logs.** + + * **Prison Backpacks: Found that the startup messages for backpacks was using references to sellall configs, which was incorrect.** The messages are now corrected. This error appeared as if sellall was being setup and configured twice, which it was not. 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 697ee1af9..cd0e51c83 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 @@ -732,19 +732,22 @@ private void sellAllAddCommand(CommandSender sender, SellAllUtil sellAllUtil = SellAllUtil.get(); if (itemID == null){ - Output.get().sendWarn(sender, messages.getString(MessagesConfig.StringID.spigot_message_sellall_item_missing_name)); + Output.get().sendWarn(sender, messages.getString( + MessagesConfig.StringID.spigot_message_sellall_item_missing_name)); return; } itemID = itemID.toUpperCase(); if (value == null){ - Output.get().sendWarn(sender, messages.getString(MessagesConfig.StringID.spigot_message_sellall_item_missing_price)); + Output.get().sendWarn(sender, messages.getString( + MessagesConfig.StringID.spigot_message_sellall_item_missing_price)); return; } if (sellAllUtil.sellAllConfig.getConfigurationSection("Items." + itemID) != null){ - Output.get().sendWarn(sender, itemID + " " + messages.getString(MessagesConfig.StringID.spigot_message_sellall_item_already_added)); + Output.get().sendWarn(sender, itemID + " " + + messages.getString(MessagesConfig.StringID.spigot_message_sellall_item_already_added)); return; } @@ -753,16 +756,21 @@ private void sellAllAddCommand(CommandSender sender, try { blockAdd = XMaterial.matchXMaterial(itemID).orElse(null); } catch (IllegalArgumentException ex){ - Output.get().sendInfo(sender, messages.getString(MessagesConfig.StringID.spigot_message_sellall_item_id_not_found) + " [" + itemID + "]"); + Output.get().sendInfo(sender, messages.getString( + MessagesConfig.StringID.spigot_message_sellall_item_id_not_found) + + " [" + itemID + "]"); return; } 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){ - Output.get().sendError(sender, messages.getString(MessagesConfig.StringID.spigot_message_sellall_item_id_not_found) + " [" + itemID + "]"); + Output.get().sendError(sender, messages.getString( + MessagesConfig.StringID.spigot_message_sellall_item_id_not_found) + + " [" + itemID + "]"); } } @@ -790,7 +798,8 @@ public void sellAllAddCommand(XMaterial blockAdd, Double value){ if (sellAllUtil.addSellAllBlock(blockAdd, value)) return; - Output.get().logInfo("&3 ITEM [" + itemID + ", " + value + " " + messages.getString(MessagesConfig.StringID.spigot_message_sellall_item_add_success)); + Output.get().logInfo("&3 ITEM [" + itemID + ", " + value + "] " + + messages.getString(MessagesConfig.StringID.spigot_message_sellall_item_add_success)); } @Command(identifier = "sellall items delete", diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/configs/SellAllConfig.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/configs/SellAllConfig.java index f12eb6823..fbedc5537 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/configs/SellAllConfig.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/configs/SellAllConfig.java @@ -26,8 +26,10 @@ public SellAllConfig(){ public void initialize(){ + String path = "/SellAllConfig.yml"; + // Filepath - File file = new File(SpigotPrison.getInstance().getDataFolder() + "/SellAllConfig.yml"); + File file = new File(SpigotPrison.getInstance().getDataFolder() + path ); // Check if the config exists fileMaker(file); @@ -50,10 +52,15 @@ public void initialize(){ if (changeCount > 0) { try { conf.save(file); - Output.get().logInfo( "&aThere were &b%d &anew values added for the language files " + "used by the SellAllConfig.yml file located at &b%s", changeCount, file.getAbsoluteFile() ); + Output.get().logInfo( "&aThere were &b%d &anew values added for the language files " + + "used by the '%s' file located at &b%s", + changeCount, path, file.getAbsoluteFile() ); } catch (IOException e) { - Output.get().logInfo( "&4Failed to save &b%d &4new values for the language files " + "used by the SellAllConfig.yml file located at &b%s&4. " + "&a %s", changeCount, file.getAbsoluteFile(), e.getMessage() ); + Output.get().logInfo( "&4Failed to save &b%d &4new values for the language files " + + "used by the '%s' file located at &b%s&4. " + + "&a %s", changeCount, + path, file.getAbsoluteFile(), e.getMessage() ); } } From d894765e6127386f5d8ec13bd0b28b4b57f00b61 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 26 Sep 2024 03:44:24 -0400 Subject: [PATCH 207/323] Prison blocks: It was realized that due to a recent expansion of the items that are included in the default for sellall, that the first 27 or so entries, were the blocks that were used in the auto generated mines when running the command '/ranks autoConfigure'. These first few blocks, were returned to their proper place so the mines are properly populated again. Also, since blocks from multiple versions of spigot have been added, new code has been added to prevent adding any block that is not support by the version of spigot that the server is running. --- docs/changelog_v3.3.x.md | 5 + .../prison/spigot/SpigotPlatform.java | 385 +++++++++++------- 2 files changed, 243 insertions(+), 147 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index cd0d3f586..508f0c8fc 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.19c 2024-09-26 +* **Prison blocks: It was realized that due to a recent expansion of the items that are included in the default for sellall, that the first 27 or so entries, were the blocks that were used in the auto generated mines when running the command '/ranks autoConfigure'.** +These first few blocks, were returned to their proper place so the mines are properly populated again. +Also, since blocks from multiple versions of spigot have been added, new code has been added to prevent adding any block that is not support by the version of spigot that the server is running. + + * **Sellall startup messages: Fixed some formatting issues that were causing a misrepresentation of the sellall configurations within the startup logs.** 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 d22c14ccd..f5fd6b70c 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 @@ -1780,8 +1780,9 @@ else if ( hasBlocks && forceKeepBlocks ) { double total = 0; for ( int i = 0; i < mBlocks.size(); i++ ) { + String blockName = mBlocks.get( i ); - PrisonBlock prisonBlock = Prison.get().getPlatform().getPrisonBlock( mBlocks.get( i ) ); + PrisonBlock prisonBlock = Prison.get().getPlatform().getPrisonBlock( blockName ); if ( prisonBlock != null ) { double chance = percents.size() > i ? percents.get( i ) : 0; @@ -1804,7 +1805,7 @@ else if ( hasBlocks && forceKeepBlocks ) { Output.get().logInfo( String.format( "AutoConfigure block assignment failure: New Block Model: " + "Unable to map to a valid PrisonBlock for this version of mc. [%s]", - mBlocks.get( i ) ) ); + blockName ) ); } @@ -1938,7 +1939,29 @@ protected List mineBlockList( List blockList, int startPos, int /** - * This listing of blocks is based strictly upon XMaterial. + *

This listing of blocks is based strictly upon XMaterial. + *

+ * + *

Please note: First part of this list is used in the mine's block list + * for the command `/ranks autoConfigure'. + * These should be listed in ascending order as far as values for the blocks + * that are included in the mines. + *

+ * + *

In the source code are comments listing which blocks are assigned to each + * along with the percentages. + *

+ * + *

Before each block is added, it is confirmed that it's valid for the + * version of Spigot that is being ran. If it's not valid, it will be + * ignored. + *

+ * + *

It should be noted the blocks in this list need to be fully compatible with + * Spigot 1.8 through 1.21 +, otherwise invalid blocks will be omitted and + * the last few mines could be messed up. + *

+ * * This is the preferred list to use with the new block model. * * @return @@ -1946,232 +1969,300 @@ protected List mineBlockList( List blockList, int startPos, int public List buildBlockListXMaterial() { List blockList = new ArrayList<>(); - blockList.add( new SellAllBlockData( XMaterial.COBBLESTONE, 4, true) ); - blockList.add( new SellAllBlockData( XMaterial.ANDESITE, 5, true) ); - blockList.add( new SellAllBlockData( XMaterial.DIORITE, 6, true) ); - blockList.add( new SellAllBlockData( XMaterial.GRANITE, 8, true) ); - blockList.add( new SellAllBlockData( XMaterial.STONE, 9, true) ); - blockList.add( new SellAllBlockData( XMaterial.POLISHED_ANDESITE, 7, true) ); +// Mine A: [minecraft: andesite 5.0, minecraft: cobblestone 95.0] + addBlockToSellallList( new SellAllBlockData( XMaterial.ANDESITE, 5, true), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.COBBLESTONE, 4, true), blockList ); +// Mine B: [minecraft: diorite 5.0, minecraft: andesite 10.0, minecraft: cobblestone 85.0] + addBlockToSellallList( new SellAllBlockData( XMaterial.DIORITE, 6, true), blockList ); + +// Mine C: [minecraft: coal_ore 5.0, minecraft: diorite 10.0, minecraft: andesite 20.0, minecraft: cobblestone 65.0] + addBlockToSellallList( new SellAllBlockData( XMaterial.COAL_ORE, 13, true), blockList ); + +// Mine D: [minecraft: granite 5.0, minecraft: coal_ore 10.0, minecraft: diorite 20.0, minecraft: andesite 20.0, minecraft: cobblestone 45.0] + addBlockToSellallList( new SellAllBlockData( XMaterial.GRANITE, 8, true), blockList ); - blockList.add( new SellAllBlockData( XMaterial.CHARCOAL, 13, true) ); - blockList.add( new SellAllBlockData( XMaterial.COAL, 13, true) ); - blockList.add( new SellAllBlockData( XMaterial.COAL_ORE, 13, true) ); - blockList.add( new SellAllBlockData( XMaterial.COAL_BLOCK, 135, true) ); - blockList.add( new SellAllBlockData( XMaterial.DEEPSLATE_COAL_ORE, 13, true) ); +// Mine E: [minecraft: stone 5.0, minecraft: granite 10.0, minecraft: coal_ore 20.0, minecraft: diorite 20.0, minecraft: andesite 20.0, minecraft: cobblestone 25.0] + addBlockToSellallList( new SellAllBlockData( XMaterial.STONE, 9, true), blockList ); +// Mine F: [minecraft: iron_ore 5.0, minecraft: stone 10.0, minecraft: granite 20.0, minecraft: coal_ore 20.0, minecraft: diorite 20.0, minecraft: andesite 25.0] + addBlockToSellallList( new SellAllBlockData( XMaterial.IRON_ORE, 18, true), blockList ); - blockList.add( new SellAllBlockData( XMaterial.IRON_NUGGET, 2, true) ); - blockList.add( new SellAllBlockData( XMaterial.IRON_ORE, 18, true) ); - blockList.add( new SellAllBlockData( XMaterial.IRON_INGOT, 18, true) ); - blockList.add( new SellAllBlockData( XMaterial.RAW_IRON, 18, true) ); - blockList.add( new SellAllBlockData( XMaterial.RAW_IRON_BLOCK, 162, true) ); - blockList.add( new SellAllBlockData( XMaterial.IRON_BLOCK, 190, true) ); - blockList.add( new SellAllBlockData( XMaterial.DEEPSLATE_IRON_ORE, 18, true) ); +// Mine G: [minecraft: polished_andesite 5.0, minecraft: iron_ore 10.0, minecraft: stone 20.0, minecraft: granite 20.0, minecraft: coal_ore 20.0, minecraft: diorite 25.0] + addBlockToSellallList( new SellAllBlockData( XMaterial.POLISHED_ANDESITE, 7, true), blockList ); + +// Mine H: [minecraft: gold_ore 5.0, minecraft: polished_andesite 10.0, minecraft: iron_ore 20.0, minecraft: stone 20.0, minecraft: granite 20.0, minecraft: coal_ore 25.0] + addBlockToSellallList( new SellAllBlockData( XMaterial.GOLD_ORE, 45, true), blockList ); + +// Mine I: [minecraft: mossy_cobblestone 5.0, minecraft: gold_ore 10.0, minecraft: polished_andesite 20.0, minecraft: iron_ore 20.0, minecraft: stone 20.0, minecraft: granite 25.0] + addBlockToSellallList( new SellAllBlockData( XMaterial.MOSSY_COBBLESTONE, 29, true), blockList ); + +// Mine J: [minecraft: coal_block 5.0, minecraft: mossy_cobblestone 10.0, minecraft: gold_ore 20.0, minecraft: polished_andesite 20.0, minecraft: iron_ore 20.0, minecraft: stone 25.0] + addBlockToSellallList( new SellAllBlockData( XMaterial.COAL_BLOCK, 135, true), blockList ); +// Mine K: [minecraft: nether_quartz_ore 5.0, minecraft: coal_block 10.0, minecraft: mossy_cobblestone 20.0, minecraft: gold_ore 20.0, minecraft: polished_andesite 20.0, minecraft: iron_ore 25.0] + addBlockToSellallList( new SellAllBlockData( XMaterial.NETHER_QUARTZ_ORE, 34, true), blockList ); + +// Mine L: [minecraft: lapis_ore 5.0, minecraft: nether_quartz_ore 10.0, minecraft: coal_block 20.0, minecraft: mossy_cobblestone 20.0, minecraft: gold_ore 20.0, minecraft: polished_andesite 25.0] + addBlockToSellallList( new SellAllBlockData( XMaterial.LAPIS_ORE, 100, true), blockList ); + +// Mine M: [minecraft: end_stone 5.0, minecraft: lapis_ore 10.0, minecraft: nether_quartz_ore 20.0, minecraft: coal_block 20.0, minecraft: mossy_cobblestone 20.0, minecraft: gold_ore 25.0] + addBlockToSellallList( new SellAllBlockData( XMaterial.END_STONE, 14, true ), blockList ); - blockList.add( new SellAllBlockData( XMaterial.GOLD_NUGGET, 5, true) ); - blockList.add( new SellAllBlockData( XMaterial.GOLD_ORE, 45, true) ); - blockList.add( new SellAllBlockData( XMaterial.GOLD_INGOT, 45, true) ); - blockList.add( new SellAllBlockData( XMaterial.RAW_GOLD, 45, true) ); - blockList.add( new SellAllBlockData( XMaterial.RAW_GOLD_BLOCK, 405, true) ); - blockList.add( new SellAllBlockData( XMaterial.GOLD_BLOCK, 450, true) ); - blockList.add( new SellAllBlockData( XMaterial.DEEPSLATE_GOLD_ORE, 45, true) ); - blockList.add( new SellAllBlockData( XMaterial.NETHER_GOLD_ORE, 45, true) ); +// Mine N: [minecraft: iron_block 5.0, minecraft: end_stone 10.0, minecraft: lapis_ore 20.0, minecraft: nether_quartz_ore 20.0, minecraft: coal_block 20.0, minecraft: mossy_cobblestone 25.0] + addBlockToSellallList( new SellAllBlockData( XMaterial.IRON_BLOCK, 190, true), blockList ); +// Mine O: [minecraft: redstone_ore 5.0, minecraft: iron_block 10.0, minecraft: end_stone 20.0, minecraft: lapis_ore 20.0, minecraft: nether_quartz_ore 20.0, minecraft: coal_block 25.0] + addBlockToSellallList( new SellAllBlockData( XMaterial.REDSTONE_ORE, 45, true), blockList ); - blockList.add( new SellAllBlockData( XMaterial.COPPER_ORE, 22, true) ); - blockList.add( new SellAllBlockData( XMaterial.RAW_COPPER, 22, true) ); - blockList.add( new SellAllBlockData( XMaterial.RAW_COPPER_BLOCK, 198, true) ); - blockList.add( new SellAllBlockData( XMaterial.COPPER_BLOCK, 198, true) ); - blockList.add( new SellAllBlockData( XMaterial.DEEPSLATE_COPPER_ORE, 22, true) ); +// Mine P: [minecraft: diamond_ore 5.0, minecraft: redstone_ore 10.0, minecraft: iron_block 20.0, minecraft: end_stone 20.0, minecraft: lapis_ore 20.0, minecraft: nether_quartz_ore 25.0] + addBlockToSellallList( new SellAllBlockData( XMaterial.DIAMOND_ORE, 222, true), blockList ); + +// Mine Q: [minecraft: quartz_block 5.0, minecraft: diamond_ore 10.0, minecraft: redstone_ore 20.0, minecraft: iron_block 20.0, minecraft: end_stone 20.0, minecraft: lapis_ore 25.0] + addBlockToSellallList( new SellAllBlockData( XMaterial.QUARTZ_BLOCK, 136, true), blockList ); +// Mine R: [minecraft: emerald_ore 5.0, minecraft: quartz_block 10.0, minecraft: diamond_ore 20.0, minecraft: redstone_ore 20.0, minecraft: iron_block 20.0, minecraft: end_stone 25.0] + addBlockToSellallList( new SellAllBlockData( XMaterial.EMERALD_ORE, 250, true), blockList ); - blockList.add( new SellAllBlockData( XMaterial.REDSTONE, 45, true) ); - blockList.add( new SellAllBlockData( XMaterial.REDSTONE_ORE, 45, true) ); - blockList.add( new SellAllBlockData( XMaterial.REDSTONE_BLOCK, 405, true) ); - blockList.add( new SellAllBlockData( XMaterial.DEEPSLATE_REDSTONE_ORE, 45, true) ); +// Mine S: [minecraft: gold_block 5.0, minecraft: emerald_ore 10.0, minecraft: quartz_block 20.0, minecraft: diamond_ore 20.0, minecraft: redstone_ore 20.0, minecraft: iron_block 25.0] + addBlockToSellallList( new SellAllBlockData( XMaterial.GOLD_BLOCK, 450, true), blockList ); +// Mine T: [minecraft: prismarine 5.0, minecraft: gold_block 10.0, minecraft: emerald_ore 20.0, minecraft: quartz_block 20.0, minecraft: diamond_ore 20.0, minecraft: redstone_ore 25.0] + addBlockToSellallList( new SellAllBlockData( XMaterial.PRISMARINE, 52, true ), blockList ); + +// Mine U: [minecraft: dark_prismarine 5.0, minecraft: prismarine 10.0, minecraft: gold_block 20.0, minecraft: emerald_ore 20.0, minecraft: quartz_block 20.0, minecraft: diamond_ore 25.0] + addBlockToSellallList( new SellAllBlockData( XMaterial.DARK_PRISMARINE, 54, true ), blockList ); + +// Mine V: [minecraft: lapis_block 5.0, minecraft: dark_prismarine 10.0, minecraft: prismarine 20.0, minecraft: gold_block 20.0, minecraft: emerald_ore 20.0, minecraft: quartz_block 25.0] + addBlockToSellallList( new SellAllBlockData( XMaterial.LAPIS_BLOCK, 900, true), blockList ); - blockList.add( new SellAllBlockData( XMaterial.DIAMOND, 222, true) ); - blockList.add( new SellAllBlockData( XMaterial.DIAMOND_ORE, 222, true) ); - blockList.add( new SellAllBlockData( XMaterial.DIAMOND_BLOCK, 1998, true) ); - blockList.add( new SellAllBlockData( XMaterial.DEEPSLATE_DIAMOND_ORE, 222, true) ); +// Mine W: [minecraft: redstone_block 5.0, minecraft: lapis_block 10.0, minecraft: dark_prismarine 20.0, minecraft: prismarine 20.0, minecraft: gold_block 20.0, minecraft: emerald_ore 25.0] + addBlockToSellallList( new SellAllBlockData( XMaterial.REDSTONE_BLOCK, 405, true), blockList ); +// Mine X: [minecraft: obsidian 5.0, minecraft: redstone_block 10.0, minecraft: lapis_block 20.0, minecraft: dark_prismarine 20.0, minecraft: prismarine 20.0, minecraft: gold_block 25.0] + addBlockToSellallList( new SellAllBlockData( XMaterial.OBSIDIAN, 450, true ), blockList ); + +// Mine Y: [minecraft: diamond_block 5.0, minecraft: obsidian 10.0, minecraft: redstone_block 20.0, minecraft: lapis_block 20.0, minecraft: dark_prismarine 20.0, minecraft: prismarine 25.0] + addBlockToSellallList( new SellAllBlockData( XMaterial.DIAMOND_BLOCK, 1998, true), blockList ); + +// Mine Z: [minecraft: emerald_block 5.0, minecraft: diamond_block 10.0, minecraft: obsidian 20.0, minecraft: redstone_block 20.0, minecraft: lapis_block 20.0, minecraft: dark_prismarine 25.0] + addBlockToSellallList( new SellAllBlockData( XMaterial.EMERALD_BLOCK, 2250, true), blockList ); + + + + + +// addBlockToSellallList( XMaterial.SLIME_BLOCK.name(), blockList ); - blockList.add( new SellAllBlockData( XMaterial.EMERALD, 250, true) ); - blockList.add( new SellAllBlockData( XMaterial.EMERALD_ORE, 250, true) ); - blockList.add( new SellAllBlockData( XMaterial.EMERALD_BLOCK, 2250, true) ); - blockList.add( new SellAllBlockData( XMaterial.DEEPSLATE_EMERALD_ORE, 250, true) ); + // The following blocks are not used to generate the mine blocks: - blockList.add( new SellAllBlockData( XMaterial.PRISMARINE_SHARD, 13, true ) ); - blockList.add( new SellAllBlockData( XMaterial.PRISMARINE, 52, true ) ); - blockList.add( new SellAllBlockData( XMaterial.DARK_PRISMARINE, 54, true ) ); + addBlockToSellallList( new SellAllBlockData( XMaterial.CHARCOAL, 13, true), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.COAL, 13, true), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.DEEPSLATE_COAL_ORE, 13, true), blockList ); - blockList.add( new SellAllBlockData( XMaterial.LAPIS_ORE, 100, true) ); - blockList.add( new SellAllBlockData( XMaterial.LAPIS_LAZULI, 100, true) ); - blockList.add( new SellAllBlockData( XMaterial.LAPIS_BLOCK, 900, true) ); - blockList.add( new SellAllBlockData( XMaterial.DEEPSLATE_LAPIS_ORE, 100, true) ); + + addBlockToSellallList( new SellAllBlockData( XMaterial.IRON_NUGGET, 2, true), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.IRON_INGOT, 18, true), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.RAW_IRON, 18, true), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.RAW_IRON_BLOCK, 162, true), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.DEEPSLATE_IRON_ORE, 18, true), blockList ); - blockList.add( new SellAllBlockData( XMaterial.QUARTZ, 34, true) ); - blockList.add( new SellAllBlockData( XMaterial.NETHER_QUARTZ_ORE, 34, true) ); - blockList.add( new SellAllBlockData( XMaterial.QUARTZ_BLOCK, 136, true) ); - blockList.add( new SellAllBlockData( XMaterial.CHISELED_QUARTZ_BLOCK, 136, true) ); - blockList.add( new SellAllBlockData( XMaterial.SMOOTH_QUARTZ, 136, true) ); + addBlockToSellallList( new SellAllBlockData( XMaterial.GOLD_NUGGET, 5, true), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.GOLD_INGOT, 45, true), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.RAW_GOLD, 45, true), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.RAW_GOLD_BLOCK, 405, true), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.DEEPSLATE_GOLD_ORE, 45, true), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.NETHER_GOLD_ORE, 45, true), blockList ); + + addBlockToSellallList( new SellAllBlockData( XMaterial.COPPER_ORE, 22, true), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.RAW_COPPER, 22, true), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.RAW_COPPER_BLOCK, 198, true), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.COPPER_BLOCK, 198, true), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.DEEPSLATE_COPPER_ORE, 22, true), blockList ); + + addBlockToSellallList( new SellAllBlockData( XMaterial.REDSTONE, 45, true), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.DEEPSLATE_REDSTONE_ORE, 45, true), blockList ); + - blockList.add( new SellAllBlockData( XMaterial.MOSSY_COBBLESTONE, 29, true) ); + addBlockToSellallList( new SellAllBlockData( XMaterial.DIAMOND, 222, true), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.DEEPSLATE_DIAMOND_ORE, 222, true), blockList ); + + addBlockToSellallList( new SellAllBlockData( XMaterial.EMERALD, 250, true), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.DEEPSLATE_EMERALD_ORE, 250, true), blockList ); - blockList.add( new SellAllBlockData( XMaterial.END_STONE, 14, true ) ); + + addBlockToSellallList( new SellAllBlockData( XMaterial.PRISMARINE_SHARD, 13, true ), blockList ); - blockList.add( new SellAllBlockData( XMaterial.OBSIDIAN, 450, true ) ); + addBlockToSellallList( new SellAllBlockData( XMaterial.LAPIS_LAZULI, 100, true), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.DEEPSLATE_LAPIS_ORE, 100, true), blockList ); + + + addBlockToSellallList( new SellAllBlockData( XMaterial.QUARTZ, 34, true), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.CHISELED_QUARTZ_BLOCK, 136, true), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.SMOOTH_QUARTZ, 136, true), blockList ); + -// blockList.add( XMaterial.SLIME_BLOCK.name() ); - // these are not used to generate the mine blocks: - blockList.add( new SellAllBlockData( XMaterial.CLAY, 12 ) ); - blockList.add( new SellAllBlockData( XMaterial.GRAVEL, 3 ) ); - blockList.add( new SellAllBlockData( XMaterial.SAND, 6 ) ); - blockList.add( new SellAllBlockData( XMaterial.DIRT, 4 ) ); - blockList.add( new SellAllBlockData( XMaterial.COARSE_DIRT, 7 ) ); - blockList.add( new SellAllBlockData( XMaterial.PODZOL, 6 ) ); - blockList.add( new SellAllBlockData( XMaterial.RED_SAND, 9 ) ); - blockList.add( new SellAllBlockData( XMaterial.BEDROCK, 500 ) ); - blockList.add( new SellAllBlockData( XMaterial.SANDSTONE, 3 ) ); - blockList.add( new SellAllBlockData( XMaterial.POLISHED_ANDESITE, 7 ) ); - blockList.add( new SellAllBlockData( XMaterial.POLISHED_DIORITE, 8 ) ); - blockList.add( new SellAllBlockData( XMaterial.POLISHED_GRANITE, 9 ) ); - blockList.add( new SellAllBlockData( XMaterial.CHISELED_NETHER_BRICKS, 39 ) ); - blockList.add( new SellAllBlockData( XMaterial.CHISELED_RED_SANDSTONE, 11 ) ); - blockList.add( new SellAllBlockData( XMaterial.CHISELED_STONE_BRICKS, 11 ) ); - blockList.add( new SellAllBlockData( XMaterial.CUT_RED_SANDSTONE, 13 ) ); - blockList.add( new SellAllBlockData( XMaterial.CUT_SANDSTONE, 10 ) ); + + + + addBlockToSellallList( new SellAllBlockData( XMaterial.CLAY, 12 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.GRAVEL, 3 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.SAND, 6 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.DIRT, 4 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.COARSE_DIRT, 7 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.PODZOL, 6 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.RED_SAND, 9 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.BEDROCK, 500 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.SANDSTONE, 3 ), blockList ); + + addBlockToSellallList( new SellAllBlockData( XMaterial.POLISHED_ANDESITE, 7 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.POLISHED_DIORITE, 8 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.POLISHED_GRANITE, 9 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.CHISELED_NETHER_BRICKS, 39 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.CHISELED_RED_SANDSTONE, 11 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.CHISELED_STONE_BRICKS, 11 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.CUT_RED_SANDSTONE, 13 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.CUT_SANDSTONE, 10 ), blockList ); -// blockList.add( new SellAllBlockData( XMaterial.QUARTZ, 34 ) ); - blockList.add( new SellAllBlockData( XMaterial.QUARTZ_SLAB, 68) ); +// addBlockToSellallList( new SellAllBlockData( XMaterial.QUARTZ, 34 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.QUARTZ_SLAB, 68), blockList ); -// blockList.add( new SellAllBlockData( XMaterial.CHISELED_QUARTZ_BLOCK, 136 ) ); - blockList.add( new SellAllBlockData( XMaterial.QUARTZ_BRICKS, 136 ) ); - blockList.add( new SellAllBlockData( XMaterial.QUARTZ_PILLAR, 136 ) ); -// blockList.add( new SellAllBlockData( XMaterial.SMOOTH_QUARTZ, 136 ) ); +// addBlockToSellallList( new SellAllBlockData( XMaterial.CHISELED_QUARTZ_BLOCK, 136 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.QUARTZ_BRICKS, 136 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.QUARTZ_PILLAR, 136 ), blockList ); +// addBlockToSellallList( new SellAllBlockData( XMaterial.SMOOTH_QUARTZ, 136 ), blockList ); - blockList.add( new SellAllBlockData( XMaterial.SMOOTH_RED_SANDSTONE, 14 ) ); - blockList.add( new SellAllBlockData( XMaterial.SMOOTH_SANDSTONE, 14 ) ); - blockList.add( new SellAllBlockData( XMaterial.SMOOTH_STONE, 14 ) ); + addBlockToSellallList( new SellAllBlockData( XMaterial.SMOOTH_RED_SANDSTONE, 14 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.SMOOTH_SANDSTONE, 14 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.SMOOTH_STONE, 14 ), blockList ); -// blockList.add( new SellAllBlockData( XMaterial.CHARCOAL, 16 ) ); - blockList.add( new SellAllBlockData( XMaterial.CRACKED_NETHER_BRICKS, 16 ) ); - blockList.add( new SellAllBlockData( XMaterial.CRACKED_STONE_BRICKS, 14 ) ); +// addBlockToSellallList( new SellAllBlockData( XMaterial.CHARCOAL, 16 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.CRACKED_NETHER_BRICKS, 16 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.CRACKED_STONE_BRICKS, 14 ), blockList ); -// blockList.add( new SellAllBlockData( XMaterial.EMERALD, 14 ) ); - blockList.add( new SellAllBlockData( XMaterial.END_STONE_BRICKS, 14 ) ); +// addBlockToSellallList( new SellAllBlockData( XMaterial.EMERALD, 14 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.END_STONE_BRICKS, 14 ), blockList ); - blockList.add( new SellAllBlockData( XMaterial.FLINT, 9 ) ); + addBlockToSellallList( new SellAllBlockData( XMaterial.FLINT, 9 ), blockList ); // BLUE_DYE is used as LAPIS_LAZULI for bukkit v1.8.x etc... -// blockList.add( new SellAllBlockData( XMaterial.LAPIS_LAZULI, 14 ) ); - blockList.add( new SellAllBlockData( XMaterial.BLUE_DYE, 14 ) ); +// addBlockToSellallList( new SellAllBlockData( XMaterial.LAPIS_LAZULI, 14 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.BLUE_DYE, 14 ), blockList ); - blockList.add( new SellAllBlockData( XMaterial.MOSSY_STONE_BRICKS, 14 ) ); + addBlockToSellallList( new SellAllBlockData( XMaterial.MOSSY_STONE_BRICKS, 14 ), blockList ); - blockList.add( new SellAllBlockData( XMaterial.PRISMARINE_SHARD, 13 ) ); + addBlockToSellallList( new SellAllBlockData( XMaterial.PRISMARINE_SHARD, 13 ), blockList ); - blockList.add( new SellAllBlockData( XMaterial.PRISMARINE_BRICKS, 52 ) ); - blockList.add( new SellAllBlockData( XMaterial.PRISMARINE_BRICK_SLAB, 52 ) ); - blockList.add( new SellAllBlockData( XMaterial.PRISMARINE_CRYSTALS, 37 ) ); - blockList.add( new SellAllBlockData( XMaterial.DARK_PRISMARINE_SLAB, 52 ) ); + addBlockToSellallList( new SellAllBlockData( XMaterial.PRISMARINE_BRICKS, 52 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.PRISMARINE_BRICK_SLAB, 52 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.PRISMARINE_CRYSTALS, 37 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.DARK_PRISMARINE_SLAB, 52 ), blockList ); - blockList.add( new SellAllBlockData( XMaterial.PURPUR_BLOCK, 14 ) ); - blockList.add( new SellAllBlockData( XMaterial.PURPUR_PILLAR, 14 ) ); + addBlockToSellallList( new SellAllBlockData( XMaterial.PURPUR_BLOCK, 14 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.PURPUR_PILLAR, 14 ), blockList ); -// blockList.add( new SellAllBlockData( XMaterial.SEA_LANTERN, 98 ) ); +// addBlockToSellallList( new SellAllBlockData( XMaterial.SEA_LANTERN, 98 ), blockList ); - blockList.add( new SellAllBlockData( XMaterial.TERRACOTTA, 10 ) ); + addBlockToSellallList( new SellAllBlockData( XMaterial.TERRACOTTA, 10 ), blockList ); - blockList.add( new SellAllBlockData( XMaterial.ACACIA_LOG, 7 ) ); - blockList.add( new SellAllBlockData( XMaterial.BIRCH_LOG, 7 ) ); - blockList.add( new SellAllBlockData( XMaterial.DARK_OAK_LOG, 7 ) ); - blockList.add( new SellAllBlockData( XMaterial.JUNGLE_LOG, 7 ) ); - blockList.add( new SellAllBlockData( XMaterial.OAK_LOG, 7 ) ); - blockList.add( new SellAllBlockData( XMaterial.SPRUCE_LOG, 7 ) ); - blockList.add( new SellAllBlockData( XMaterial.ACACIA_PLANKS, 28 ) ); - blockList.add( new SellAllBlockData( XMaterial.BIRCH_PLANKS, 28 ) ); - blockList.add( new SellAllBlockData( XMaterial.DARK_OAK_PLANKS, 28 ) ); - blockList.add( new SellAllBlockData( XMaterial.JUNGLE_PLANKS, 28 ) ); - blockList.add( new SellAllBlockData( XMaterial.OAK_PLANKS, 28 ) ); - blockList.add( new SellAllBlockData( XMaterial.SPRUCE_PLANKS, 28 ) ); + addBlockToSellallList( new SellAllBlockData( XMaterial.ACACIA_LOG, 7 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.BIRCH_LOG, 7 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.DARK_OAK_LOG, 7 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.JUNGLE_LOG, 7 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.OAK_LOG, 7 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.SPRUCE_LOG, 7 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.ACACIA_PLANKS, 28 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.BIRCH_PLANKS, 28 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.DARK_OAK_PLANKS, 28 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.JUNGLE_PLANKS, 28 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.OAK_PLANKS, 28 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.SPRUCE_PLANKS, 28 ), blockList ); - blockList.add( new SellAllBlockData( XMaterial.ACACIA_WOOD, 7 ) ); - blockList.add( new SellAllBlockData( XMaterial.BIRCH_WOOD, 7 ) ); - blockList.add( new SellAllBlockData( XMaterial.DARK_OAK_WOOD, 7 ) ); - blockList.add( new SellAllBlockData( XMaterial.JUNGLE_WOOD, 7 ) ); - blockList.add( new SellAllBlockData( XMaterial.OAK_WOOD, 7 ) ); - blockList.add( new SellAllBlockData( XMaterial.SPRUCE_WOOD, 7 ) ); + addBlockToSellallList( new SellAllBlockData( XMaterial.ACACIA_WOOD, 7 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.BIRCH_WOOD, 7 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.DARK_OAK_WOOD, 7 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.JUNGLE_WOOD, 7 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.OAK_WOOD, 7 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.SPRUCE_WOOD, 7 ), blockList ); -// blockList.add( new SellAllBlockData( XMaterial.IRON_NUGGET, 3 ) ); -// blockList.add( new SellAllBlockData( XMaterial.IRON_INGOT, 27 ) ); +// addBlockToSellallList( new SellAllBlockData( XMaterial.IRON_NUGGET, 3 ), blockList ); +// addBlockToSellallList( new SellAllBlockData( XMaterial.IRON_INGOT, 27 ), blockList ); // -// blockList.add( new SellAllBlockData( XMaterial.GOLD_NUGGET, 12 ) ); -// blockList.add( new SellAllBlockData( XMaterial.GOLD_INGOT, 108 ) ); +// addBlockToSellallList( new SellAllBlockData( XMaterial.GOLD_NUGGET, 12 ), blockList ); +// addBlockToSellallList( new SellAllBlockData( XMaterial.GOLD_INGOT, 108 ), blockList ); // -// blockList.add( new SellAllBlockData( XMaterial.REDSTONE, 45 ) ); +// addBlockToSellallList( new SellAllBlockData( XMaterial.REDSTONE, 45 ), blockList ); - blockList.add( new SellAllBlockData( XMaterial.GLOWSTONE, 52 ) ); - blockList.add( new SellAllBlockData( XMaterial.GLOWSTONE_DUST, 14 ) ); + addBlockToSellallList( new SellAllBlockData( XMaterial.GLOWSTONE, 52 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.GLOWSTONE_DUST, 14 ), blockList ); -// blockList.add( new SellAllBlockData( XMaterial.COAL, 15 ) ); -// blockList.add( new SellAllBlockData( XMaterial.DIAMOND, 200 ) ); +// addBlockToSellallList( new SellAllBlockData( XMaterial.COAL, 15 ), blockList ); +// addBlockToSellallList( new SellAllBlockData( XMaterial.DIAMOND, 200 ), blockList ); - blockList.add( new SellAllBlockData( XMaterial.SUGAR_CANE, 13 ) ); - blockList.add( new SellAllBlockData( XMaterial.SUGAR, 13 ) ); - blockList.add( new SellAllBlockData( XMaterial.PAPER, 13 ) ); + addBlockToSellallList( new SellAllBlockData( XMaterial.SUGAR_CANE, 13 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.SUGAR, 13 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.PAPER, 13 ), blockList ); - 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 ) ); + addBlockToSellallList( new SellAllBlockData( XMaterial.SOUL_SAND, 25 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.BROWN_MUSHROOM, 5 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.BROWN_MUSHROOM_BLOCK, 5 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.RED_MUSHROOM, 5 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.RED_MUSHROOM_BLOCK, 5 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.SLIME_BALL, 7 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.SLIME_BLOCK, 63 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.PACKED_ICE, 7 ), blockList ); - blockList.add( new SellAllBlockData( XMaterial.BRICK, 4 ) ); - blockList.add( new SellAllBlockData( XMaterial.BRICKS, 16 ) ); // 1 bricks = 4 brick + addBlockToSellallList( new SellAllBlockData( XMaterial.BRICK, 4 ), blockList ); + addBlockToSellallList( new SellAllBlockData( XMaterial.BRICKS, 16 ), blockList ); // 1 bricks = 4 brick + return blockList; } + private void addBlockToSellallList( SellAllBlockData saBlockData, List blockList ) { + + org.bukkit.inventory.ItemStack itemStack = saBlockData.getBlock().parseItem(); + + // Exclude invalid blocks since the sellall list includes block names from 1.8 through 1.21+ + if ( itemStack != null ) { + blockList.add( saBlockData ); + } + + } + // /** // * This listing of blocks is based strictly upon the old prison's block // * model. From fcc227fec83e2d6dbba11db33cce5d04ad4e64b8 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 26 Sep 2024 04:26:20 -0400 Subject: [PATCH 208/323] Prison v3.3.0-alpha.19d 2024-09-26 --- docs/changelog_v3.3.x.md | 8 +++++++- gradle.properties | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 508f0c8fc..0e8834aa5 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.19c 2024-09-26 +# 3.3.0-alpha.19d 2024-09-26 + + + + +** 3.3.0-alpha.19d 2024-09-26** + * **Prison blocks: It was realized that due to a recent expansion of the items that are included in the default for sellall, that the first 27 or so entries, were the blocks that were used in the auto generated mines when running the command '/ranks autoConfigure'.** diff --git a/gradle.properties b/gradle.properties index a056f7c57..d4040c53b 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.19c +version=3.3.0-alpha.19d From 9eaa32678e5d9bed426ab45773dba38eae8b9fbd Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 28 Sep 2024 14:40:06 -0400 Subject: [PATCH 209/323] Mine Bombs: Improve the debugging information on when mine bombs are selected, or rejected based upon the player having access to the mine or if a cooldown has rejected the mine bomb. SpigotPlayer: Using bukkit's block.isPassable() on getLineOfSight(), but may need to be extended to getLineOfsightExactLocation(). --- docs/changelog_v3.3.x.md | 6 ++- .../tech/mcprison/prison/bombs/MineBombs.java | 16 ++++++ .../prison/spigot/game/SpigotPlayer.java | 29 +++++++++- .../spigot/utils/PrisonBombListener.java | 54 +++++++++++++------ 4 files changed, 86 insertions(+), 19 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 0e8834aa5..abd6fd1f3 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,15 +14,17 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.19d 2024-09-26 +# 3.3.0-alpha.19d 2024-09-28 +* **Mine Bombs: Improve the debugging information on when mine bombs are selected, or rejected based upon the player having access to the mine or if a cooldown has rejected the mine bomb.** +SpigotPlayer: Using bukkit's block.isPassable() on getLineOfSight(), but may need to be extended to getLineOfsightExactLocation(). +It was not clear why mine bombs were not working. ** 3.3.0-alpha.19d 2024-09-26** - * **Prison blocks: It was realized that due to a recent expansion of the items that are included in the default for sellall, that the first 27 or so entries, were the blocks that were used in the auto generated mines when running the command '/ranks autoConfigure'.** These first few blocks, were returned to their proper place so the mines are properly populated again. Also, since blocks from multiple versions of spigot have been added, new code has been added to prevent adding any block that is not support by the version of spigot that the server is running. 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 132e17718..8999f05d0 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 @@ -271,8 +271,11 @@ public MineBombData findBombByName( Player player, String bombName ) { MineBombData results = null; + StringBuilder dbug = new StringBuilder(); String cleanedBombName = Text.stripColor( bombName.toLowerCase() ); + + dbug.append( "&3## findBombByName: [&a" ).append( cleanedBombName ).append( "&3] "); if ( cleanedBombName != null && !cleanedBombName.isEmpty() ) { for ( String bombKey : getConfigData().getBombs().keySet() ) @@ -286,6 +289,8 @@ public MineBombData findBombByName( Player player, String bombName ) (cBombName.equalsIgnoreCase( cleanedBombName ) || cleanedBombName.equalsIgnoreCase( bombKey )) ) { + dbug.append( " &aMatch! &3" ); + results = bomb; } } @@ -302,6 +307,8 @@ public MineBombData findBombByName( Player player, String bombName ) if ( cooldownTicks <= 0 ) { // Submit another cooldown: MineBombCooldownTask.addPlayerCooldown( player, ticks ); + + dbug.append( "&3 StartCoolDown: " ).append( ticks ).append( " ticks" ); } else { // The player is still in a cooldown using minebombs, so @@ -311,10 +318,19 @@ public MineBombData findBombByName( Player player, String bombName ) // player.sendMessage( String.format( message, bombName ) ); + + dbug.append( "&3 CoolDownIsInEffect: " ) + .append( cooldownTicks ).append( " ticks remaining" ).append(" &aRejected! &3 " ); results = null; } } + dbug.append( " &3Results: ").append( results == null ? "&cFail-NoBomb" : "&aSuccess" ); + + if ( Output.get().isDebug() ) { + Output.get().logInfo( dbug.toString() ); + } + return results == null ? null : results.clone(); } 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 6ad2ec60c..def2d537e 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 @@ -252,8 +252,10 @@ public SpigotBlock getLineOfSightBlock() { List blocks = bukkitPlayer.getLineOfSight( null, 256 ); for ( Block block : blocks ) { - if ( block != null && block.getType() != Material.AIR ) { + if ( block != null && block.getType() != Material.AIR && + !block.isPassable() ) { + // return the first non-null and non-AIR block, which will // be the one the player is looking at: results = SpigotBlock.getSpigotBlock( block ); @@ -264,6 +266,25 @@ public SpigotBlock getLineOfSightBlock() { } + /** + *

This uses the line of sight to get an exact location of where the player + * is clicking. Normally, when selecting a block, only the block's location + * is accessible which is basically integer resolution, although the player maybe + * clicking somewhere in the middle of a block. This gives a way to finely + * select where they were looking, instead of just the block they were + * looking at and clicking on. + *

+ * + *

Please notice that there may be issues with this code. Review the + * other function in this class 'getLineOfSightBlock()' in that it uses + * bukkit's block.isPassible(). That function does not exist in the + * prison block and may need to be added. Currently it's not possible to + * be added at this time since too many other changes are in effect within + * prison. This is a note and a placeholder for these possible changes. + *

+ * + * @return + */ public Location getLineOfSightExactLocation() { SpigotLocation eyeLoc = new SpigotLocation( getWrapper().getEyeLocation() ); @@ -272,7 +293,11 @@ public Location getLineOfSightExactLocation() { Location loc = eyeLoc.add(eyeVec); int i = 0; - while ( i++ <= 50 && loc.getBlockAt().isEmpty() ) { + + // Is isPassible also true when isEmpty? If so, then this could be simplified... + // while ( i++ <= 75 && (loc.getBlockAt().isEmpty() || loc.getBlockAt().isPassible()) ) { + + while ( i++ <= 75 && loc.getBlockAt().isEmpty() ) { loc = loc.add(eyeVec); } 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 8ed01ef22..8ce5ae8a5 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 @@ -95,12 +95,12 @@ public void mineBombPlacementEvent( BlockPlaceEvent event ) { Block targetBlock = event.getBlockAgainst(); - SpigotBlock lsBlock = sPlayer.getLineOfSightBlock(); +// SpigotBlock lsBlock = sPlayer.getLineOfSightBlock(); - Output.get().logInfo( - "### Place mine bomb: mineBombPlacementEvent: block: %s sight: %s", - targetBlock.getLocation().toString(), - lsBlock.getLocation().toString() ); +// Output.get().logInfo( +// "### Place mine bomb: mineBombPlacementEvent: block: %s sight: %s", +// targetBlock.getLocation().toString(), +// lsBlock.getLocation().toString() ); EquipmentSlot hand = SpigotCompatibility.getInstance().getHand(event); @@ -351,21 +351,45 @@ public void bombPlacementEvent( PlayerInteractEvent event ) { Location losLoc = sPlayer.getLineOfSightExactLocation(); - // The placedBombLocation will be used as the center point of the animation: - mineBomb.setPlacedBombLocation( losLoc ); - - Output.get().logInfo( - "### Place mine bomb: bombPlacementEvent: block: %s " - + "sight: %s LineOfSight: %s ", - new SpigotLocation( targetBlock.getLocation()).toString(), - lsBlock.getLocation().toString(), - (losLoc == null ? "null" : losLoc.toString()) ); - if ( losLoc != null ) { + + // The placedBombLocation will be used as the center point of the animation: + mineBomb.setPlacedBombLocation( losLoc ); + lsBlock = (SpigotBlock) losLoc.getBlockAt(); targetBlock = lsBlock.getWrapper(); } + else { + Location loc = new SpigotLocation( targetBlock.getLocation() ); + + mineBomb.setPlacedBombLocation( loc ); + + lsBlock = (SpigotBlock) loc.getBlockAt(); + + targetBlock = lsBlock.getWrapper(); + + if ( Output.get().isDebug() ) { + + String msg = "&3MineBombListener: LineOfSight was not able to be " + + "established to get the exactly placement locaiton. " + + "Falling back onv original targetBlock's location."; + Output.get().logInfo( msg ); + } + } + +// Output.get().logInfo( +// "### Place mine bomb: bombPlacementEvent: block: %s " +// + "sight: %s LineOfSight: %s ", +// new SpigotLocation( targetBlock.getLocation()).toString(), +// lsBlock.getLocation().toString(), +// (losLoc == null ? "null" : losLoc.toString()) ); + +// if ( losLoc != null ) { +// lsBlock = (SpigotBlock) losLoc.getBlockAt(); +// +// targetBlock = lsBlock.getWrapper(); +// } From fdccd802e730bd9c043f8f55533919e5cf327402 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 28 Sep 2024 14:47:27 -0400 Subject: [PATCH 210/323] PrisonBlock: Fix an issue with PrisonBlock setting a class variable that is also set within it's parent class. Overall, at a rough level, this does not cause a problem with the current prison environment. It's wrong. But it works. Where it is failing is when prison is trying to setup ORM on the Mine object to simplify and expand the capability of future enhancements. --- docs/changelog_v3.3.x.md | 5 +++++ .../prison/internal/block/PrisonBlock.java | 16 ++++++++-------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index abd6fd1f3..13c0b11ac 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.19d 2024-09-28 +* **PrisonBlock: Fix an issue with PrisonBlock setting a class variable that is also set within it's parent class.** +Overall, at a rough level, this does not cause a problem with the current prison environment. It's wrong. But it works. +Where it is failing is when prison is trying to setup ORM on the Mine object to simplify and expand the capability of future enhancements.. + + * **Mine Bombs: Improve the debugging information on when mine bombs are selected, or rejected based upon the player having access to the mine or if a cooldown has rejected the mine bomb.** SpigotPlayer: Using bukkit's block.isPassable() on getLineOfSight(), but may need to be extended to getLineOfsightExactLocation(). It was not clear why mine bombs were not working. 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 58a6cdd3b..cd97fb775 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 @@ -29,7 +29,7 @@ public class PrisonBlock public static PrisonBlock IGNORE; public static PrisonBlock NULL_BLOCK; - private PrisonBlockType blockType; +// private PrisonBlockType blockType; private boolean useBlockTypeAsPrefix = false; // private String blockName; @@ -101,7 +101,7 @@ public PrisonBlock( String blockName, boolean block ) { public PrisonBlock( PrisonBlockType blockType, String blockName, double chance, long blockCountTotal ) { super( blockType, blockName, chance, blockCountTotal ); - this.blockType = blockType; +// this.blockType = blockType; // this.blockName = blockName.toLowerCase(); // this.chance = chance; @@ -130,12 +130,12 @@ public String toString() { ( getChance() > 0 ? " " + Double.toString( getChance()) : ""); } - public PrisonBlockType getBlockType() { - return blockType; - } - public void setBlockType( PrisonBlockType blockType ) { - this.blockType = blockType; - } +// public PrisonBlockType getBlockType() { +// return blockType; +// } +// public void setBlockType( PrisonBlockType blockType ) { +// this.blockType = blockType; +// } // public String getBlockName() { // return blockName; From 3444d4b414507bae698bc46823e1ef7f0f48e93e Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 28 Sep 2024 14:52:21 -0400 Subject: [PATCH 211/323] Auto Features: clear bukkit clearDrops. An issue using an older version of prison resulted in the targetBlock being null. This has not been reproduceable with the current version of prison, so it's probably been fixed at it's root levels. But this change was made just to ensure it does not become an issue in the future. --- docs/changelog_v3.3.x.md | 4 ++++ .../prison/spigot/block/OnBlockBreakMines.java | 10 +++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 13c0b11ac..a780cfbba 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.19d 2024-09-28 +* **Auto Features: clear bukkit clearDrops.** +An issue using an older version of prison resulted in the targetBlock being null. This has not been reproduceable with the current version of prison, so it's probably been fixed at it's root levels. But this change was made just to ensure it does not become an issue in the future. + + * **PrisonBlock: Fix an issue with PrisonBlock setting a class variable that is also set within it's parent class.** Overall, at a rough level, this does not cause a problem with the current prison environment. It's wrong. But it works. Where it is failing is when prison is trying to setup ORM on the Mine object to simplify and expand the capability of future enhancements.. 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 92290583f..b958caaf8 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 @@ -919,10 +919,14 @@ private void getSpigotDrops( List bukkitDrops, SpigotBlock sBlo public void clearBukkitDrops( List bukkitDrops, MineTargetPrisonBlock targetBlock ) { + if ( targetBlock != null ) { + SpigotBlock sBlock = (SpigotBlock) targetBlock.getMinedBlock(); - SpigotBlock sBlock = (SpigotBlock) targetBlock.getMinedBlock(); - sBlock.clearDrops(); - + if ( sBlock != null ) { + + sBlock.clearDrops(); + } + } } From 30f78bd5b875823bd8b1d4ceed3884f32e9ad05e Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 28 Sep 2024 16:41:39 -0400 Subject: [PATCH 212/323] Mines: reconnectObjects() is a way to re-hooked up objects that could not be saved/stored when loading these objects from the database/files. These currently are not enabled or tested yet, but they are the foundation of getting the new process working to support a new way of storing and loading data. --- .../internal/block/MineTargetBlockKey.java | 22 +++++++++- .../tech/mcprison/prison/util/Bounds.java | 33 +++++++++++++++ .../tech/mcprison/prison/util/Location.java | 40 ++++++++++++++++++- .../tech/mcprison/prison/util/BoundsTest.java | 9 +++-- 4 files changed, 98 insertions(+), 6 deletions(-) diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/block/MineTargetBlockKey.java b/prison-core/src/main/java/tech/mcprison/prison/internal/block/MineTargetBlockKey.java index e527fbffe..ff4f56922 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/block/MineTargetBlockKey.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/block/MineTargetBlockKey.java @@ -1,18 +1,34 @@ package tech.mcprison.prison.internal.block; import tech.mcprison.prison.internal.World; +import tech.mcprison.prison.output.Output; import tech.mcprison.prison.util.Location; public class MineTargetBlockKey implements Comparable { - private final World world; + private final String worldName; + private final transient World world; private final int x, y, z; + public MineTargetBlockKey() { + super(); + + this.world = null; + this.worldName = null; + + this.x = 0; + this.y = 0; + this.z = 0; + +// Output.get().logInfo( "MineTargetBlockKey: World and coordinates need to be set." ); + } + public MineTargetBlockKey( World world, int x, int y, int z ) { super(); this.world = world; + this.worldName = world == null ? null : world.getName(); this.x = x; this.y = y; @@ -44,6 +60,10 @@ public World getWorld() { return world; } + public String getWorldName() { + return worldName; + } + public int getX() { return x; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/util/Bounds.java b/prison-core/src/main/java/tech/mcprison/prison/util/Bounds.java index 39de171b9..deed8bbc5 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/util/Bounds.java +++ b/prison-core/src/main/java/tech/mcprison/prison/util/Bounds.java @@ -18,6 +18,8 @@ package tech.mcprison.prison.util; +import java.util.Optional; + import tech.mcprison.prison.Prison; import tech.mcprison.prison.internal.World; @@ -298,6 +300,37 @@ public Bounds( Bounds bounds, Edges edge, int amount ) { } + + /** + *

This function should be called after loading a mine from + * storage, and this function should reconnect all dynamic objects + * that could not be stored with the core Mine data. + *

+ * + *

Examples: World objects. + *

+ */ + public void reconnectObjects() { + + if ( getMin() != null && getMin().getWorld() == null ) { + String worldName = getMin().getWorldName(); + + Optional worldOpt = Prison.get().getPlatform().getWorld(worldName); + + if ( worldOpt.isPresent() ) { + World world = worldOpt.get(); + + setWorld( world ); + } + } + } + + /** + *

Sets the world on the min, max, and center objects. + *

+ * + * @param world + */ public void setWorld( World world ) { if ( world != null ) { 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 fea3f5495..960d018b3 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 @@ -19,6 +19,7 @@ package tech.mcprison.prison.util; import java.text.DecimalFormat; +import java.util.Optional; import tech.mcprison.prison.Prison; import tech.mcprison.prison.bombs.MineBombs.AnimationArmorStandItemLocation; @@ -37,7 +38,9 @@ */ public class Location { - private World world; + private transient World world; + private String worldName; + private double x, y, z; private float pitch, yaw; @@ -48,6 +51,8 @@ public class Location { public Location(World world, double x, double y, double z, float pitch, float yaw, Vector direction) { this.world = world; + this.worldName = world == null ? null : world.getName(); + this.x = x; this.y = y; this.z = z; @@ -79,6 +84,30 @@ public Location clone() { return new Location( this ); } + + /** + *

This function should be called after loading a mine from + * storage, and this function should reconnect all dynamic objects + * that could not be stored with the core Mine data. + *

+ * + *

Examples: World objects. + *

+ */ + public void reconnectObects() { + if ( getWorld() == null ) { + String worldName = getWorldName(); + + Optional worldOpt = Prison.get().getPlatform().getWorld(worldName); + + if ( worldOpt.isPresent() ) { + World world = worldOpt.get(); + + setWorld( world ); + } + } + } + public World getWorld() { return world; } @@ -87,7 +116,14 @@ public void setWorld(World world) { this.world = world; } - public double getX() { + public String getWorldName() { + return worldName; + } + public void setWorldName(String worldName) { + this.worldName = worldName; + } + + public double getX() { return x; } diff --git a/prison-core/src/test/java/tech/mcprison/prison/util/BoundsTest.java b/prison-core/src/test/java/tech/mcprison/prison/util/BoundsTest.java index 7593fd0db..fe8c78a1f 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/util/BoundsTest.java +++ b/prison-core/src/test/java/tech/mcprison/prison/util/BoundsTest.java @@ -30,7 +30,8 @@ */ public class BoundsTest { - @Test public void equals() throws Exception { + @Test + public void equals() throws Exception { Bounds bounds = new Bounds(new Location(null, 0.0, 0.0, 0.0), new Location(null, 10.0, 10.0, 10.0)); Bounds otherBounds = @@ -39,11 +40,13 @@ public class BoundsTest { assertTrue(bounds.equals(otherBounds)); } - @Test public void fail() throws Exception { + @Test + public void fail() throws Exception { assertTrue( true ); } - @Test public void within() throws Exception { + @Test + public void within() throws Exception { TestWorld world1 = new TestWorld("test1"); // TestWorld world2 = new TestWorld("test2"); Location loc1 = new Location(world1, 0.0, 4.0, 0.0); From bf12a170604217e2593f30b0edaafc37133a7131 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 28 Sep 2024 17:27:08 -0400 Subject: [PATCH 213/323] Mines: relocate a few objects to pull them out of MineData since they are constants. --- docs/changelog_v3.3.x.md | 7 +++ .../internal/block/PrisonBlockStatusData.java | 4 ++ .../prison/mines/commands/MinesCommands.java | 25 +++++----- .../mines/commands/MinesImportCommands.java | 4 +- .../tech/mcprison/prison/mines/data/Mine.java | 40 ++++++++++++++++ .../mcprison/prison/mines/data/MineData.java | 46 ++----------------- .../prison/mines/data/MinesConfig.java | 2 +- .../prison/spigot/SpigotPlatform.java | 2 +- 8 files changed, 72 insertions(+), 58 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index a780cfbba..3d030a4fb 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.19d 2024-09-28 +* **Mines: relocate a few objects to pull them out of MineData since they are constants.** + + +* **Mines: reconnectObjects() is a way to re-hooked up objects that could not be saved/stored when loading these objects from the database/files.** +These currently are not enabled or tested yet, but they are the foundation of getting the new process working to support a new way of storing and loading data. + + * **Auto Features: clear bukkit clearDrops.** An issue using an older version of prison resulted in the targetBlock being null. This has not been reproduceable with the current version of prison, so it's probably been fixed at it's root levels. But this change was made just to ensure it does not become an issue in the future. diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/block/PrisonBlockStatusData.java b/prison-core/src/main/java/tech/mcprison/prison/internal/block/PrisonBlockStatusData.java index 1b5a7ed23..199f0f738 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/block/PrisonBlockStatusData.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/block/PrisonBlockStatusData.java @@ -55,6 +55,10 @@ public abstract class PrisonBlockStatusData { private transient int altCountPhysical; + public PrisonBlockStatusData() { + super(); + } + public PrisonBlockStatusData( PrisonBlockType blockType, String blockName, String displayName, double chance, long blockCountTotal ) { 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 1c26fb8c6..faded21e5 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 @@ -42,8 +42,7 @@ import tech.mcprison.prison.internal.block.PrisonBlock; import tech.mcprison.prison.mines.PrisonMines; import tech.mcprison.prison.mines.data.Mine; -import tech.mcprison.prison.mines.data.MineData; -import tech.mcprison.prison.mines.data.MineData.MineNotificationMode; +import tech.mcprison.prison.mines.data.Mine.MineNotificationMode; import tech.mcprison.prison.mines.data.MineScheduler.MineResetActions; import tech.mcprison.prison.mines.data.MineScheduler.MineResetScheduleType; import tech.mcprison.prison.mines.data.PrisonSortableResults; @@ -1994,15 +1993,15 @@ public void skipResetCommand(CommandSender sender, public void resetTimeCommand(CommandSender sender, @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. " + + "With a minimum value of "+ Mine.MINE_RESET__TIME_SEC__MINIMUM + " seconds. " + "Using '*disable*' will turn off the auto reset. Use of " + "*default* will set the time to " + - MineData.MINE_RESET__TIME_SEC__DEFAULT + " seconds. " + Mine.MINE_RESET__TIME_SEC__DEFAULT + " seconds. " + "[*default* *disable*]" ) String time ) { - int resetTime = MineData.MINE_RESET__TIME_SEC__DEFAULT; + int resetTime = Mine.MINE_RESET__TIME_SEC__DEFAULT; PrisonMines pMines = PrisonMines.getInstance(); @@ -2021,14 +2020,14 @@ else if ( "*default*".equalsIgnoreCase( time ) ) { catch ( NumberFormatException e ) { Output.get().sendWarn( sender, "&7Invalid resetTime value for &b%s&7. Must be an integer value of &b%d &7or greater. [&b%s&7]", - mineName, MineData.MINE_RESET__TIME_SEC__MINIMUM, time ); + mineName, Mine.MINE_RESET__TIME_SEC__MINIMUM, time ); return; } } - if ( !"*disable*".equalsIgnoreCase( time ) && resetTime < MineData.MINE_RESET__TIME_SEC__MINIMUM ) { + if ( !"*disable*".equalsIgnoreCase( time ) && resetTime < Mine.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 ); + mineName, Mine.MINE_RESET__TIME_SEC__MINIMUM, resetTime ); return; } @@ -2337,17 +2336,17 @@ public void setNotificationCommand(CommandSender sender, long noteRadius = 0L; if ( noteMode == MineNotificationMode.radius ) { if ( radius == null || radius.trim().length() == 0 ) { - noteRadius = MineData.MINE_RESET__BROADCAST_RADIUS_BLOCKS; + noteRadius = Mine.MINE_RESET__BROADCAST_RADIUS_BLOCKS; } else { try { noteRadius = Long.parseLong( radius ); if ( noteRadius < 1 ) { - noteRadius = MineData.MINE_RESET__BROADCAST_RADIUS_BLOCKS; + noteRadius = Mine.MINE_RESET__BROADCAST_RADIUS_BLOCKS; DecimalFormat dFmt = Prison.get().getDecimalFormatInt(); Output.get().sendWarn( sender, "&7Invalid radius value. " + "Must be an positive non-zero integer. Using the default value: &b%s &7[&b%s&7]", - dFmt.format(MineData.MINE_RESET__BROADCAST_RADIUS_BLOCKS), radius ); + dFmt.format(Mine.MINE_RESET__BROADCAST_RADIUS_BLOCKS), radius ); return; } } @@ -3680,7 +3679,7 @@ public void mineWhereAmI(CommandSender sender) { // some arbitrary distance as a max radius. We do not want to use the individual values // that have been set for each mine. else if ( !mine.isVirtual() && mine.getBounds().within( player.getLocation(), - MineData.MINE_RESET__BROADCAST_RADIUS_BLOCKS) ) { + Mine.MINE_RESET__BROADCAST_RADIUS_BLOCKS) ) { Double distance = mine.getBounds().getDistance3d( player.getLocation() ); // Double distance = new Bounds( mine.getBounds().getCenter(), player.getLocation()).getDistance(); nearMine.put( distance.intValue(), mine ); @@ -3715,7 +3714,7 @@ else if ( !mine.isVirtual() && mine.getBounds().within( player.getLocation(), } else if ( inMine.size() == 0 ) { // you are not near any mines: - sender.sendMessage( "&3Sorry, you are not within " + MineData.MINE_RESET__BROADCAST_RADIUS_BLOCKS + + sender.sendMessage( "&3Sorry, you are not within " + Mine.MINE_RESET__BROADCAST_RADIUS_BLOCKS + " blocks from any mine." ); } diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesImportCommands.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesImportCommands.java index 1ca912e33..837d05c40 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesImportCommands.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesImportCommands.java @@ -14,14 +14,14 @@ import tech.mcprison.prison.internal.block.PrisonBlockTypes; import tech.mcprison.prison.mines.PrisonMines; import tech.mcprison.prison.mines.data.Mine; +import tech.mcprison.prison.mines.data.Mine.MineNotificationMode; import tech.mcprison.prison.mines.data.Mine.MineType; -import tech.mcprison.prison.mines.data.MineData.MineNotificationMode; import tech.mcprison.prison.mines.features.MineLinerBuilder; import tech.mcprison.prison.mines.features.MineLinerBuilder.LinerPatterns; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.selection.Selection; -import tech.mcprison.prison.util.Location; import tech.mcprison.prison.util.Bounds.Edges; +import tech.mcprison.prison.util.Location; public class MinesImportCommands extends MinesBlockCommands { diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/Mine.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/Mine.java index a98462376..e0345596c 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/Mine.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/Mine.java @@ -51,6 +51,13 @@ public class Mine implements PrisonSortable, Comparable, PlaceholderStringCoverter { + public static final int MINE_RESET__TIME_SEC__DEFAULT = 15 * 60; // 15 minutes + public static final int MINE_RESET__TIME_SEC__MINIMUM = 30; // 30 seconds + public static final long MINE_RESET__BROADCAST_RADIUS_BLOCKS = 150; + + public static final String MINE_NOTIFICATION_PERMISSION_PREFIX = "mines.notification."; + + public enum MineType { primary, playerMines @@ -75,6 +82,39 @@ public enum MineUnitTestUsage { TRUE; } + public enum MineNotificationMode { + disabled, + disable, + within, + radius, + world, + server, + + displayOptions + ; + + public static MineNotificationMode fromString(String mode) { + return fromString(mode, radius); + } + public static MineNotificationMode fromString(String mode, MineNotificationMode defaultValue) { + MineNotificationMode results = defaultValue; + + if ( mode != null && mode.trim().length() > 0 ) { + for ( MineNotificationMode mnm : values() ) { + if ( mnm.name().equalsIgnoreCase( mode )) { + results = mnm; + } + } + } + + if ( results == disable ) { + results = disabled; + } + + return results; + } + } + /** * Creates a new, empty mine instance */ diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineData.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineData.java index 817177a95..7da9a50f5 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineData.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineData.java @@ -14,6 +14,7 @@ import tech.mcprison.prison.internal.block.PrisonBlock; import tech.mcprison.prison.internal.block.PrisonBlock.PrisonBlockType; import tech.mcprison.prison.internal.block.PrisonBlockStatusData; +import tech.mcprison.prison.mines.data.Mine.MineNotificationMode; import tech.mcprison.prison.mines.data.Mine.MineType; import tech.mcprison.prison.mines.features.MineBlockEvent; import tech.mcprison.prison.mines.features.MineLinerData; @@ -26,12 +27,6 @@ public abstract class MineData implements ModuleElement { - public static final int MINE_RESET__TIME_SEC__DEFAULT = 15 * 60; // 15 minutes - public static final int MINE_RESET__TIME_SEC__MINIMUM = 30; // 30 seconds - public static final long MINE_RESET__BROADCAST_RADIUS_BLOCKS = 150; - - public static final String MINE_NOTIFICATION_PERMISSION_PREFIX = "mines.notification."; - private transient final ModuleElementType elementType; private String name; @@ -162,38 +157,7 @@ public abstract class MineData private transient boolean isDeleted = false; - public enum MineNotificationMode { - disabled, - disable, - within, - radius, - world, - server, - - displayOptions - ; - - public static MineNotificationMode fromString(String mode) { - return fromString(mode, radius); - } - public static MineNotificationMode fromString(String mode, MineNotificationMode defaultValue) { - MineNotificationMode results = defaultValue; - - if ( mode != null && mode.trim().length() > 0 ) { - for ( MineNotificationMode mnm : values() ) { - if ( mnm.name().equalsIgnoreCase( mode )) { - results = mnm; - } - } - } - - if ( results == disable ) { - results = disabled; - } - - return results; - } - } + public MineData() { @@ -223,9 +187,9 @@ public MineData() { */ this.sortOrder = 0; - this.resetTime = MINE_RESET__TIME_SEC__DEFAULT; + this.resetTime = Mine.MINE_RESET__TIME_SEC__DEFAULT; this.notificationMode = MineNotificationMode.radius; - this.notificationRadius = MINE_RESET__BROADCAST_RADIUS_BLOCKS; + this.notificationRadius = Mine.MINE_RESET__BROADCAST_RADIUS_BLOCKS; this.useNotificationPermission = false; this.targetResetTime = 0; @@ -1145,7 +1109,7 @@ public void setUseNotificationPermission( boolean useNotificationPermission ) { } public String getMineNotificationPermissionName() { - return MINE_NOTIFICATION_PERMISSION_PREFIX + getName().toLowerCase(); + return Mine.MINE_NOTIFICATION_PERMISSION_PREFIX + getName().toLowerCase(); } /** diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MinesConfig.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MinesConfig.java index 008da7dda..3489cff3f 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MinesConfig.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MinesConfig.java @@ -55,7 +55,7 @@ public class MinesConfig implements FileIOData { /** * The duration between mine resets in seconds. */ - public int resetTime = MineData.MINE_RESET__TIME_SEC__DEFAULT; + public int resetTime = Mine.MINE_RESET__TIME_SEC__DEFAULT; // /** // * The worlds that reset messages should be broadcasted to. Ignored if multiworld 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 f5fd6b70c..4e7da4217 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 @@ -91,7 +91,7 @@ import tech.mcprison.prison.mines.PrisonMines; import tech.mcprison.prison.mines.commands.MinesCommands; import tech.mcprison.prison.mines.data.Mine; -import tech.mcprison.prison.mines.data.MineData.MineNotificationMode; +import tech.mcprison.prison.mines.data.Mine.MineNotificationMode; import tech.mcprison.prison.mines.features.MineLinerBuilder.LinerPatterns; import tech.mcprison.prison.mines.managers.MineManager; import tech.mcprison.prison.modules.Module; From 433650fa6b2081fd833bbd935f30ed576c190de2 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 28 Sep 2024 17:33:28 -0400 Subject: [PATCH 214/323] Ranks: a user reported a null pointer issue so made some changes to prevent it. Was not able to reproduce it. --- docs/changelog_v3.3.x.md | 4 ++++ .../src/main/java/tech/mcprison/prison/ranks/RankUtil.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 3d030a4fb..1532558b0 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.19d 2024-09-28 +* **Ranks: a user reported a null pointer issue so made some changes to prevent it.*** +Was not able to reproduce it. + + * **Mines: relocate a few objects to pull them out of MineData since they are constants.** diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/RankUtil.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/RankUtil.java index 08001c4c0..e52dc159c 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/RankUtil.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/RankUtil.java @@ -600,8 +600,8 @@ else if ( pForceCharge == PromoteForceCharge.refund_player) { // Validate that the player's rank was actually changed: PlayerRank newRank = rankPlayer.getPlayerRank( ladderName ); - if ( newRank.equals( originalRank ) || - !targetRank.equals( newRank.getRank() ) ) { + if ( newRank != null && (newRank.equals( originalRank ) || + !targetRank.equals( newRank.getRank() )) ) { results.setUnexpectedRank( newRank.getRank() ); From a936895568eb6ef8ceb107f10d0a1cd2e8fd6095 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 28 Sep 2024 17:40:47 -0400 Subject: [PATCH 215/323] Mines: adding transient to Mine data so it will not try to save the temporary and transient data when using ORM is generating json data from it. --- docs/changelog_v3.3.x.md | 3 ++ .../mcprison/prison/mines/data/MineData.java | 35 ++++++++++------ .../mcprison/prison/mines/data/MineReset.java | 42 +++++++++---------- .../prison/mines/data/MineScheduler.java | 8 ++-- .../mcprison/prison/mines/data/MineTasks.java | 1 + 5 files changed, 51 insertions(+), 38 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 1532558b0..66b61bcd2 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.19d 2024-09-28 +* **Mines: adding transient to Mine data so it will not try to save the temporary and transient data when using ORM is generating json data from it.** + + * **Ranks: a user reported a null pointer issue so made some changes to prevent it.*** Was not able to reproduce it. diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineData.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineData.java index 7da9a50f5..38c009457 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineData.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineData.java @@ -26,18 +26,20 @@ public abstract class MineData implements ModuleElement { + + private int dataVersion = 1; private transient final ModuleElementType elementType; private String name; private String tag; - private boolean enabled = false; + private transient boolean enabled = false; private boolean virtual = false; // Controls if a mine is able to be used during a mine reset: - private MineStateMutex mineStateMutex; + private transient MineStateMutex mineStateMutex; private MineType mineType; @@ -68,10 +70,10 @@ public abstract class MineData private long notificationRadius; private boolean useNotificationPermission = false; - private long targetResetTime; - private int resetCount = 0; + private transient long targetResetTime; + private transient int resetCount = 0; - private long lastResetTimeLong = 0; + private transient long lastResetTimeLong = 0; /** * These blocks are obsolete, and are no longer used in prison, but they @@ -82,7 +84,7 @@ public abstract class MineData * supporting magic values with the older bukkit versions. */ @SuppressWarnings( "deprecation" ) - private List blocks; + private transient List blocks; /** * This list of PrisonBlocks represents the new Prison block model. Its @@ -102,7 +104,7 @@ public abstract class MineData private transient Set prisonBlockTypes; - private TreeMap blockStats; + private transient TreeMap blockStats; /** *

If any of the mine's blocks are effected by gravity, then this field @@ -129,13 +131,13 @@ public abstract class MineData private boolean skipResetEnabled = false; private double skipResetPercent; private int skipResetBypassLimit; - private transient int skipResetBypassCount; + private int skipResetBypassCount; private List resetCommands; // private boolean usePagingOnReset = false; - private ModuleElement rank; + private transient ModuleElement rank; /** * When loading mines, ranks will not have been loaded yet, so must * save the rankString to be paired to the Ranks later. @@ -150,9 +152,9 @@ public abstract class MineData private boolean mineSweeperEnabled; - private int mineSweeperCount; - private long mineSweeperTotalMs; - private long mineSweeperBlocksChanged; + private transient int mineSweeperCount; + private transient long mineSweeperTotalMs; + private transient long mineSweeperBlocksChanged; private transient boolean isDeleted = false; @@ -830,7 +832,7 @@ public PrisonBlockStatusData getBlockStats( String blockName ) { return results; } - public TreeMap getBlockStats() { + public TreeMap getBlockStats() { return blockStats; } @@ -996,6 +998,13 @@ public void setAccessPermission( String accessPermission ) { } + public int getDataVersion() { + return dataVersion; + } + public void setDataVersion(int dataVersion) { + this.dataVersion = dataVersion; + } + public MineType getMineType() { return mineType; } 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 71396056d..901bd530e 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 @@ -94,29 +94,29 @@ public abstract class MineReset public static final long MINE_RESET__AIR_COUNT_BASE_DELAY = 30000L; // 30 seconds - private List mineTargetPrisonBlocks = null; - private TreeMap mineTargetPrisonBlocksMap = null; + private transient List mineTargetPrisonBlocks = null; + private transient TreeMap mineTargetPrisonBlocksMap = null; - private MineJob currentJob; + private transient MineJob currentJob; - private int resetPage = 0; - private int resetPosition = 0; + private transient int resetPage = 0; + private transient int resetPosition = 0; - private long resetPageMaxPageElapsedTimeMs = -1; - private long resetPagePageSubmitDelayTicks = -1; - private long resetPageTimeoutCheckBlockCount = -1; + private transient long resetPageMaxPageElapsedTimeMs = -1; + private transient long resetPagePageSubmitDelayTicks = -1; + private transient long resetPageTimeoutCheckBlockCount = -1; - private int airCountOriginal = 0; - private int airCount = 0; - private long airCountTimestamp = 0L; - private long airCountElapsedTimeMs = 0L; + private transient int airCountOriginal = 0; + private transient int airCount = 0; + private transient long airCountTimestamp = 0L; + private transient long airCountElapsedTimeMs = 0L; - private long statsResetTimeMS = 0; - private long statsBlockGenTimeMS = 0; - private long statsBlockUpdateTimeMS = 0; - private long statsBlockUpdateTimeNanos = 0; + private transient long statsResetTimeMS = 0; + private transient long statsBlockGenTimeMS = 0; + private transient long statsBlockUpdateTimeMS = 0; + private transient long statsBlockUpdateTimeNanos = 0; // Note: The time it takes to teleport players and broadcast is so trivial // that they are being disabled to reduce the clutter and memory load. @@ -124,13 +124,13 @@ public abstract class MineReset // private long statsTeleport2TimeMS = 0; // private long statsMessageBroadcastTimeMS = 0; - private int statsResetPages = 0; - private long statsResetPageBlocks = 0; - private long statsResetPageMs = 0; + private transient int statsResetPages = 0; + private transient long statsResetPageBlocks = 0; + private transient long statsResetPageMs = 0; - private List statsMineSweeperTaskMs; - private boolean mineSweeperSubmitted = false; + private transient List statsMineSweeperTaskMs; + private transient boolean mineSweeperSubmitted = false; public MineReset() { super(); diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineScheduler.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineScheduler.java index 2e1cc07ec..bf1d23288 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineScheduler.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineScheduler.java @@ -44,10 +44,10 @@ public abstract class MineScheduler * once a workflow cycle has been completed. *

*/ - private List jobWorkflow; - private Stack jobStack; -// private MineJob currentJob; - private Integer taskId = null; + private transient List jobWorkflow; + private transient Stack jobStack; +// private transient MineJob currentJob; + private transient Integer taskId = null; private transient long mineResetStartTimestamp; diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineTasks.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineTasks.java index ab4af8375..282d3d05d 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineTasks.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineTasks.java @@ -8,6 +8,7 @@ import tech.mcprison.prison.internal.block.Block; import tech.mcprison.prison.internal.block.PrisonBlock; import tech.mcprison.prison.mines.PrisonMines; +import tech.mcprison.prison.mines.data.Mine.MineNotificationMode; import tech.mcprison.prison.mines.data.MineScheduler.MineJob; import tech.mcprison.prison.mines.tasks.MineChangeBlockTask; import tech.mcprison.prison.output.Output; From a530a36ecd0afb76cde665b927f9237bbcd603dd Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 28 Sep 2024 17:45:48 -0400 Subject: [PATCH 216/323] Mines: Hook up the reconnectObjects() function so it will be able to hook up the dependencies. This is not hooked up yet, but will be used with the new ORM json manager. --- docs/changelog_v3.3.x.md | 4 ++ .../mcprison/prison/mines/data/MineData.java | 50 +++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 66b61bcd2..f60923670 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.19d 2024-09-28 +* **Mines: Hook up the reconnectObjects() function so it will be able to hook up the dependencies.** +This is not hooked up yet, but will be used with the new ORM json manager. + + * **Mines: adding transient to Mine data so it will not try to save the temporary and transient data when using ORM is generating json data from it.** diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineData.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineData.java index 38c009457..66286a862 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineData.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineData.java @@ -235,6 +235,56 @@ protected void initialize() { } + /** + *

This function should be called after loading a mine from + * storage, and this function should reconnect all dynamic objects + * that could not be stored with the core Mine data. + *

+ * + *

Note: getWorld() is actually a helper to get a world object out of + * getBounds() and setWorld() sets the world on both getBounds() and getSpawn(). + *

+ * + *

Examples: World objects. There may be other objects that need to be reconnected. + *

+ */ + public void reconnectObjects() { + + if ( !isVirtual() ) { + + if ( getBounds() != null ) { + getBounds().reconnectObjects(); + } + + if ( getSpawn() != null ) { + getSpawn().reconnectObects(); + } + + // Note: getWorld() is actually a helper to get a world object out of + // getBounds() and setWorld() sets the world on both getBounds() and + // getSpawn(). + + + // The following two collections do not use World objects so they do not + // need to be reconnected: +// getPrisonBlocks(); +// getBlockStats(); + + } + +// if ( getWorld() == null ) { +// String worldName = getWorldName(); +// +// Optional worldOpt = Prison.get().getPlatform().getWorld(worldName); +// +// if ( worldOpt.isPresent() ) { +// World world = worldOpt.get(); +// +// setWorld( world ); +// } +// } + + } public boolean isEnabled() { From 95e4c3a33738d7300c33be81c06c49a91bfacdb0 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 28 Sep 2024 17:50:37 -0400 Subject: [PATCH 217/323] Mines: Hooking up a test dump to the mines commands so I can more easily test what JSON is generated with the current settings and configurations. --- docs/changelog_v3.3.x.md | 3 + .../prison/mines/commands/MinesCommands.java | 64 +++++++++++++++++++ .../tech/mcprison/prison/mines/data/Mine.java | 5 +- 3 files changed, 71 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index f60923670..bb40713ac 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.19d 2024-09-28 +* **Mines: Hooking up a test dump to the mines commands so I can more easily test what JSON is generated with the current settings and configurations.** + + * **Mines: Hook up the reconnectObjects() function so it will be able to hook up the dependencies.** This is not hooked up yet, but will be used with the new ORM json manager. 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 faded21e5..55e1516d6 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 @@ -23,6 +23,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Map.Entry; import java.util.Objects; import java.util.Optional; import java.util.Set; @@ -34,12 +35,15 @@ import tech.mcprison.prison.commands.Command; import tech.mcprison.prison.commands.CommandPagedData; import tech.mcprison.prison.commands.Wildcard; +import tech.mcprison.prison.file.JsonFileIO; import tech.mcprison.prison.internal.CommandSender; import tech.mcprison.prison.internal.Player; import tech.mcprison.prison.internal.World; import tech.mcprison.prison.internal.block.Block; import tech.mcprison.prison.internal.block.MineResetType; +import tech.mcprison.prison.internal.block.MineTargetPrisonBlock; import tech.mcprison.prison.internal.block.PrisonBlock; +import tech.mcprison.prison.internal.block.PrisonBlockStatusData; import tech.mcprison.prison.mines.PrisonMines; import tech.mcprison.prison.mines.data.Mine; import tech.mcprison.prison.mines.data.Mine.MineNotificationMode; @@ -5877,4 +5881,64 @@ else if ( "*global*".equalsIgnoreCase(mineName) ) { } } + + + public void minesDumpCommand(CommandSender sender, + @Arg(name = "mineName", description = "The name of the mine to dump") + String mineName ) { + + PrisonMines pMines = PrisonMines.getInstance(); + + Mine mine = pMines.getMine( mineName ); + + if ( mine != null ) { + + JsonFileIO jfio = new JsonFileIO(); + +// Gson gson = new GsonBuilder().registerTypeAdapter(IsBean.class, new InterfaceAdapter()).create(); + + DecimalFormat dFmt = new DecimalFormat( "####" ); + + int ser = (int) (Math.random() * 9999d); + + String fName = "temp_mines_" + dFmt.format(ser) + ".json"; + + File f = new File( Prison.get().getDataFolder(), fName); + + + try { + +// if ( mine.getBlockStats().size() > 0 ) { +// +// Entry block = mine.getBlockStats().firstEntry(); +// +// String blockJson = jfio.toString(block); +// +// Output.get().logInfo(blockJson); +// +// +// } + + String mineJson = jfio.toString(mine); + + + jfio.saveJsonFile(f, mine ); + + sender.sendMessage( "Mine dumpped to: " + f.getAbsolutePath() ); + } + catch (Exception e) { + + sender.sendMessage( "Mine dump error: " + e.getMessage() ); + e.printStackTrace(); + } + + } + else { + sender.sendMessage( "A valid mine name is required. Try again.");; + return; + } + + + + } } diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/Mine.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/Mine.java index e0345596c..3f63fc3b5 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/Mine.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/Mine.java @@ -25,6 +25,7 @@ import java.util.Set; import tech.mcprison.prison.Prison; +import tech.mcprison.prison.file.FileIOData; import tech.mcprison.prison.internal.World; import tech.mcprison.prison.internal.block.PrisonBlock; import tech.mcprison.prison.internal.block.PrisonBlockStatusData; @@ -48,7 +49,9 @@ @SuppressWarnings( "deprecation" ) public class Mine extends MineScheduler - implements PrisonSortable, Comparable, PlaceholderStringCoverter { + implements PrisonSortable, Comparable, + PlaceholderStringCoverter, + FileIOData { public static final int MINE_RESET__TIME_SEC__DEFAULT = 15 * 60; // 15 minutes From 1478e953d6bdb52531125315b61af0b858f2b2c2 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 28 Sep 2024 17:55:50 -0400 Subject: [PATCH 218/323] Mines: checking access. This change breaks down the access checks to see if a player has access to a given mine so it can be properly logged when in debug mode. It's been a problem trying to figure out why some events would work or wouldn't, now this will help identify access related conditions. Example is the use of mine bombs. --- docs/changelog_v3.3.x.md | 4 ++ .../mcprison/prison/mines/data/MineData.java | 52 +++++++++++++++---- 2 files changed, 47 insertions(+), 9 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index bb40713ac..1e3bc3bd1 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.19d 2024-09-28 +* **Mines: checking access. This change breaks down the access checks to see if a player has access to a given mine so it can be properly logged when in debug mode.** +It's been a problem trying to figure out why some events would work or wouldn't, now this will help identify access related conditions. Example is the use of mine bombs. + + * **Mines: Hooking up a test dump to the mines commands so I can more easily test what JSON is generated with the current settings and configurations.** diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineData.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineData.java index 66286a862..a294e429f 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineData.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineData.java @@ -1022,16 +1022,50 @@ public boolean hasTPAccess( Player player ) { public boolean hasMiningAccess( Player player ) { boolean results = false; - if ( isMineAccessByRank() && - Prison.get().getPlatform().isMineAccessibleByRank( player, this ) || - !isMineAccessByRank() && - isAccessPermissionEnabled() && player.hasPermission( getAccessPermission() ) - - /// Note: the following cannot be added here since it will grant access if both are disabled - // || !isMineAccessByRank() && !isAccessPermissionEnabled() - ) { + StringBuilder dbug = new StringBuilder(); + + dbug.append( "&3## hasMineAccess: mineAccessByRank: " ).append( isMineAccessByRank() ); + + /// Note: the following cannot be added here since it will grant access if both are disabled + // || !isMineAccessByRank() && !isAccessPermissionEnabled() - results = true; + if ( isMineAccessByRank() ) { + + if ( Prison.get().getPlatform().isMineAccessibleByRank( player, this ) ) { + + dbug.append( "Success!" ); + results = true; + } + else { + dbug.append( "&cFailed! &aPlayer does not have access based upon their rank." ); + } + + } + else { + + dbug.append( " accessByPerms: " ).append( isAccessPermissionEnabled() ); + + if ( isAccessPermissionEnabled() ) { + + if ( player.hasPermission( getAccessPermission() )) { + + dbug.append( "Success!" ); + results = true; + } + else { + dbug.append( "&cFailed! &aPlayer does not have access based upon the permission: [" ) + .append( getAccessPermission() == null ? "null" : getAccessPermission() ); + } + } + else { + + dbug.append( " &cFailed! &aMust have either accessByRank or accessByPerm enabled. " ); + } + + } + + if ( Output.get().isDebug() ) { + Output.get().logInfo( dbug.toString() ); } return results; From be90233e356af3c0998b1f3ae394b7337784abe0 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 11 Oct 2024 12:51:05 -0400 Subject: [PATCH 219/323] Update xseries to v11.3.0 from v11.2.1. --- docs/changelog_v3.3.x.md | 5 ++++- gradle/libs.versions.toml | 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 1e3bc3bd1..3f2aa3676 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.19d 2024-09-28 +# 3.3.0-alpha.19d 2024-10-11 + + +* **Update xseries to v11.3.0 from v11.2.1.** * **Mines: checking access. This change breaks down the access checks to see if a player has access to a given mine so it can be properly logged when in debug mode.** diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 49bb2cdda..560050228 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -34,7 +34,7 @@ commons-lang3 = "3.12.0" groovy = "3.0.9" gson = "2.10.1" spiget = "1.4.6-SNAPSHOT" -xseries = "11.2.1" +xseries = "11.3.0" junit = "4.12" guava = "31.1-jre" spigotApi = "1.13.2-R0.1-SNAPSHOT" From db088716fdb1d714e089ce2aaaf228dd1faaf23c Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 11 Oct 2024 12:52:45 -0400 Subject: [PATCH 220/323] Rankup: would not work for ladders other than default and prestiges. Fixed. --- docs/changelog_v3.3.x.md | 3 ++ .../prison/ranks/commands/RankUpCommand.java | 31 ++++++++++++------- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 3f2aa3676..36afc4304 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.19d 2024-10-11 +* **Rankup: would not work for ladders other than default and prestiges. Fixed.** + + * **Update xseries to v11.3.0 from v11.2.1.** 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 42161c4a0..c788a122b 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 @@ -261,7 +261,7 @@ public void rankUp(CommandSender sender, ); - if ( isDefaultBypassPermCheck || +; if ( isDefaultBypassPermCheck || isPrestigeBypassPermCheck || isLadderDefault && hasDefaultPerm || @@ -592,25 +592,34 @@ private boolean rankUpPrivate(CommandSender sender, String playerName, String la // Get the player's next rank on default ladder, or if at end then it will return the next // prestiges rank. - PlayerRank playerRankTarget = rankPlayer.getNextPlayerRank(); + PlayerRank playerRankTarget = null; - - // If the nextRank is null or the ladder does not match selected ladder, then exit: - if ( playerRankTarget == null || playerRankTarget.getRank() == null || - !playerRankTarget.getRank().getLadder().getName().equalsIgnoreCase( ladder ) ) { + if ( targetLadder.isDefault() || targetLadder.isPrestiges() ) { - return false; + playerRankTarget = rankPlayer.getNextPlayerRank(); + + // If the nextRank is null or the ladder does not match selected ladder, then exit: + if ( playerRankTarget == null || playerRankTarget.getRank() == null ) { + + if ( Output.get().isDebug() ) { + Output.get().logInfo( + "RankUp ladder= %s currentRank= %s " + + "No next default or prestige rank. At end of both ladders?", + ladder, rankCurrent.getRank().getName() ); + } + + return false; + } } + RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); - // If the target ladder is either default or prestiges, then use the getNextPlayerRank() value - // that is provided. Only use the following code if not these two ladders. - if ( !ladder.equalsIgnoreCase( LadderManager.LADDER_DEFAULT ) && - !ladder.equalsIgnoreCase( LadderManager.LADDER_PRESTIGES ) ) { + // If ranking up on neither default or prestige ladders: + if ( !targetLadder.isDefault() && !targetLadder.isPrestiges() ) { PlayerRank playerRankCurrent = rankPlayerFactory.getRank( rankPlayer, ladder ); From 1ebbbc276d864965503de27a7d4620ba3620f4be Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 14 Dec 2024 13:28:18 -0500 Subject: [PATCH 221/323] Major Prison performance cleanup: When there are a few thousand players on the server and in prison, prison was running in to major performance issues that was basically killing the performance of the server. One major cause was with the startup routine of trying to add players that are on the server, but not in prison. This could run for literally days and consume tons of processing resources. So prison no longer tries to pre-add any player. They have to join the server to be added. The other major problem, was that if prison was trying to lookup a player that was not online, it would hit bukkit's offline players, and it would get a full list of all offline players. This was horrible! Bukkit would have to read all player files to generate the offline players listing, which could take a long time. For example, with 46,000 players, it could take a few minutes for bukkit to fully load all players, and during that time, paper starts generating tons of warnings stating the server is not responding correctly. It does not kill the server, but it generates mega bytes of errors in the log files. So to fix this problem, prison no longer uses the bukkit offline player's functions unless trying to access ONE offline player using strictly their UUID. A name search would require almost all files to be searched too. As a result, prison is far more stable for very large player bases on servers!! This is a major improvement. In the past there has been complaints about prison when there were a lot of players, but I was never able to zero in on the problem since no one was really willing to work with me on figuring this out. What helped a lot was being gifted over 46,000 players. :) So now I can do some serious testing with many players. --- docs/changelog_v3.3.x.md | 13 + .../tech/mcprison/prison/PrisonCommand.java | 11 +- .../prison/commands/BaseCommands.java | 40 +-- .../placeholders/PlaceholderIdentifier.java | 37 +-- .../mcprison/prison/ranks/PrisonRanks.java | 84 ++++--- .../prison/ranks/data/RankPlayerFactory.java | 1 + .../prison/ranks/managers/PlayerManager.java | 95 ++++--- .../prison/spigot/SpigotPlatform.java | 233 ++++++++++++------ .../commands/PrisonSpigotGUICommands.java | 14 +- .../prison/spigot/utils/PrisonUtils.java | 39 ++- 10 files changed, 378 insertions(+), 189 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 36afc4304..b328b3de3 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,19 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.19d 2024-10-11 +2024-12-14 + +* **Prison was gifted over 46,000 players!!!** +Someone who was running in to performance issues with prison on a large server, gifted me over 46,000 players in both prison and in bukkit. Now I can perform various testing with larger player bases to help fix and prevent performance issues. + + +* **Major Prison performance cleanup:** When there are a few thousand players on the server and in prison, prison was running in to major performance issues that was basically killing the performance of the server. +One major cause was with the startup routine of trying to add players that are on the server, but not in prison. This could run for literally days and consume tons of processing resources. So prison no longer tries to pre-add any player. They have to join the server to be added. +The other major problem, was that if prison was trying to lookup a player that was not online, it would hit bukkit's offline players, and it would get a full list of all offline players. This was horrible! Bukkit would have to read all player files to generate the offline players listing, which could take a long time. For example, with 46,000 players, it could take a few minutes for bukkit to fully load all players, and during that time, paper starts generating tons of warnings stating the server is not responding correctly. It does not kill the server, but it generates mega bytes of errors in the log files. +So to fix this problem, prison no longer uses the bukkit offline player's functions unless trying to access ONE offline player using strictly their UUID. A name search would require almost all files to be searched too. +As a result, prison is far more stable for very large player bases on servers!! This is a major improvement. In the past there has been complaints about prison when there were a lot of players, but I was never able to zero in on the problem since no one was really willing to work with me on figuring this out. What helped a lot was being gifted over 46,000 players. :) So now I can do some serious testing with many players. + + * **Rankup: would not work for ladders other than default and prestiges. Fixed.** 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 bfa943c72..440f2dc46 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java +++ b/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java @@ -638,9 +638,13 @@ private Player getPlayer( CommandSender sender, String playerName ) { if ( playerName != null ) { Optional opt = Prison.get().getPlatform().getPlayer( playerName ); if ( !opt.isPresent() ) { - opt = Prison.get().getPlatform().getOfflinePlayer( playerName ); + + result = Prison.get().getPlatform().getRankPlayer( null, playerName ); +// opt = Prison.get().getPlatform().getOfflinePlayer( playerName ); } - if ( opt.isPresent() ) { + +// if ( opt.isPresent() ) { + else { result = opt.get(); } } @@ -2563,7 +2567,8 @@ private Player getPlayer( String playerName ) { } if ( player == null ) { - player = Prison.get().getPlatform().getOfflinePlayer( playerName ).orElse( null ); + player = Prison.get().getPlatform().getRankPlayer( null, playerName ); +// player = Prison.get().getPlatform().getOfflinePlayer( playerName ).orElse( null ); } return player; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/commands/BaseCommands.java b/prison-core/src/main/java/tech/mcprison/prison/commands/BaseCommands.java index 895bcceaa..ea05497a4 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/commands/BaseCommands.java +++ b/prison-core/src/main/java/tech/mcprison/prison/commands/BaseCommands.java @@ -56,21 +56,31 @@ public Player getPlayer( CommandSender sender, String playerName, UUID uuid ) { playerName = sender.getName(); } - if ( playerName != null ) { - Optional opt = Prison.get().getPlatform().getPlayer( playerName ); - if ( !opt.isPresent() ) { - opt = Prison.get().getPlatform().getOfflinePlayer( playerName ); - } - if ( opt.isPresent() ) { - result = opt.get(); - } - } - if ( result == null && uuid != null ) { - Optional opt = Prison.get().getPlatform().getOfflinePlayer( uuid ); - if ( opt.isPresent() ) { - result = opt.get(); - } - } + result = Prison.get().getPlatform().getRankPlayer( uuid, playerName ); + + +// if ( playerName != null ) { +// Optional opt = Prison.get().getPlatform().getPlayer( playerName ); +// +// result = opt.orElse( null ); +// +//// if ( !opt.isPresent() ) { +//// opt = Prison.get().getPlatform().getOfflinePlayer( playerName ); +//// } +//// if ( opt.isPresent() ) { +//// result = opt.get(); +//// } +// } +// if ( result == null && uuid != null ) { +// +//// result = Prison.get().getPlatform().getRankPlayer( uuid, playerName ); +// +//// Optional opt = Prison.get().getPlatform().getOfflinePlayer( uuid ); +//// if ( opt.isPresent() ) { +//// result = opt.get(); +//// } +// } + // playerName = playerName != null && !playerName.trim().isEmpty() ? // playerName : sender != null ? sender.getName() : null; 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 a9409b9d4..8da017fef 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 @@ -178,25 +178,26 @@ public boolean checkPlaceholderKey(PlaceHolderKey placeHolderKey) { public void setPlayer( UUID playerUuid, String playerName ) { Player player = null; - if ( playerUuid != null ) { + player = Prison.get().getPlatform().getRankPlayer( playerUuid, playerName ); - player = Prison.get().getPlatform().getPlayer( playerUuid ).orElse( null ); - } - - if ( player == null && playerName != null ) { - - player = Prison.get().getPlatform().getPlayer( playerName ).orElse( null ); - } - - if ( player == null && playerUuid != null ) { - - player = Prison.get().getPlatform().getOfflinePlayer( playerUuid ).orElse( null ); - } - - if ( player == null && playerName != null ) { - - player = Prison.get().getPlatform().getOfflinePlayer( playerName ).orElse( null ); - } +// if ( playerUuid != null ) { +// player = Prison.get().getPlatform().getPlayer( playerUuid ).orElse( null ); +// } +// +// if ( player == null && playerName != null ) { +// +// player = Prison.get().getPlatform().getPlayer( playerName ).orElse( null ); +// } +// +// if ( player == null && playerUuid != null ) { +// +// player = Prison.get().getPlatform().getOfflinePlayer( playerUuid ).orElse( null ); +// } +// +// if ( player == null && playerName != null ) { +// +// player = Prison.get().getPlatform().getOfflinePlayer( playerName ).orElse( null ); +// } if ( player != null ) { 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 927ec61c8..7341fbccb 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 @@ -26,7 +26,6 @@ import tech.mcprison.prison.PrisonAPI; import tech.mcprison.prison.convert.ConversionManager; 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; @@ -313,6 +312,13 @@ public boolean reloadRanksAndLadders() { return success; } + /** + *

This is actually a very bad idea to add any players that have not joined. + * This should be disabled. When a player joins the server for the first time, + * then it will add them successfully. + *

+ * + */ public void checkAllPlayersForJoin() { @@ -324,6 +330,8 @@ public void checkAllPlayersForJoin() if ( addNewPlayers ) { + long startMs = System.currentTimeMillis(); + RankUpCommand rankupCommands = rankManager.getRankupCommands(); // If there is a default rank on the default ladder, then @@ -335,17 +343,33 @@ public void checkAllPlayersForJoin() int addedPlayers = 0; int fixedPlayers = 0; - for ( Player player : Prison.get().getPlatform().getOfflinePlayers() ) { - - // getPlayer() will add a player who does not exist: - RankPlayer rPlayer = playerManager.getPlayer( player ); - if ( rPlayer != null ) { - if ( rPlayer.checkName( player.getName() ) ) { - playerManager.savePlayer( rPlayer ); - addedPlayers++; - } - } - } + List rPlayers = playerManager.getPlayers(); + + // NOTE: The Platform.getOfflinePlayers() only returns the playerManager.getPlayers() because + // bukkit can seriously lag the server and kill it. +// List players = Prison.get().getPlatform().getOfflinePlayers(); +// +// String msg = String.format( +// "PrisonRanks: checkAllPlayersForJoin: Prison has %s players. Bukkit has %s. " +// + "Any player who is not in Prison will have to join prison to be added to prison.", +// Prison.get().getDecimalFormatInt().format( rPlayers.size() ), +// Prison.get().getDecimalFormatInt().format( players.size() ) +// ); +// +// Output.get().logInfo( msg ); + + // Prison will no longer add offline players. They must join to be added. +// for ( Player player : players ) { +// +// // getPlayer() will add a player who does not exist: +// RankPlayer rPlayer = playerManager.getPlayer( player ); +// if ( rPlayer != null ) { +// if ( rPlayer.checkName( player.getName() ) ) { +// playerManager.savePlayer( rPlayer ); +// addedPlayers++; +// } +// } +// } RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); @@ -364,28 +388,28 @@ public void checkAllPlayersForJoin() } - for ( RankPlayer rPlayer : playerManager.getPlayers() ) { + for ( RankPlayer rPlayer : rPlayers ) { // @SuppressWarnings( "unused" ) // String rp = rPlayer.toString(); - Rank rankOnDefault = null; +// Rank rankOnDefault = null; PlayerRank pRank = rankPlayerFactory.getRank( rPlayer, defaultLadder ); - if ( pRank != null ) { - - rankOnDefault = pRank.getRank(); - -// Output.get().logInfo( "#### %s ladder = %s isRankNull= %s rank= %s %s [%s]" , -// rPlayer.getName(), -// defaultLadder.getName(), -// (rankOnDefault == null ? "true" : "false"), (rankOnDefault == null ? "null" : rankOnDefault.getName()), -// (rankOnDefaultStr == null ? "true" : "false"), (rankOnDefaultStr == null ? "null" : rankOnDefaultStr.getName()), -// rp ); - - } - if ( rankOnDefault == null ) { +// if ( pRank != null ) { +// +// rankOnDefault = pRank.getRank(); +// +//// Output.get().logInfo( "#### %s ladder = %s isRankNull= %s rank= %s %s [%s]" , +//// rPlayer.getName(), +//// defaultLadder.getName(), +//// (rankOnDefault == null ? "true" : "false"), (rankOnDefault == null ? "null" : rankOnDefault.getName()), +//// (rankOnDefaultStr == null ? "true" : "false"), (rankOnDefaultStr == null ? "null" : rankOnDefaultStr.getName()), +//// rp ); +// +// } + if ( pRank == null || pRank.getRank() == null ) { rankupCommands.setPlayerRank( rPlayer, defaultRank ); @@ -406,7 +430,11 @@ public void checkAllPlayersForJoin() } } - Output.get().logInfo( "Ranks: Finished First Join Checks." ); + long endMs = System.currentTimeMillis(); + + long duration = endMs - startMs; + + Output.get().logInfo( "Ranks: Finished First Join Checks: " + duration + " ms" ); } else { diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactory.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactory.java index 4177dadcc..835182d03 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactory.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactory.java @@ -416,6 +416,7 @@ public PlayerRank getRank( RankPlayer rankPlayer, RankLadder ladder ) { { if ( key != null && key.getName().equalsIgnoreCase( ladder.getName() ) ) { results = rankPlayer.getLadderRanks().get( key ); + break; } } } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java index 086d2f53f..7ea743df3 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java @@ -70,6 +70,8 @@ public class PlayerManager private Collection collection; private List players; + + // NOTE: playersByName is indexed by both the player's name, and their UUID. private TreeMap playersByName; @@ -143,6 +145,9 @@ public void loadPlayers() throws IOException { if ( rankPlayer.getNames().size() > 0 ) { playersByName.put( rankPlayer.getDisplayName(), rankPlayer ); + // add lowercased name: + playersByName.put( rankPlayer.getDisplayName().toLowerCase(), rankPlayer ); + } } @@ -303,32 +308,52 @@ public RankPlayer getPlayer(UUID uid, String playerName) { if ( !playerName.isEmpty() && getPlayersByName().containsKey( playerName ) ) { results = getPlayersByName().get( playerName ); } - - if ( results == null ) { - - // Debug info on player when results are null from the first "search". - debugLogPlayerInfo( "getPlayer(): UUID check (could not match on playerName):", playerName, - uid == null ? "none" : uid.toString(), false ); - - for ( RankPlayer rankPlayer : players ) { - if ( uid != null && rankPlayer.getUUID().equals(uid) || - - !playerName.isEmpty() && - rankPlayer.getName() != null && - rankPlayer.getName().equalsIgnoreCase( playerName ) ) { - - // This checks to see if they have a new name, if so, then adds it to the history: - // But the UID must match: - if ( uid != null && rankPlayer.getUUID().equals(uid) ) { - rankPlayer.setEnableDirty( true ); - rankPlayer.setDirty( rankPlayer.checkName( playerName ) ); - } - - results = rankPlayer; - break; - } - } + else if ( !playerName.isEmpty() && getPlayersByName().containsKey( playerName.toLowerCase() ) ) { + results = getPlayersByName().get( playerName.toLowerCase() ); } + else if ( uid != null && getPlayersByName().containsKey( uid.toString() ) ) { + results = getPlayersByName().get( uid.toString() ); + + if ( results != null ) { + // There was probably a name change since it did not hit on the player's name, + // so update the name history: + + // This checks to see if they have a new name, if so, then adds it to the history: + // But the UID must match: + if ( uid != null && results.getUUID().equals(uid) ) { + results.setEnableDirty( true ); + results.setDirty( results.checkName( playerName ) ); + } + } + } + + +// // If we don't have the player by name or UUID, we can only check +// if ( results == null ) { +// +// // Debug info on player when results are null from the first "search". +// debugLogPlayerInfo( "getPlayer(): UUID check (could not match on playerName):", playerName, +// uid == null ? "none" : uid.toString(), false ); +// +// for ( RankPlayer rankPlayer : players ) { +// if ( uid != null && rankPlayer.getUUID().equals(uid) || +// +// !playerName.isEmpty() && +// rankPlayer.getName() != null && +// rankPlayer.getName().equalsIgnoreCase( playerName ) ) { +// +// // This checks to see if they have a new name, if so, then adds it to the history: +// // But the UID must match: +// if ( uid != null && rankPlayer.getUUID().equals(uid) ) { +// rankPlayer.setEnableDirty( true ); +// rankPlayer.setDirty( rankPlayer.checkName( playerName ) ); +// } +// +// results = rankPlayer; +// break; +// } +// } +// } // Optional results = players.stream().filter( // player -> (uid != null ? @@ -336,7 +361,9 @@ public RankPlayer getPlayer(UUID uid, String playerName) { // ( playerName != null || playerName.trim().length() == 0 ? false : // player.checkName( playerName )))).findFirst(); - if ( results == null && playerName != null && !"console".equalsIgnoreCase( playerName ) ) { + if ( results == null && uid != null && playerName != null && !"console".equalsIgnoreCase( playerName ) ) { + + // Player's uuid and name cannot be null if they are being added as a new prison player: debugLogPlayerInfo( "getPlayer(): addPlayer (final attempt: could not match on playerName or UUID):", playerName, uid == null ? "none" : uid.toString(), false ); @@ -387,7 +414,9 @@ private RankPlayer addPlayer( UUID uid, String playerName ) { if ( PrisonTaskSubmitter.isPrimaryThread() ) { results = addPlayerSyncTask( uid, playerName ); } - else if ( !getPlayersByName().containsKey( playerName )) { + else if ( !getPlayersByName().containsKey( playerName ) && + !getPlayersByName().containsKey( playerName.toLowerCase() ) + ) { // Submit the sync task to add player. But since this is an // async thread, we can only return a null. Future requests @@ -407,14 +436,16 @@ protected RankPlayer addPlayerSyncTask( UUID uid, String playerName ) { if ( uid != null && playerName != null && playerName.trim().length() > 0 && !"CONSOLE".equalsIgnoreCase( playerName ) && - !getPlayersByName().containsKey( playerName )) { + !getPlayersByName().containsKey( playerName ) && + !getPlayersByName().containsKey( playerName.toLowerCase() ) ) { synchronized( getPlayersByName() ) { // recheck to ensure that the player's name is not in the getPlayersByName() // collection... it could have been added since submitting the sync task: - if ( !getPlayersByName().containsKey( playerName ) ) { + if ( !getPlayersByName().containsKey( playerName ) && + !getPlayersByName().containsKey( playerName.toLowerCase() ) ) { RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); @@ -428,6 +459,8 @@ protected RankPlayer addPlayerSyncTask( UUID uid, String playerName ) { players.add(newPlayer); getPlayersByName().put( playerName, newPlayer ); + getPlayersByName().put( playerName.toLowerCase(), newPlayer ); + getPlayersByName().put( uid.toString(), newPlayer ); debugLogPlayerInfo( "addPlayerSyncTask: firstJoin:", playerName, @@ -488,7 +521,9 @@ public void debugLogPlayerInfo( String eventName, String playerName, String uuid if ( Output.get().isDebug() ) { - boolean newPlayer = playerName != null ? !getPlayersByName().containsKey( playerName ) : false; + boolean newPlayer = playerName != null ? + !getPlayersByName().containsKey( playerName ) && + !getPlayersByName().containsKey( playerName.toLowerCase() ) : false; if ( playerName == null ) { playerName = "**Error No player name**"; 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 4e7da4217..88ea237db 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 @@ -337,7 +337,8 @@ public Optional getPlayer(String name) { // })); } - @Override public Optional getPlayer(UUID uuid) { + @Override + public Optional getPlayer(UUID uuid) { org.bukkit.entity.Player playerBukkit = Bukkit.getPlayer(uuid); return Optional.ofNullable( playerBukkit == null ? null : new SpigotPlayer(playerBukkit) ); @@ -357,109 +358,183 @@ public Optional getPlayer(String name) { // return player; // })); } + + public Player getPlayer( org.bukkit.entity.Player playerBukkit ) { + + return new SpigotPlayer(playerBukkit); + } - @Override public List getOnlinePlayers() { + /** + *

If there are a lot of players on a server, getting bukkit's online players should be + * a fairly low cost operation since they all should have been loaded in to memory and there + * shouldn't be any disk access to load all of the players. + *

+ * + *

The functions that are using this list of players, are either teleporting players out of + * a mine before resetting the mine, or broadcasting messages to the players. So they do need + * to be online. + *

+ * + */ + @Override + public List getOnlinePlayers() { return Bukkit.getOnlinePlayers().stream() - .map(player -> getPlayer(player.getUniqueId()).get()) + .map( player -> getPlayer( player )) .collect(Collectors.toList()); } + /** + *

Warning: Do not use because the Bukkit.getOfflinePlayer( name ) is deprecated. + * Use instead, the getRankPlayer() and if they exist, which means they are setup in prison, + * then you will have their UUID to use the Bukkit.getOfflinePlayer( uuid ) function. + *

+ */ @Override public Optional getOfflinePlayer(String name) { - return getOfflinePlayer(name, null); + + Player player = null; + + try { + OfflinePlayer oPlayer = Bukkit.getOfflinePlayer( name ); + player = (oPlayer == null ? null : new SpigotOfflinePlayer( oPlayer ) ); + } + catch (Exception e) { + Output.get().logWarn( "SpigotPlatform.getOfflinePlayer(name) failed (is deprecated): " + e.getMessage() ); + } + + return Optional.ofNullable( player ); + +// return getOfflinePlayer(name, null); } @Override public Optional getOfflinePlayer(UUID uuid) { - return getOfflinePlayer(null, uuid); + + OfflinePlayer oPlayer = Bukkit.getOfflinePlayer( uuid ); + Player player = (oPlayer == null ? null : new SpigotOfflinePlayer( oPlayer ) ); + + return Optional.ofNullable( player ); + +// return getOfflinePlayer(null, uuid); } + + /** + *

This function will return all players that are setup in prison. + * This function cannot use bukkit's getOffLinePlayers() because for + * servers with a lot of players, that will force bukkit to read a ton + * of files, which will lag the server big time. + *

+ * + *

Using the PlayerManger to get the registered players makes the most + * sense. + *

+ * + */ @Override public List getOfflinePlayers() { List players = new ArrayList<>(); - for ( OfflinePlayer oPlayer : Bukkit.getOfflinePlayers() ) { - if ( oPlayer != null ) { - - players.add( new SpigotOfflinePlayer( oPlayer ) ); + if ( PrisonRanks.getInstance() != null && PrisonRanks.getInstance().isEnabled() ) { + PlayerManager pm = PrisonRanks.getInstance().getPlayerManager(); + + for ( RankPlayer rPlayer : pm.getPlayers() ) { + players.add(rPlayer); } - } + + } + + +// for ( OfflinePlayer oPlayer : Bukkit.getOfflinePlayers() ) { +// if ( oPlayer != null ) { +// +// players.add( new SpigotOfflinePlayer( oPlayer ) ); +// } +// } return players; } - private Optional getOfflinePlayer(String name, UUID uuid) { - Player player = null; - - if ( uuid != null ) { - OfflinePlayer oPlayer = Bukkit.getOfflinePlayer( uuid ); - player = (oPlayer == null ? null : new SpigotOfflinePlayer( oPlayer ) ); - - } - - if ( player == null && name != null && name.trim().length() > 0 ) { - - // No hits on uuid so only compare names: - for ( OfflinePlayer oPlayer : Bukkit.getOfflinePlayers() ) { - if ( oPlayer != null && oPlayer.getName() != null && - oPlayer.getName().equalsIgnoreCase( name.trim() ) ) { - - player = new SpigotOfflinePlayer( oPlayer ); - break; - } - else if ( oPlayer == null || oPlayer.getName() == null ) { - Output.get().logWarn( "SpigotPlatform.getOfflinePlayer: Bukkit return a " + - "bad player: OfflinePlayer == null? " + (oPlayer == null) + - ( oPlayer == null ? "" : - " name= " + (oPlayer.getName() == null ? "null" : - oPlayer.getName()))); - - } - } - } - - // If player is not available, then try to get a RankPlayer instance of the player: - if ( player == null ) { - if ( PrisonRanks.getInstance() != null && PrisonRanks.getInstance().isEnabled() ) { - PlayerManager pm = PrisonRanks.getInstance().getPlayerManager(); - - RankPlayer rankPlayer = pm.getPlayer( uuid, name ); - if ( rankPlayer != null ) { - if ( uuid != null && rankPlayer.getUUID().equals( uuid ) || - uuid == null && name != null && rankPlayer.getName() != null && - rankPlayer.getName().equalsIgnoreCase( name )) { - - player = rankPlayer; - } - } - } - } - - return Optional.ofNullable( player ); - - -// for ( OfflinePlayer offP : Bukkit.getOfflinePlayers() ) { -// if ( name != null && offP.getName().equalsIgnoreCase( name) || -// uuid != null && offP.getUniqueId().equals(uuid) ) { -// -// // ### getting the offline bukkit player here! -// player = new SpigotOfflinePlayer( offP ); -// players.add(player); -// break; -// } +// private Optional getOfflinePlayer(String name, UUID uuid) { +// Player player = null; +// +// if ( PrisonRanks.getInstance() != null && PrisonRanks.getInstance().isEnabled() ) { +// PlayerManager pm = PrisonRanks.getInstance().getPlayerManager(); +// +// player = pm.getPlayer( uuid, name ); +// // } +// +// +//// if ( uuid != null ) { +//// OfflinePlayer oPlayer = Bukkit.getOfflinePlayer( uuid ); +//// player = (oPlayer == null ? null : new SpigotOfflinePlayer( oPlayer ) ); +//// +//// } +//// +//// if ( player == null && name != null && name.trim().length() > 0 ) { +//// +//// // No hits on uuid so only compare names: +//// for ( OfflinePlayer oPlayer : Bukkit.getOfflinePlayers() ) { +//// if ( oPlayer != null && oPlayer.getName() != null && +//// oPlayer.getName().equalsIgnoreCase( name.trim() ) ) { +//// +//// player = new SpigotOfflinePlayer( oPlayer ); +//// break; +//// } +//// else if ( oPlayer == null || oPlayer.getName() == null ) { +//// Output.get().logWarn( "SpigotPlatform.getOfflinePlayer: Bukkit return a " + +//// "bad player: OfflinePlayer == null? " + (oPlayer == null) + +//// ( oPlayer == null ? "" : +//// " name= " + (oPlayer.getName() == null ? "null" : +//// oPlayer.getName()))); +//// +//// } +//// } +//// } +//// +//// // If player is not available, then try to get a RankPlayer instance of the player: +//// if ( player == null ) { +//// if ( PrisonRanks.getInstance() != null && PrisonRanks.getInstance().isEnabled() ) { +//// PlayerManager pm = PrisonRanks.getInstance().getPlayerManager(); +//// +//// RankPlayer rankPlayer = pm.getPlayer( uuid, name ); +//// if ( rankPlayer != null ) { +//// if ( uuid != null && rankPlayer.getUUID().equals( uuid ) || +//// uuid == null && name != null && rankPlayer.getName() != null && +//// rankPlayer.getName().equalsIgnoreCase( name )) { +//// +//// player = rankPlayer; +//// } +//// } +//// } +//// } // -// List olPlayers = Arrays.asList( Bukkit.getOfflinePlayers() ); -// for ( OfflinePlayer offlinePlayer : olPlayers ) { -// if ( name != null && offlinePlayer.getName().equals(name) || -// uuid != null && offlinePlayer.getUniqueId().equals(uuid) ) { -// player = new SpigotPlayer(offlinePlayer.getPlayer()); -// players.add(player); -// break; -// } -// } // return Optional.ofNullable( player ); - } +// +// +//// for ( OfflinePlayer offP : Bukkit.getOfflinePlayers() ) { +//// if ( name != null && offP.getName().equalsIgnoreCase( name) || +//// uuid != null && offP.getUniqueId().equals(uuid) ) { +//// +//// // ### getting the offline bukkit player here! +//// player = new SpigotOfflinePlayer( offP ); +//// players.add(player); +//// break; +//// } +//// } +//// +//// List olPlayers = Arrays.asList( Bukkit.getOfflinePlayers() ); +//// for ( OfflinePlayer offlinePlayer : olPlayers ) { +//// if ( name != null && offlinePlayer.getName().equals(name) || +//// uuid != null && offlinePlayer.getUniqueId().equals(uuid) ) { +//// player = new SpigotPlayer(offlinePlayer.getPlayer()); +//// players.add(player); +//// break; +//// } +//// } +//// return Optional.ofNullable( player ); +// } @Override public String getPluginVersion() { return plugin.getDescription().getVersion(); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotGUICommands.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotGUICommands.java index c93825121..1a04cb637 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotGUICommands.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotGUICommands.java @@ -43,19 +43,21 @@ private void prisonManagerGUI(CommandSender sender) { Player player = getSpigotPlayer(sender); - if (player == null) { - Output.get().sendInfo(sender, SpigotPrison.format( getMessages().getString(MessagesConfig.StringID.spigot_message_console_error))); - return; - } +// if (player == null) { +// Output.get().sendInfo(sender, SpigotPrison.format( getMessages().getString(MessagesConfig.StringID.spigot_message_console_error))); +// return; +// } - if (player.hasPermission("prison.admin")) { + if (player != null && player.hasPermission("prison.admin")) { SpigotPrisonGUI gui = new SpigotPrisonGUI(player); gui.open(); return; } // If the player will be shown the /gui help, then force close any open inventory: - player.closeInventory(); + if (player != null ) { + player.closeInventory(); + } sender.dispatchCommand("gui help"); } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtils.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtils.java index 34e5b59fa..ff0f8300d 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtils.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtils.java @@ -1,12 +1,11 @@ package tech.mcprison.prison.spigot.utils; -import java.util.Optional; - import org.bukkit.Bukkit; import tech.mcprison.prison.Prison; import tech.mcprison.prison.internal.CommandSender; import tech.mcprison.prison.internal.Player; +import tech.mcprison.prison.ranks.data.RankPlayer; import tech.mcprison.prison.spigot.game.SpigotOfflinePlayer; import tech.mcprison.prison.spigot.game.SpigotPlayer; @@ -158,24 +157,44 @@ else if ( !sender.isOp() && !sender.hasPermission( permsSelf ) ) { protected SpigotPlayer getSpigotPlayer( String playerName, boolean useOfflinePlayer ) { SpigotPlayer result = null; - if ( playerName != null ) { - Optional opt = Prison.get().getPlatform().getPlayer( playerName ); + RankPlayer rPlayer = Prison.get().getPlatform().getRankPlayer( null, playerName ); + + if ( rPlayer != null ) { + Player player = Prison.get().getPlatform().getPlayer( rPlayer.getUUID() ).orElse(null); - if ( opt.isPresent() ) { - result = (SpigotPlayer) opt.get(); + if ( player != null ) { + result = (SpigotPlayer) player; } else if ( useOfflinePlayer ) { - Optional optOLP = Prison.get().getPlatform().getOfflinePlayer( playerName ); + Player offLinePlayer = Prison.get().getPlatform().getOfflinePlayer( player.getUUID() ).orElse( null ); - if ( optOLP.isPresent() ) { + if ( offLinePlayer != null ) { - SpigotOfflinePlayer offlinePlayer = (SpigotOfflinePlayer) optOLP.get(); + SpigotOfflinePlayer offlinePlayer = (SpigotOfflinePlayer) offLinePlayer; result = new SpigotPlayer( offlinePlayer.getWrapper().getPlayer() ); } } - } + +// if ( playerName != null ) { +// Optional opt = Prison.get().getPlatform().getPlayer( playerName ); +// +// if ( opt.isPresent() ) { +// result = (SpigotPlayer) opt.get(); +// } +// else if ( useOfflinePlayer ) { +// Optional optOLP = Prison.get().getPlatform().getOfflinePlayer( playerName ); +// +// if ( optOLP.isPresent() ) { +// +// SpigotOfflinePlayer offlinePlayer = (SpigotOfflinePlayer) optOLP.get(); +// +// result = new SpigotPlayer( offlinePlayer.getWrapper().getPlayer() ); +// } +// } +// +// } return result; } From 56af7b1f01b9a530bba266943550e219189f70c0 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 14 Dec 2024 13:35:02 -0500 Subject: [PATCH 222/323] Players: Fixed a problem with getting the vector for where the player is looking. The actual vector was getting lost so the result was that nothing was able to be properly calculated. This was fixed by creating an internal prison vector which could be used instead. --- docs/changelog_v3.3.x.md | 4 +++ .../mcprison/prison/spigot/SpigotUtil.java | 28 +++++++++++++------ 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index b328b3de3..c6823cf9d 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.19d 2024-10-11 +* **Players: Fixed a problem with getting the vector for where the player is looking. The actual vector was getting lost so the result was that nothing was able to be properly calculated.** +This was fixed by creating an internal prison vector which could be used instead. + + 2024-12-14 * **Prison was gifted over 46,000 players!!!** 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 eaea2814e..ea7f4c4fb 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 @@ -55,6 +55,7 @@ import tech.mcprison.prison.spigot.integrations.IntegrationMinepacksPlugin; import tech.mcprison.prison.util.Location; import tech.mcprison.prison.util.Text; +import tech.mcprison.prison.util.Vector; /** * Utilities for converting Prison-Core types to Spigot types. @@ -1095,10 +1096,20 @@ private static void logTestBlocks( StringBuilder sb, String message ) { public static Location bukkitLocationToPrison(org.bukkit.Location bukkitLocation) { - return new Location(new SpigotWorld(bukkitLocation.getWorld()), bukkitLocation.getX(), + Location loc = new Location(new SpigotWorld(bukkitLocation.getWorld()), bukkitLocation.getX(), bukkitLocation.getY(), bukkitLocation.getZ(), bukkitLocation.getPitch(), bukkitLocation.getYaw() ); + double x = bukkitLocation.getDirection().getX(); + double y = bukkitLocation.getDirection().getY(); + double z = bukkitLocation.getDirection().getZ(); + + Vector direction = new Vector( x, y, z ); + + loc.setDirection( direction ); + + return loc; + // org.bukkit.util.Vector v = bukkitLocation.getDirection(); // Vector direction = new Vector( v.getX(), v.getY(), v.getZ() ); // @@ -1248,14 +1259,15 @@ public static InventoryView.Property prisonPropertyToBukkit(Viewable.Property pr * @return OfflinePlayer */ public static OfflinePlayer getBukkitOfflinePlayer( UUID uuid ) { - OfflinePlayer results = null; - for ( OfflinePlayer offP : Bukkit.getOfflinePlayers() ) { - if ( uuid != null && offP.getUniqueId().equals(uuid) ) { - results = offP; - break; - } - } + OfflinePlayer results = Bukkit.getOfflinePlayer(uuid); + +// for ( OfflinePlayer offP : Bukkit.getOfflinePlayers() ) { +// if ( uuid != null && offP.getUniqueId().equals(uuid) ) { +// results = offP; +// break; +// } +// } return results; } From 74194debacce00b5ffe392ddda73f3cb82712e43 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 14 Dec 2024 13:41:11 -0500 Subject: [PATCH 223/323] Mines: Debug block breakage. Created a new command '/mines debugBlockBreak` that will now be able to use tools from other plugins. Realized there was a problem with using the mine wand when testing block breakage in that you could not test with any other tool, which would prevent other plugins from handling the events like they should. So now, by holding any tool in your hand, and issuing the command '/mines debugBlockBreak' it will test the block breakage with whatever they are holding. --- docs/changelog_v3.3.x.md | 5 ++ .../mcprison/prison/spigot/SpigotPrison.java | 7 +++ .../PrisonDebugBlockInspectorCommand.java | 51 +++++++++++++++++++ .../events/PrisonDebugBlockInspector.java | 26 ++++++++-- 4 files changed, 85 insertions(+), 4 deletions(-) create mode 100644 prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/PrisonDebugBlockInspectorCommand.java diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index c6823cf9d..e269b5ffa 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.19d 2024-10-11 +* **Mines: Debug block breakage. Created a new command '/mines debugBlockBreak` that will now be able to use tools from other plugins.** +Realized there was a problem with using the mine wand when testing block breakage in that you could not test with any other tool, which would prevent other plugins from handling the events like they should. +So now, by holding any tool in your hand, and issuing the command '/mines debugBlockBreak' it will test the block breakage with whatever they are holding. + + * **Players: Fixed a problem with getting the vector for where the player is looking. The actual vector was getting lost so the result was that nothing was able to be properly calculated.** This was fixed by creating an internal prison vector which could be used instead. 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 40000bccb..2093a1498 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 @@ -60,6 +60,7 @@ import tech.mcprison.prison.sellall.PrisonSellall; import tech.mcprison.prison.sellall.commands.SellallCommands; import tech.mcprison.prison.spigot.autofeatures.AutoManagerFeatures; +import tech.mcprison.prison.spigot.autofeatures.PrisonDebugBlockInspectorCommand; import tech.mcprison.prison.spigot.autofeatures.events.AutoManagerBlockBreakEvents; import tech.mcprison.prison.spigot.backpacks.BackpacksListeners; import tech.mcprison.prison.spigot.backpacks.BackpacksUtil; @@ -332,6 +333,7 @@ public void onEnableStartup() { } Bukkit.getPluginManager().registerEvents(new SpigotListener(), this); + try { isBackPacksEnabled = getConfig().getBoolean("backpacks"); @@ -1238,6 +1240,11 @@ private void initModulesAndCommands() { } + + // Register the '/mines debugBlockBreak' command: + Prison.get().getCommandHandler().registerCommands( new PrisonDebugBlockInspectorCommand() ); + + } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/PrisonDebugBlockInspectorCommand.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/PrisonDebugBlockInspectorCommand.java new file mode 100644 index 000000000..fbaeeb2f3 --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/PrisonDebugBlockInspectorCommand.java @@ -0,0 +1,51 @@ +package tech.mcprison.prison.spigot.autofeatures; + + +import tech.mcprison.prison.Prison; +import tech.mcprison.prison.commands.Command; +import tech.mcprison.prison.internal.CommandSender; +import tech.mcprison.prison.internal.Player; +import tech.mcprison.prison.spigot.autofeatures.events.PrisonDebugBlockInspector; +import tech.mcprison.prison.spigot.commands.PrisonSpigotBaseCommands; +import tech.mcprison.prison.spigot.game.SpigotPlayer; +import tech.mcprison.prison.util.Location; + +public class PrisonDebugBlockInspectorCommand + extends PrisonSpigotBaseCommands { + + + @Command( identifier = "mines debugBlockBreak", + description = "This will debug the BlockBreakEvent chain of plugins handling the " + + "event. Look at a block, while holding the tool of choice, and then " + + "issue this command.", + altPermissions = "prison.admin", + onlyPlayers = true + ) + private void mineDebugBlockBreak(CommandSender sender) { + +// Player player = getSpigotPlayer(sender); + + + PrisonDebugBlockInspector blockInspector = PrisonDebugBlockInspector.getInstance(); + + +// (SpigotPlayer) sender.getPlatformPlayer(); + + Player player = Prison.get().getPlatform().getPlayer( sender.getPlatformPlayer().getUUID() ).orElse(null); + + + if ( player != null && player instanceof SpigotPlayer ) { + + SpigotPlayer sPlayer = (SpigotPlayer) player; + + Location location = sPlayer.getLineOfSightExactLocation(); + + boolean isSneaking = true; + + blockInspector.debugBlockBreak( sPlayer, isSneaking, location ); + } + + + } + +} 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 0ddd9ffd0..6ab3713f5 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 @@ -6,6 +6,7 @@ import org.bukkit.event.EventException; import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.plugin.RegisteredListener; import com.cryptomorin.xseries.XMaterial; @@ -102,8 +103,6 @@ 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 ) { @@ -125,7 +124,19 @@ public void onPlayerInteract( PrisonPlayerInteractEvent e ) { boolean isSneaking = player.isSneaking(); Location location = e.getClicked(); - SpigotBlock sBlock = (SpigotBlock) location.getBlockAt(); + + + debugBlockBreak( player, isSneaking, location ); + + } + + public void debugBlockBreak( SpigotPlayer player, boolean isSneaking, + Location location + ) { + + List output = new ArrayList<>(); + + SpigotBlock sBlock = (SpigotBlock) location.getBlockAt(); // UUID playerUUID = e.getPlayer().getUUID(); // Mine mine = obbMines.findMine( playerUUID, sBlock, null, null ); @@ -316,8 +327,15 @@ public void dumpBlockBreakEvent( SpigotPlayer player, SpigotBlock sBlock, MineTa // boolean isLeaves = blockName.contains( "leaves" ); // boolean isWood = blockName.matches( "wood|log|planks|sapling" ); + ItemStack ourItem = new SpigotItemStack( heldItem ); + ItemStack toolItem = SelectionManager.SELECTION_TOOL; + + boolean isMineWand = ourItem != null && ourItem.equals(toolItem); - SpigotItemStack tool = useShovel ? + // If what is being held is not a mine wand, then use what is being held: + SpigotItemStack tool = + !isMineWand ? (SpigotItemStack) ourItem : + useShovel ? new SpigotItemStack( XMaterial.DIAMOND_SHOVEL.parseItem() ) : ( useAxe ? new SpigotItemStack( XMaterial.DIAMOND_AXE.parseItem() ) : From da5322f6cef694c39e9c1ecfcc0cc56f508925b8 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 14 Dec 2024 22:50:51 -0500 Subject: [PATCH 224/323] Doc updates: Provide more information on '/mines set resetThreshold' and the new command '/mines debugBlockBreak'. --- docs/changelog_v3.3.x.md | 5 +++- docs/prison_docs_101_setting_up_mines.md | 31 +++++++++++++++++++++--- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index e269b5ffa..8cbead753 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.19d 2024-10-11 +# 3.3.0-alpha.19d 2024-12-14 + + +* **Doc updates: Provide more information on '/mines set resetThreshold' and the new command '/mines debugBlockBreak'.** * **Mines: Debug block breakage. Created a new command '/mines debugBlockBreak` that will now be able to use tools from other plugins.** diff --git a/docs/prison_docs_101_setting_up_mines.md b/docs/prison_docs_101_setting_up_mines.md index 50c61b391..7cf480090 100644 --- a/docs/prison_docs_101_setting_up_mines.md +++ b/docs/prison_docs_101_setting_up_mines.md @@ -6,7 +6,7 @@ This document provides some highlights to how to setup mines. It is a work in progress so check back for more information. -*Documented updated: 2024-03-11* +*Documented updated: 2024-12-14*
@@ -136,6 +136,9 @@ A mine wand will allow you to set the coordinates of a mine by clicking on a blo A mine wand can also be used for debugging block break actions within a mine. If you are having issues with getting mines to work, it's one of the many built-in support tools that can help figure out what's going wrong, since a prison server can become very complex, especially when factoring in other plugins. Please contact us through our discord server for additional help if needed. +Note: You can now test block breakage with the command `/mines debugBlockBreak` while holding the tools of your choice. This may be a better way to test enchantment plugins, which will probably ignore a plain diamond pickaxe that is used by default with the mine wand. + +

Laying Out the New Mine

@@ -203,7 +206,7 @@ Some of the highlights of these commands are as follows: * `/mines set accessPermission help` : Use a mine permission to grant players access to the mine. This will override WG regions and resolve issues with strange behaviors resulting from WG. This must be a plain permission and cannot be a permission group. -* `/mines command` : **Now active!** **Take your mines to the next level!** See the document on [Mine Commands](prison_docs_111_mine_commands.md) for more information. Every time a mine resets, you can now control what commands run right before a reset, and what runs right after a reset. These commands are similar to the Rank Commands, since they can be any command that you can run from the console. The idea is that you can have unique mines that have not been possible before, such as randomly spawned forests or specific builds. +* `/mines command` : **Take your mines to the next level!** See the document on [Mine Commands](prison_docs_111_mine_commands.md) for more information. Every time a mine resets, you can now control what commands run right before a reset, and what runs right after a reset. These commands are similar to the Rank Commands, since they can be any command that you can run from the console. The idea is that you can have unique mines that have not been possible before, such as randomly spawned forests or specific builds. * `/mines delete` : Deletes a mine. You can always undelete a mine by going in to the server file system and rename the deleted mine, then restart the server. * `/mines info` : Very useful in viewing all information related to the mine. * `/mines list` : Displays all mines on your server. @@ -211,6 +214,11 @@ Some of the highlights of these commands are as follows: * `/mines rename` : Renames a mine. +* `/mines debugBlockBreak` if you need to debug what's happening with block breakage on your server, please use this new tool to get detailed account of which plugins are handling, or interfering, with the block breakage. This works both in side a mine, and outside. + * They way you use this command, is in game, you will look at a block (center the cross-hair on the block), while holding a tool, or weapon of your choice, then issue the command in-game `/mines debugBlockBreak`. Then look at the console for detailed information on the command's output. It will be very detailed, and could possibly be a few dozen lines long, or more, if there are a lot of installed plugins on your server. + + + * `/mines reset ` : Resets the mine. Forces a regeneration of all the blocks, even if the mine is in skip reset mode. `` should be the name of the mine, but can also be ** *all* ** to force all the mines to reset one after the other. If such action is performed, then all mine resets will be done through a submission with a slight delay between each reset, and it will prevent the running of the mine reset commands to prevent possible looping. `` should not be use directly without understanding what they do. * `/mines stats` : Toggles the display of stats that pertain to how long it takes to reset the mines. View /mines info or /mines list to see the stats. Use this command again to turn it off. @@ -269,7 +277,19 @@ Some of the highlights of these commands are as follows: * `/mines set notificationPerm` : Enables or Disables notifications pertaining to mine resets to be seen only by players who have permission to that mine. The permissions used are `mines.notification.[mineName]` in all lower case. * `/mines set notification` : Can turn off the notifications on a per-mine basis. Or set the notification radius, or only notify players within the mine. This command cannot change the message. * `/mines set rank ` : Links a mine to a rank, otherwise there is no way within prison to identify which mines should be associated with a given rank. If **rankName** is **none** then it removes the associated rank from the mine (deletes the rank). This is not yet needed, but it will be used in the near future with new features, or enhancements to existing features. -* `/mines set resetThreshold` : This allows you to set a percent remaining in the mine to use as a threshold for resets. For example if you set it to 20.5% then the mine will reset when it reaches 25.5% blocks remaining. When the mine resets, it will initiate the `zeroBlockResetDelay` functionality, of which it's not exactly "zero blocks" anymore. + + +* `/mines set resetThreshold` : This allows you to set a percent remaining in the mine to use as a threshold for resets. For example if you set it to 20.5% then the mine will reset when it reaches 25.5% blocks remaining. When the mine resets, it will initiate the `zeroBlockResetDelay` functionality, of which it's not exactly "zero blocks" anymore. + * Please be careful if using values that are way too high, such as over 90%, as it could possibly result in such frequent mine resets per second, that the internal mine-locks could become corrupt or stuck. If this happens, please manually reset the mine with `/mines reset force`. + * Excessive mine resets can cause lag and other server performance issues. This would not be considered a bug or a design flaw. It's more so a configuration issue, so use at your own risk. + * To find out how many mined blocks it will take to reset the mine, use this formula, which example of 98% threshold in a mine that is 30 x 15 x 30 (13,500 blocks): + * blocks-to-reset = total-blocks * (1.0 - percent-reset-threshold) + * blocks-to-reset = 13,500 * (1.0 - 0.98) + * blocks-to-reset = 13,500 * 0.02 + * blocks-to-reset = 270 blocks + * You may want to consider how quickly a player can mine blocks with the highest efficiency pickaxe that you allow on your server. Then multiply that projected value by the number of players that may be mining together in the mine. In general, you would want to increase the total blocks mined before resetting the mine, which will do a much better job of handling a large number of blocks being removed per interval. + + * `/mines set resetTime` : Changes the time between resets, as expressed in seconds. Applies to each mine independently. * **Removed:** `/mines set resetPaging` : This no longer is a setting, since Prison always uses a more advanced type of paging that dynamically prevents server lag. This is an advanced feature that can eliminate lag that might be experienced with the resetting of enormous large mines. A mine could be millions of blocks in size and without this setting it may take a few seconds, or longer to reset, and it could cause the ticks to fall far behind, even to the point of forcing a shutdown. This command instead will breakdown the mine's reset in to very small chunks that will prevent the TPS from slowing down, and it will allow other critical tasks to continue to run. The total length of time for the rest may be increased, but it will not hurt the server. Prison does not use async resets due to eventual corruption of the bukkit and spigot components. * `/mines set size` : Allows you to resize a mine without redefining it with the prison selection wand. Just specify which direction to increase or decrease. It also uses the `/mines set liner repair` feature to fill in voids when reducing an edge. @@ -478,7 +498,7 @@ The feature zero blocks reset delay identifies what should happen when Prison de If this feature is enabled, and the delay value is set to Zero, then the mine is forced to reset with no delay. If there is a light load of jobs running on the server, then it will be instantly reset, otherwise there will be a delay for the job to wait its turn to run. -If the reset delay is non-zero, the value is measured in seconds, with a valid value of 0.01 seconds. But keep in mind that in reality the seconds are converted to ticks and is scheduled within the Bukkit job queue. Therefore, since there are 1000 milliseonds within one second, and 20 ticks within one second, one tick is the smaller possible value, which equates to 50 milliseconds. This is equivalent to 0.05 seconds. When the seconds are converted to ticks, the values will be rounded down to a whole integer value. So if a value is provide such as 0.049 it will be submitted as 0 ticks, which will result in zero delay (if possible) before running. +If the reset delay is non-zero, the value is measured in seconds, with a valid value of 0.01 seconds. But keep in mind that in reality the seconds are converted to ticks and is scheduled within the Bukkit job queue. Therefore, since there are 1000 milliseconds within one second, and 20 ticks within one second, one tick is the smaller possible value, which equates to 50 milliseconds. This is equivalent to 0.05 seconds. When the seconds are converted to ticks, the values will be rounded down to a whole integer value. So if a value is provide such as 0.049 it will be submitted as 0 ticks, which will result in zero delay (if possible) before running. The bottom line is that this feature can force an earlier reset of the mine when it becomes totally empty of blocks. A delay may be needed, or desired, to reach your perfection for the mine. @@ -487,6 +507,9 @@ The bottom line is that this feature can force an earlier reset of the mine when By using the command `/mines set resetThreshold` it is effectively able to shift when the mine resets. It does not delay when the mine resets, but instead it provides way to trigger a reset based upon a percentage of the mine that remains. It works in conjunction with Zero Block Reset Delay too, where instead of waiting until zero blocks remain, it then applies a percentage to change the reset level. +A mine that is 10,000 blocks, when the resetThreshold is set to 90%, the mine will reset after about 1,000 blocks are mined (10%). Setting this value too high, like even over 80%, does not make sense. It would be far more efficient, and easier on the server's TPS to instead make the mine much, much smaller. Setting this to a high percentage is bad overall, because the mine will reset with a fraction of it's total blocks being mined, but yet a mine reset will replace all 100% of the blocks in the mine, which can contribute to server lag if the frequency is way too high. + +Very high values can also result in prison resetting the mine many times per second, especially if there are multiple players mining with very high efficiency pickaxes being used. It is also very much possible, that if the mines are being reset a few times per second, or even every few seconds, that the internal mine-locks that are being used could have their state become corrupt and therefore prevent the mine from resetting. If this happens, the locks should auto-release after 5 minutes. But you can also manually force a reset to fix them with `/mines reset force`. From 81a89e5f9c1010bc8bc6c3cfd7fc325cdb2e75a4 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 15 Dec 2024 00:20:57 -0500 Subject: [PATCH 225/323] Updated nbtApi from v2.13.2 to v2.14.0. This should provide better support for spigot 1.21.4. Tried to update XSeries to v12.0.0 but it failed. It does not appear to work with spigot v1.13.2, which is the version which prison uses for building it's jars. Will have to figure this out later, maybe their release v12.1.0 will address these issues. --- docs/changelog_v3.3.x.md | 6 ++++++ gradle/libs.versions.toml | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 8cbead753..b39131abf 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.19d 2024-12-14 +* **Updated nbtApi from v2.13.2 to v2.14.0. This should provide better support for spigot 1.21.4.** + +Tried to update XSeries to v12.0.0 but it failed. It does not appear to work with spigot v1.13.2, which is the version which prison uses for building it's jars. Will have to figure this out later, maybe their release v12.1.0 will address these issues. + + + * **Doc updates: Provide more information on '/mines set resetThreshold' and the new command '/mines debugBlockBreak'.** diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 560050228..3e2ea7dc4 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -19,7 +19,7 @@ ## Bad?: https://repo.codemc.io/service/rest/repository/browse/maven-public/de/tr7zw/item-nbt-api-plugin/2.11.3/ -# Note: papi has two possible URLs: The second one is the offical but the repo does not work well. +# Note: papi has two possible URLs: The second one is the official but the repo does not work well. # com.github.placeholderapi:placeholderapi # me.clip:placeholderapi # @@ -39,7 +39,7 @@ junit = "4.12" guava = "31.1-jre" spigotApi = "1.13.2-R0.1-SNAPSHOT" -nbtApi = "2.13.2" +nbtApi = "2.14.0" papi = "2.11.6" vault = "1.7.1" From 08d35067a059777d3735e5960539da8f2513568e Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 15 Dec 2024 00:45:56 -0500 Subject: [PATCH 226/323] Version 3.3.0-alpha.19e 2024-12-14. --- docs/changelog_v3.3.x.md | 7 +++++-- gradle.properties | 2 +- .../tech/mcprison/prison/spigot/sellall/SellAllUtil.java | 5 +++++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index b39131abf..25f41beca 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.19d 2024-12-14 +# 3.3.0-alpha.19e 2024-12-14 + + +### Version 3.3.0-alpha.19e 2024-12-14 * **Updated nbtApi from v2.13.2 to v2.14.0. This should provide better support for spigot 1.21.4.** @@ -93,7 +96,7 @@ SpigotPlayer: Using bukkit's block.isPassable() on getLineOfSight(), but may nee It was not clear why mine bombs were not working. -** 3.3.0-alpha.19d 2024-09-26** +### 3.3.0-alpha.19d 2024-09-26** * **Prison blocks: It was realized that due to a recent expansion of the items that are included in the default for sellall, that the first 27 or so entries, were the blocks that were used in the auto generated mines when running the command '/ranks autoConfigure'.** diff --git a/gradle.properties b/gradle.properties index d4040c53b..a70ffb933 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.19d +version=3.3.0-alpha.19e 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 10ceb11e7..aa62891c8 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 @@ -144,8 +144,13 @@ private void initCachedData() { 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).get(); 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).get(); 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(); From a3568f8549738cc5a8439174ef75ce8ae1974fdc Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 22 Dec 2024 22:32:22 -0500 Subject: [PATCH 227/323] PrisonBlock: Significant modifications to support non-prison blocks for sellall. The alters many behaviors to allow for almost any dynamic custom block name, outside of the supported custom items. Created constants for the selection wand, both for the PrisonBlock and the item stack. These changes will support sellall's use of more dynamic block names that are not within prison. If it is a custom block name, then it will be added to prison's list of blocks. These should not be used in mines since prison cannot generate them faithfully. --- docs/changelog_v3.3.x.md | 10 ++- .../mcprison/prison/internal/ItemStack.java | 32 ++++++- .../prison/internal/block/PrisonBlock.java | 84 +++++++++++++++++-- .../internal/block/PrisonBlockTypes.java | 25 ++++-- .../prison/selection/SelectionListener.java | 6 +- .../prison/selection/SelectionManager.java | 17 ++-- .../prison/selection/SelectionTest.java | 3 +- .../events/PrisonDebugBlockInspector.java | 13 +-- 8 files changed, 159 insertions(+), 31 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 25f41beca..8411768e4 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,15 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.19e 2024-12-14 +# 3.3.0-alpha.19e 2024-12-22 + + + +* **PrisonBlock: Significant modifications to support non-prison blocks for sellall.** +The alters many behaviors to allow for almost any dynamic custom block name, outside of the supported custom items. +Created constants for the selection wand, both for the PrisonBlock and the item stack. +These changes will support sellall's use of more dynamic block names that are not within prison. If it is a custom block name, then it will be added to prison's list of blocks. These should not be used in mines since prison cannot generate them faithfully. + ### Version 3.3.0-alpha.19e 2024-12-14 diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/ItemStack.java b/prison-core/src/main/java/tech/mcprison/prison/internal/ItemStack.java index 4dca23666..dac4d23bc 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/ItemStack.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/ItemStack.java @@ -41,6 +41,13 @@ public class ItemStack { private List lore; // private Map enchantments; + public static final ItemStack SELECTION_WAND; + + static { + SELECTION_WAND = new ItemStack( 1, PrisonBlock.SELECTION_WAND, + "&7Corner 1 - Left click", + "&7Corner 2 - Right click"); + } /** * Do not use this constructor, it is for unit testing. @@ -55,8 +62,13 @@ protected ItemStack() { public ItemStack(String displayName, int amount, PrisonBlock material, String... lore) { this.displayName = displayName; this.amount = amount; - this.material = material; + this.material = material.clone(); this.lore = new ArrayList<>(Arrays.asList(lore)); + + if ( displayName != null && displayName.trim().length() > 0 ) { + this.material.setDisplayName( displayName.trim() ); + } + // this.enchantments = new HashMap<>(); } @@ -64,6 +76,10 @@ public ItemStack(int amount, PrisonBlock material, String... lore) { this.amount = amount; this.material = material; this.lore = new ArrayList<>(Arrays.asList(lore)); + + if ( material.getDisplayName() != null && material.getDisplayName().trim().length() > 0 ) { + setDisplayName( material.getDisplayName() ); + } } public ItemStack( ItemStack iStack ) { @@ -71,6 +87,10 @@ public ItemStack( ItemStack iStack ) { this.amount = iStack.getAmount(); this.material = iStack.getMaterial().clone(); this.lore = new ArrayList<>( iStack.getLore() ); + + if ( displayName != null && displayName.trim().length() > 0 ) { + this.material.setDisplayName( displayName.trim() ); + } } /** @@ -114,6 +134,16 @@ public PrisonBlock getMaterial() { public void setMaterial( PrisonBlock material ) { this.material = material; } + + /** + *

The material for an item stack is the PrisonBlock. + *

+ * + * @return + */ + public PrisonBlock getPrisonBlock() { + return getMaterial(); + } public List getLore() { return lore; 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 cd97fb775..9a1601ea3 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 @@ -6,6 +6,7 @@ import tech.mcprison.prison.internal.ItemStack; import tech.mcprison.prison.internal.block.PrisonBlockTypes.InternalBlockTypes; import tech.mcprison.prison.util.Location; +import tech.mcprison.prison.util.Text; /** *

This class embodies the nature of the block and different behaviors, if @@ -24,6 +25,7 @@ public class PrisonBlock public static PrisonBlock AIR; public static PrisonBlock GLASS; public static PrisonBlock PINK_STAINED_GLASS; + public static PrisonBlock SELECTION_WAND; public static PrisonBlock BLAZE_ROD; public static PrisonBlock LAPIS_ORE; public static PrisonBlock IGNORE; @@ -52,6 +54,9 @@ public class PrisonBlock AIR = new PrisonBlock( InternalBlockTypes.AIR.name(), false ); GLASS = new PrisonBlock( InternalBlockTypes.GLASS.name(), true ); PINK_STAINED_GLASS = new PrisonBlock( InternalBlockTypes.PINK_STAINED_GLASS.name(), true ); + SELECTION_WAND = new PrisonBlock( InternalBlockTypes.BLAZE_ROD.name(), false ); + SELECTION_WAND.setDisplayName( "&6Selection Wand" ); + BLAZE_ROD = new PrisonBlock( InternalBlockTypes.BLAZE_ROD.name(), false ); LAPIS_ORE = new PrisonBlock( InternalBlockTypes.LAPIS_ORE.name(), true ); IGNORE = new PrisonBlock( InternalBlockTypes.IGNORE.name(), true ); @@ -77,6 +82,32 @@ public boolean isCustomBlockType() { */ public PrisonBlock( String blockName ) { this( PrisonBlockType.minecraft, blockName, 0, 0); + + // If the blockName as a PrisonBlockType, then strip it off of the blockName + // and set the new name for the block, plus set the BlockType. + for (PrisonBlockType bType : PrisonBlockType.values() ) { + String blockType = bType.name() + ":"; + + if ( blockName.startsWith( blockType ) ) { + blockName = blockName.replace( blockType, blockName ); + setBlockName( blockName ); + setBlockType( bType ); + + break; + } + } + + // If there is still a ':' then everything after that is a formatted displayName. + // Strip it off save it. + if ( getBlockName().contains( ":" ) ) { + String[] bNameDisplayName = getBlockName().split(":"); + + if ( bNameDisplayName.length == 2 ) { + setBlockName( bNameDisplayName[0] ); + setDisplayName( bNameDisplayName[1] ); + } + } + } public PrisonBlock( String blockName, String displayName ) { this( PrisonBlockType.minecraft, blockName, 0, 0); @@ -114,11 +145,16 @@ public PrisonBlock( PrisonBlock clonable ) { clonable.getChance(), clonable.getBlockCountTotal() ); + this.setDisplayName( clonable.getDisplayName() ); + this.useBlockTypeAsPrefix = clonable.isUseBlockTypeAsPrefix(); this.valid = clonable.isValid(); this.block = clonable.isBlock(); this.legacyBlock = clonable.isLegacyBlock(); + this.setLoreAllowed( clonable.isLoreAllowed() ); + this.setSalePrice( clonable.getSalePrice() ); + this.setPurchasePrice( clonable.getPurchasePrice() ); this.location = clonable == null || clonable.getLocation() == null ? null : new Location( clonable.getLocation() ); @@ -126,8 +162,22 @@ public PrisonBlock( PrisonBlock clonable ) { @Override public String toString() { - return getBlockType().name() + ": " + getBlockName() + - ( getChance() > 0 ? " " + Double.toString( getChance()) : ""); + + StringBuilder sb = new StringBuilder(); + + sb.append( getBlockType().name() ) + .append( ":" ) + .append( getBlockName() ); + + if ( getChance() > 0 ) { + sb.append( " " ) + .append( Double.toString( getChance()) ); + } + + return sb.toString(); + +// return getBlockType().name() + ": " + getBlockName() + +// ( getChance() > 0 ? " " + Double.toString( getChance()) : ""); } // public PrisonBlockType getBlockType() { @@ -172,6 +222,10 @@ public String getBlockNameFormal() { * a type of minecraft. *

* + *

If the PrisonBlock has a display name, the color codes are stripped and then + * set to lower case, and spaces are replaced with '_'. Then the block search name is + * appended with the display name preceded with a ':'. + * * @return */ public String getBlockNameSearch() { @@ -181,12 +235,27 @@ public String getBlockNameSearch() { String blockName = getBlockName().toLowerCase(); - String displayName = getDisplayName() != null ? - ":" + getDisplayName().toLowerCase() : ""; + String displayName = getDisplayNameText(); + if ( displayName != null ) { + displayName = ":" + displayName.toLowerCase().replace(" ", "_"); + } + else { + displayName = ""; + } + return blockType + blockName + displayName; } + public String getDisplayNameText() { + String results = getDisplayName(); + + if ( results != null ) { + results = Text.stripColor( results.trim() ); + } + + return results; + } public String getBlockCoordinates() { StringBuilder sb = new StringBuilder(); @@ -380,9 +449,12 @@ public int compareTo( PrisonBlock block ) results = getBlockName().compareToIgnoreCase( block.getBlockName() ); - if ( results == 0 && getDisplayName() != null && block.getDisplayName() != null ) { - results = getDisplayName().compareToIgnoreCase( block.getDisplayName() ); + if ( results == 0 && getBlockNameSearch() != null && block.getBlockNameSearch() != null ) { + results = getBlockNameSearch().compareToIgnoreCase( block.getBlockNameSearch() ); } +// if ( results == 0 && getDisplayName() != null && block.getDisplayName() != null ) { +// results = getDisplayName().compareToIgnoreCase( block.getDisplayName() ); +// } } } diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/block/PrisonBlockTypes.java b/prison-core/src/main/java/tech/mcprison/prison/internal/block/PrisonBlockTypes.java index b5054d682..05e2fe764 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/block/PrisonBlockTypes.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/block/PrisonBlockTypes.java @@ -63,7 +63,7 @@ private void initializeBlockTypes() { // Map all available blocks to the blockTypesByName map: for ( PrisonBlock pb : getBlockTypes() ) { - getBlockTypesByName().put( pb.getBlockName().toLowerCase(), pb ); + getBlockTypesByName().put( pb.getBlockNameSearch(), pb ); } } @@ -86,30 +86,36 @@ public void addBlockTypes( List blockTypes ) { // Map all available blocks to the blockTypesByName map: for ( PrisonBlock pb : blockTypes ) { + + String blockKey = pb.getBlockNameSearch(); // Check to see if this current block pb already exists, if it does // then set the prefix usage: - if ( getBlockTypesByName().containsKey( pb.getBlockName().toLowerCase() )) { + if ( getBlockTypesByName().containsKey( blockKey ) ) { pb.setUseBlockTypeAsPrefix( true ); } - getBlockTypesByName().put( pb.getBlockName().toLowerCase(), pb ); + + getBlockTypesByName().put( blockKey, pb ); +// getBlockTypesByName().put( pb.getBlockName().toLowerCase(), pb ); getBlockTypes().add( pb ); - if ( pb.getBlockType() != PrisonBlockType.minecraft ) { - - getBlockTypesByName().put( pb.getBlockNameSearch().toLowerCase(), pb ); - } +// if ( pb.getBlockType() != PrisonBlockType.minecraft || pb.getDisplayName() != null ) { +// +// getBlockTypesByName().put( blockKey, pb ); +// } } } public List getBlockTypes( String searchTerm, boolean restrictToBlocks ) { List results = new ArrayList<>(); + searchTerm = searchTerm.toLowerCase().replace(" ", "_"); + for ( PrisonBlock pBlock : getBlockTypes() ) { if ( (!restrictToBlocks || restrictToBlocks && pBlock.isBlock()) && - pBlock.getBlockNameSearch().toLowerCase().contains( searchTerm.toLowerCase() )) { + pBlock.getBlockNameSearch().contains( searchTerm )) { results.add( pBlock ); } } @@ -140,7 +146,10 @@ public PrisonBlock getBlockTypesByName( String blockName ) { blockName = blockName.toLowerCase(); if ( "air".equals( blockName ) ) { results = PrisonBlock.AIR; + return results; } + + // only minecraft types should not have the prefix: else if ( blockName.startsWith( PrisonBlockType.minecraft.name() + ":" )) { blockName = blockName.replaceAll( PrisonBlockType.minecraft.name() + ":", "" ); } diff --git a/prison-core/src/main/java/tech/mcprison/prison/selection/SelectionListener.java b/prison-core/src/main/java/tech/mcprison/prison/selection/SelectionListener.java index 3b9a2f756..bf4e41d05 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/selection/SelectionListener.java +++ b/prison-core/src/main/java/tech/mcprison/prison/selection/SelectionListener.java @@ -37,7 +37,8 @@ public void init() { @Subscribe public void onPlayerInteract(PrisonPlayerInteractEvent e) { ItemStack ourItem = e.getItemInHand(); - ItemStack toolItem = SelectionManager.SELECTION_TOOL; + ItemStack toolItem = ItemStack.SELECTION_WAND; +// ItemStack toolItem = SelectionManager.SELECTION_TOOL; if ( ourItem == null || !ourItem.equals(toolItem)) { return; @@ -53,7 +54,8 @@ public void onPlayerInteract(PrisonPlayerInteractEvent e) { .sendMessage("&7First position set to &8" + e.getClicked().toBlockCoordinates()); checkForEvent(e.getPlayer(), sel); - } else if (e.getAction() == PrisonPlayerInteractEvent.Action.RIGHT_CLICK_BLOCK) { + } + else if (e.getAction() == PrisonPlayerInteractEvent.Action.RIGHT_CLICK_BLOCK) { // Set second position Selection sel = Prison.get().getSelectionManager().getSelection(e.getPlayer()); sel.setMax(e.getClicked()); diff --git a/prison-core/src/main/java/tech/mcprison/prison/selection/SelectionManager.java b/prison-core/src/main/java/tech/mcprison/prison/selection/SelectionManager.java index 7d8aea24e..c0df99b6d 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/selection/SelectionManager.java +++ b/prison-core/src/main/java/tech/mcprison/prison/selection/SelectionManager.java @@ -23,7 +23,6 @@ import tech.mcprison.prison.internal.ItemStack; import tech.mcprison.prison.internal.Player; -import tech.mcprison.prison.internal.block.PrisonBlock; import tech.mcprison.prison.internal.inventory.Inventory; import tech.mcprison.prison.output.Output; @@ -32,9 +31,13 @@ */ public class SelectionManager { - public static final ItemStack SELECTION_TOOL = - new ItemStack("&6Selection Wand", 1, PrisonBlock.BLAZE_ROD, "&7Corner 1 - Left click", - "&7Corner 2 - Right click"); +// public static final ItemStack SELECTION_TOOL = +// new ItemStack( 1, PrisonBlock.SELECTION_WAND, +// "&7Corner 1 - Left click", +// "&7Corner 2 - Right click"); + +// new ItemStack("&6Selection Wand", 1, PrisonBlock.BLAZE_ROD, "&7Corner 1 - Left click", +// "&7Corner 2 - Right click"); private Map selectionMap; public SelectionManager() { @@ -51,7 +54,7 @@ public SelectionManager() { public void bestowSelectionTool(Player player) { int countBefore = selectionWandCount( player ); - player.give(SELECTION_TOOL); + player.give( ItemStack.SELECTION_WAND ); int countAfter = selectionWandCount( player ); @@ -66,9 +69,11 @@ private int selectionWandCount( Player player) { for (ItemStack is : inv.getItems()) { if ( is != null && + is.getMaterial().compareTo( ItemStack.SELECTION_WAND.getMaterial() ) == 0 // is.getName().toLowerCase().contains( "selection wand" ) && // is.getDisplayName().toLowerCase().contains( "selection wand" ) && - is.getMaterial().compareTo( PrisonBlock.BLAZE_ROD ) == 0 ) { +// is.getMaterial().compareTo( PrisonBlock.BLAZE_ROD ) == 0 + ) { count += is.getAmount(); } } diff --git a/prison-core/src/test/java/tech/mcprison/prison/selection/SelectionTest.java b/prison-core/src/test/java/tech/mcprison/prison/selection/SelectionTest.java index 188c13c4a..f22fb71dd 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/selection/SelectionTest.java +++ b/prison-core/src/test/java/tech/mcprison/prison/selection/SelectionTest.java @@ -59,7 +59,8 @@ public class SelectionTest { World ourWorld = new TestWorld("TestWorld"); TestPlayer ourPlayer = new TestPlayer(); - ItemStack coloredToolItemStack = SelectionManager.SELECTION_TOOL; + ItemStack coloredToolItemStack = ItemStack.SELECTION_WAND; +// ItemStack coloredToolItemStack = SelectionManager.SELECTION_TOOL; coloredToolItemStack .setDisplayName(Text.translateAmpColorCodes(coloredToolItemStack.getDisplayName())); 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 6ab3713f5..7b342ca5a 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 @@ -6,7 +6,6 @@ import org.bukkit.event.EventException; import org.bukkit.event.block.BlockBreakEvent; -import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.plugin.RegisteredListener; import com.cryptomorin.xseries.XMaterial; @@ -18,7 +17,6 @@ import tech.mcprison.prison.internal.events.player.PrisonPlayerInteractEvent; import tech.mcprison.prison.mines.data.Mine; import tech.mcprison.prison.output.Output; -import tech.mcprison.prison.selection.SelectionManager; import tech.mcprison.prison.spigot.block.OnBlockBreakMines; import tech.mcprison.prison.spigot.block.SpigotBlock; import tech.mcprison.prison.spigot.block.SpigotItemStack; @@ -112,9 +110,11 @@ public void onPlayerInteract( PrisonPlayerInteractEvent e ) { this.lastAccess = System.currentTimeMillis(); ItemStack ourItem = e.getItemInHand(); - ItemStack toolItem = SelectionManager.SELECTION_TOOL; + ItemStack toolItem = ItemStack.SELECTION_WAND; +// ItemStack toolItem = SelectionManager.SELECTION_TOOL; - if ( ourItem == null || !ourItem.equals(toolItem) || !Output.get().isDebug() ) { + if ( ourItem == null || ourItem.getMaterial().compareTo(toolItem.getMaterial()) != 0 || + !Output.get().isDebug() ) { return; } //e.setCanceled(true); @@ -328,9 +328,10 @@ public void dumpBlockBreakEvent( SpigotPlayer player, SpigotBlock sBlock, MineTa // boolean isWood = blockName.matches( "wood|log|planks|sapling" ); ItemStack ourItem = new SpigotItemStack( heldItem ); - ItemStack toolItem = SelectionManager.SELECTION_TOOL; + ItemStack toolItem = ItemStack.SELECTION_WAND; +// ItemStack toolItem = SelectionManager.SELECTION_TOOL; - boolean isMineWand = ourItem != null && ourItem.equals(toolItem); + boolean isMineWand = ourItem != null && ourItem.getMaterial().compareTo(toolItem.getMaterial()) == 0; // If what is being held is not a mine wand, then use what is being held: SpigotItemStack tool = From eafe1b2572fa920f33e2e697af17cfe32541bde9 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 22 Dec 2024 22:40:48 -0500 Subject: [PATCH 228/323] Sellall: Much better support for blocks with custom names. Both for rejecting the wrong blocks, but also for now being able to sell them. These changes are not perfect and does not support some conditions. These blocks that are added through sellall should never be used within mines because prison cannot create those blocks to place in the mines. New command: '/sellall addHand'. Improved a few other commands too such as '/sellall list' and '/sellall items inspect'. --- docs/changelog_v3.3.x.md | 6 + .../mcprison/prison/spigot/SpigotUtil.java | 11 +- .../commands/PrisonSpigotSellAllCommands.java | 191 ++++++++++++++---- .../prison/spigot/sellall/SellAllUtil.java | 125 +++++++++++- 4 files changed, 281 insertions(+), 52 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 8411768e4..e9a059d07 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.19e 2024-12-22 +* **Sellall: Much better support for blocks with custom names.** Both for rejecting the wrong blocks, but also for now being able to sell them. +These changes are not perfect and does not support some conditions. +Prison currently does not support multiple custom blocks with the same material types and the same display name. +These blocks that are added through sellall should never be used within mines because prison cannot create those blocks to place in the mines. +New command: '/sellall addHand'. Improved a few other commands too such as '/sellall list' and '/sellall items inspect'. + * **PrisonBlock: Significant modifications to support non-prison blocks for sellall.** The alters many behaviors to allow for almost any dynamic custom block name, outside of the supported custom items. 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 ea7f4c4fb..a01f6e656 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 @@ -200,11 +200,12 @@ public static SpigotItemStack getSpigotItemStack( PrisonBlock material, int amou return iStack; } - public static void getSpigotBlock( ItemStack iStack ) { - //XMaterial xmat = XMaterial.matchXMaterial( iStack ); - -// SpigotCompatibility.getInstance(). - } + +// public static void getSpigotBlock( ItemStack iStack ) { +// //XMaterial xmat = XMaterial.matchXMaterial( iStack ); +// +//// SpigotCompatibility.getInstance(). +// } /*public static HashMap addItemToPlayerInventory( 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 cd0e51c83..5bced6afa 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 @@ -302,12 +302,12 @@ else if (p == null){ if ( getPlayer( sender, playerName ) != null ) { - Output.get().sendInfo(sender, "&cSorry but the specified player must be online " - + "[/sellall sell %s]", playerName ); + sender.sendMessage( String.format( "&cSorry but the specified player must be online " + + "[/sellall sell %s]", playerName ) ); } else { - Output.get().sendInfo(sender, "&cSorry but you can't use that from the console!"); + sender.sendMessage( "&cSorry but you can't use that command from the console."); } @@ -325,7 +325,7 @@ else if (p == null){ if (sellAllUtil.isSellAllSellPermissionEnabled){ String permission = sellAllUtil.permissionSellAllSell; if (permission == null || !p.hasPermission(permission)){ - Output.get().sendWarn(new SpigotPlayer(p), + sender.sendMessage( messages.getString(MessagesConfig.StringID.spigot_message_missing_permission) // + " [" + permission + "]" ); @@ -354,14 +354,14 @@ public void sellAllSellHandCommand(CommandSender sender){ SellAllUtil sellAllUtil = SellAllUtil.get(); if (!sellAllUtil.isSellAllHandEnabled){ - Output.get().sendWarn(sender, "The command /sellall hand is disabled from the config!"); + sender.sendMessage( "The command /sellall hand is disabled from the config!"); return; } Player p = getSpigotPlayer(sender); if (p == null){ - Output.get().sendInfo(sender, "&cSorry but you can't use that from the console!"); + sender.sendMessage( "&cSorry but you can't use that from the console!"); return; } @@ -370,7 +370,7 @@ public void sellAllSellHandCommand(CommandSender sender){ if (sellAllUtil.isSellAllSellPermissionEnabled){ String permission = sellAllUtil.permissionSellAllSell; if (permission == null || !p.hasPermission(permission)){ - Output.get().sendWarn(new SpigotPlayer(p), + sender.sendMessage( messages.getString(MessagesConfig.StringID.spigot_message_missing_permission) // + " [" + permission + "]" ); @@ -466,12 +466,13 @@ 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 ); + sender.sendMessage( + String.format( "&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!"); + sender.sendMessage( "&cSorry but you can't use that from the console!"); } @@ -484,7 +485,7 @@ else if (p == null){ if (sellAllUtil.isSellAllSellPermissionEnabled){ String permission = sellAllUtil.permissionSellAllSell; if (permission == null || !p.hasPermission(permission)){ - Output.get().sendWarn(new SpigotPlayer(p), + sender.sendMessage( messages.getString(MessagesConfig.StringID.spigot_message_missing_permission) // + " [" + permission + "]" ); @@ -513,14 +514,14 @@ public void sellAllValueOfHandCommand(CommandSender sender){ SellAllUtil sellAllUtil = SellAllUtil.get(); if (!sellAllUtil.isSellAllHandEnabled){ - Output.get().sendWarn(sender, "The command `/sellall valueOfHand` is disabled from the config! (SellAllHandEnabled)"); + sender.sendMessage( "The command `/sellall valueOfHand` is disabled in the configs! (SellAllHandEnabled)"); return; } Player p = getSpigotPlayer(sender); if (p == null){ - Output.get().sendInfo(sender, "&cSorry but you can't use that from the console!"); + sender.sendMessage( "&cSorry but you can't use that from the console!"); return; } @@ -529,7 +530,7 @@ public void sellAllValueOfHandCommand(CommandSender sender){ if (sellAllUtil.isSellAllSellPermissionEnabled){ String permission = sellAllUtil.permissionSellAllSell; if (permission == null || !p.hasPermission(permission)){ - Output.get().sendWarn(new SpigotPlayer(p), + sender.sendMessage( messages.getString(MessagesConfig.StringID.spigot_message_missing_permission) // + " [" + permission + "]" ); @@ -732,21 +733,21 @@ private void sellAllAddCommand(CommandSender sender, SellAllUtil sellAllUtil = SellAllUtil.get(); if (itemID == null){ - Output.get().sendWarn(sender, messages.getString( + sender.sendMessage( messages.getString( MessagesConfig.StringID.spigot_message_sellall_item_missing_name)); return; } itemID = itemID.toUpperCase(); if (value == null){ - Output.get().sendWarn(sender, messages.getString( + sender.sendMessage( messages.getString( MessagesConfig.StringID.spigot_message_sellall_item_missing_price)); return; } if (sellAllUtil.sellAllConfig.getConfigurationSection("Items." + itemID) != null){ - Output.get().sendWarn(sender, itemID + " " + + sender.sendMessage( itemID + " " + messages.getString(MessagesConfig.StringID.spigot_message_sellall_item_already_added)); return; } @@ -755,25 +756,103 @@ private void sellAllAddCommand(CommandSender sender, XMaterial blockAdd; try { blockAdd = XMaterial.matchXMaterial(itemID).orElse(null); - } catch (IllegalArgumentException ex){ - Output.get().sendInfo(sender, messages.getString( + } + catch (IllegalArgumentException ex){ + sender.sendMessage( messages.getString( MessagesConfig.StringID.spigot_message_sellall_item_id_not_found) + " [" + itemID + "]"); return; } if (sellAllUtil.addSellAllBlock(blockAdd, value)){ - Output.get().sendInfo(sender, "&3 ITEM [" + itemID + ", " + value + "] " + + sender.sendMessage( "&3 ITEM [" + itemID + ", " + value + "] " + messages.getString(MessagesConfig.StringID.spigot_message_sellall_item_add_success)); } - } catch (IllegalArgumentException ex){ - Output.get().sendError(sender, messages.getString( + } + catch (IllegalArgumentException ex){ + sender.sendMessage( messages.getString( MessagesConfig.StringID.spigot_message_sellall_item_id_not_found) + " [" + itemID + "]"); } } + + + @Command(identifier = "sellall items addHand", + description = "Adds an item that the player is holding to sellall ", + permissions = "prison.admin", + onlyPlayers = false) + private void sellAllAddHandItemCommand(CommandSender sender, + @Arg(name = "Value", description = "The value of the item.") Double value ) { + + if ( !isEnabled() ) { + return; + } + SellAllUtil sellAllUtil = SellAllUtil.get(); + + + SpigotPlayer sPlayer = (SpigotPlayer) sender.getPlatformPlayer(); + + if ( sPlayer == null ) { + String msg = String.format( + "Only online players can add what they're holding." + ); + sender.sendMessage(msg); + } + else { + + SpigotPlayerUtil sUtil = new SpigotPlayerUtil( sPlayer ); + + SpigotItemStack iStack = sUtil.getItemInHand(); + + if ( iStack == null || iStack.isAir() ) { + + String msg = String.format( + "Nothing to add to sellall. You're not holding anything other than air." + ); + sender.sendMessage(msg); + } + else { + + if (value == null){ + sender.sendMessage( messages.getString( + MessagesConfig.StringID.spigot_message_sellall_item_missing_price)); + return; + } + + + + + PrisonBlock pBlock = iStack.getMaterial(); + + String displayName = iStack.getDisplayName(); + if ( displayName != null && displayName.trim().length() > 0 ) { + pBlock.setDisplayName( displayName.trim() ); + } + + String sellallName = pBlock.getBlockNameSearch(); + + + if (sellAllUtil.sellAllConfig.getConfigurationSection("Items." + sellallName) != null){ + sender.sendMessage( sellallName + " " + + messages.getString(MessagesConfig.StringID.spigot_message_sellall_item_already_added)); + return; + } + + + + if (sellAllUtil.addSellAllBlock( sellallName, value, pBlock )){ + sender.sendMessage( "&3 ITEM [" + sellallName + ", " + value + "] " + + messages.getString(MessagesConfig.StringID.spigot_message_sellall_item_add_success)); + } + +// sellAllAddCommand( sender, sellallName, value ); + + } + } + } + /** *

This will add the XMaterial and value to the sellall. * This will update even if the sellall has not been enabled. @@ -922,15 +1001,18 @@ private void sellAllAllowLoreCommand(CommandSender sender, // return; try { - XMaterial blockAdd; - try { - blockAdd = XMaterial.matchXMaterial(itemID).orElse(null); - } catch (IllegalArgumentException ex){ - Output.get().sendError(sender, messages.getString(MessagesConfig.StringID.spigot_message_sellall_item_id_not_found) + " [" + itemID + "]"); - return; - } - if (sellAllUtil.editAllowLore(blockAdd, allowLore )) { + PrisonBlock pBlock = Prison.get().getPlatform().getPrisonBlock( itemID ); + +// XMaterial blockAdd; +// try { +// blockAdd = XMaterial.matchXMaterial(itemID).orElse(null); +// } catch (IllegalArgumentException ex){ +// Output.get().sendError(sender, messages.getString(MessagesConfig.StringID.spigot_message_sellall_item_id_not_found) + " [" + itemID + "]"); +// return; +// } + + if (sellAllUtil.editAllowLore( pBlock, allowLore )) { Output.get().sendInfo(sender, "&3ITEM [" + itemID + ", allowLore= " + allowLore + "] " + messages.getString(MessagesConfig.StringID.spigot_message_sellall_item_edit_success)); } @@ -941,7 +1023,6 @@ private void sellAllAllowLoreCommand(CommandSender sender, } - @Command(identifier = "sellall items inspect", description = "Inspects what the player is holding and provides a dump of all related " + "information.", @@ -977,15 +1058,18 @@ private void sellAllItemInspectCommand(CommandSender sender) { } else { + PrisonBlock pBlock = iStack.getMaterial(); + boolean iStackHasLore = iStack.getLore() != null && iStack.getLore().size() > 0; ChatDisplay chatDisplay = new ChatDisplay("&bSellall Items inspect: " ); List msg = new ArrayList<>(); String name = iStack.getName(); - String nameFull = iStack.getDisplayName() == null ? "" : iStack.getDisplayName(); + String nameSellall = pBlock.getBlockNameSearch(); + String nameFull = iStack.getDisplayName() == null ? "" : + "(" + Text.stripColor( iStack.getDisplayName()) + ")"; - PrisonBlock pBlock = iStack.getMaterial(); int amount = iStack.getAmount(); @@ -995,8 +1079,37 @@ private void sellAllItemInspectCommand(CommandSender sender) { String nbtInfo = iStack.getNBTItemStackInfo(); - chatDisplay.addText( "Item: %-14s (%s)", name, nameFull ); - chatDisplay.addText( "Qty: %5s PrisonItem: %s", + + chatDisplay.addText( "Item: %-14s %s", name, nameFull ); + chatDisplay.addText( "Sellall Name: &7%s &3(use this value when adding to sellall)", nameSellall ); + + + PrisonBlock sellallItem = sellAllUtil.getSellAllItems().get( nameSellall ); + boolean sellallItemAllowLore = sellallItem.isLoreAllowed(); + + if ( sellallItem != null && iStackHasLore == sellallItemAllowLore ) { + + String itemPrice = sellallItem.getSalePrice() == null ? "---" : + Prison.getDecimalFormatStaticInt().format( + sellallItem.getSalePrice().doubleValue() ); + chatDisplay.addText( " Item Price: &7%s", itemPrice ); + + if ( sellallItem.getPurchasePrice() != null ) { + + String purchasePrice = sellallItem.getPurchasePrice() == null ? "---" : + Prison.getDecimalFormatStaticInt().format( + sellallItem.getPurchasePrice().doubleValue() ); + chatDisplay.addText( " Purchase Price: &7%s", purchasePrice ); + } + + if ( sellallItem.isLoreAllowed() ) { + + chatDisplay.addText( " Allow Lore when sold: &7true" ); + } + } + + + chatDisplay.addText( "Quanty: %5s PrisonItem: %s", Integer.toString(amount), pBlock.getBlockNameFormal() ); if ( lore.size() == 0 ) { @@ -1692,13 +1805,14 @@ private void sellAllListItems( CommandSender sender ) { ChatDisplay chatDisplay = new ChatDisplay("&bSellall Item 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; +// boolean first = sb.length() == 0; Double cost = items.get( key ).getSalePrice(); - if ( !first ) { + if ( sb.length() > 0 ) { sb.append( " " ); } @@ -1707,7 +1821,7 @@ private void sellAllListItems( CommandSender sender ) { // sb.append( String.format( "%-" + maxLenKey + "s %" + maxLenVal + "s %-" + maxLenCode + "s", // key.toString(), fFmt.format( cost ), key.name() ) ); - if ( !first ) { + if ( ++columns >= 3 ) { chatDisplay.addText( sb.toString() ); if ( ++lines % 10 == 0 && lines > 1 ) { @@ -1715,6 +1829,7 @@ private void sellAllListItems( CommandSender sender ) { } sb.setLength( 0 ); + columns = 0; } } if ( sb.length() > 0 ) { 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 aa62891c8..4adfd842b 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 @@ -1206,6 +1206,7 @@ else if ( !pBlockSellAll.isLoreAllowed() && iStack.getLore().size() > 0 ) { return soldItem; } + public PrisonBlock getSellallItem( PrisonBlock block ) { PrisonBlock pBlockSellAll = sellAllItems.get( block.getBlockNameSearch() ); @@ -1550,6 +1551,17 @@ public HashMap initSellAllItems(){ String itemID = sellAllConfig.getString( itemPrefix + ".ITEM_ID"); PrisonBlock pBlock = Prison.get().getPlatform().getPrisonBlock(itemID); + + if ( pBlock == null ) { + // create a prison block for this sellall item: + pBlock = new PrisonBlock( key.trim().toLowerCase() ); + + // Add it: + List newBlockTypes = new ArrayList<>(); + newBlockTypes.add( pBlock ); + Prison.get().getPlatform().getPrisonBlockTypes().addBlockTypes( newBlockTypes ); + + } if ( pBlock != null ) { @@ -1574,7 +1586,8 @@ public HashMap initSellAllItems(){ try { double value = Double.parseDouble(purchaseValueString); pBlock.setPurchasePrice( value ); - } catch (NumberFormatException ignored) { + } + catch (NumberFormatException ignored) { } } @@ -1680,6 +1693,17 @@ public boolean addSellAllBlock(XMaterial xMaterial, double value) { return addSellAllBlock( xMaterial, null, value ); } + /** + *

Note: This function was flawed (now fixed). When searching for the sellall item, it uses the + * 'getBlockNameSearch()' which includes the displayName, but when setting the sellall + * item, it ignores the displayName. + *

+ * + * @param xMaterial + * @param displayName + * @param value + * @return + */ public boolean addSellAllBlock(XMaterial xMaterial, String displayName, double value) { PrisonBlock pBlockKey = Prison.get().getPlatform().getPrisonBlock( xMaterial.name() ); @@ -1687,6 +1711,12 @@ public boolean addSellAllBlock(XMaterial xMaterial, String displayName, double v Output.get().logDebug( "sellall add: invalid block name (%s)", xMaterial.name()); return false; } + + // Add the displayName to the block on it can be properly setup in sellall: + if ( displayName != null && displayName.trim().length() > 0 ) { + pBlockKey.setDisplayName( displayName ); + } + String key = pBlockKey.getBlockNameSearch(); // String key = pBlockKey.getBlockName().toLowerCase(); @@ -1735,6 +1765,82 @@ public boolean addSellAllBlock(XMaterial xMaterial, String displayName, double v // sellAllBlocks.put(xMaterial, value); return true; } + + /** + * + *

Warning: use with caution since this does not validate against XMaterial. + *

+ * + *

Note: This function was flawed (now fixed). When searching for the sellall item, it uses the + * 'getBlockNameSearch()' which includes the displayName, but when setting the sellall + * item, it ignores the displayName. + *

+ * + * @param xMaterial + * @param displayName + * @param value + * @return + */ + public boolean addSellAllBlock( String itemNameSearch, double value, PrisonBlock pBlock ) { + + PrisonBlock pBlockSellall = sellAllItems.get( itemNameSearch ); + + // If that is an invalid PrisonBlock, then exit + if ( pBlockSellall != null ) { + Output.get().logDebug( "sellall add: block already exists (%s)", itemNameSearch ); + return false; + } + + + // pBlock is null, but it's being used below. So clone the key: +// pBlock = pBlockKey.clone(); + + try { + + String itemName = itemNameSearch.toUpperCase(); + String displayName = pBlock.getDisplayName(); + + + File sellAllFile = new File(SpigotPrison.getInstance().getDataFolder() + "/SellAllConfig.yml"); + FileConfiguration conf = YamlConfiguration.loadConfiguration(sellAllFile); + + conf.set("Items." + itemName + ".ITEM_ID", itemNameSearch ); + conf.set("Items." + itemName + ".ITEM_VALUE", value); + conf.set("Items." + itemName + ".IS_LORE_ALLOWED", pBlock.isLoreAllowed() ); + + if ( displayName != null ) { + conf.set("Items." + itemName + ".ITEM_DISPLAY_NAME", displayName ); + } + + if (getBooleanValue("Options.Sell_Per_Block_Permission_Enabled")) { + String itemPerm = "Items." + itemName + ".ITEM_PERMISSION"; + conf.set( itemPerm, sellAllConfig.getString("Options.Sell_Per_Block_Permission") + itemNameSearch ); + } + conf.save(sellAllFile); + updateConfig(); + + pBlock.setSalePrice( value ); + + PrisonBlock pBlockKey = Prison.get().getPlatform().getPrisonBlock( itemNameSearch ); + if ( pBlockKey == null ) { + List pbList = new ArrayList<>(); + + pbList.add( pBlock ); + + Prison.get().getPlatform().getPrisonBlockTypes().addBlockTypes( pbList ); + } + + sellAllItems.put( itemNameSearch, pBlock ); + + } catch (IOException e) { + e.printStackTrace(); + return false; + } + + +// sellAllBlocks.put(xMaterial, value); + return true; + } // /** // * @@ -2100,22 +2206,23 @@ public boolean editPrice(XMaterial xMaterial, String displayName, double value) } - public boolean editAllowLore(XMaterial xMaterial, boolean value) { + public boolean editAllowLore( PrisonBlock pBlock, boolean value) { +// public boolean editAllowLore(XMaterial xMaterial, boolean value) { - PrisonBlock pBlockKey = Prison.get().getPlatform().getPrisonBlock( xMaterial.name() ); - String key = pBlockKey.getBlockNameSearch(); +// PrisonBlock pBlockKey = Prison.get().getPlatform().getPrisonBlock( xMaterial.name() ); +// String key = pBlockKey.getBlockNameSearch(); - PrisonBlock pBlock = sellAllItems.get( key ); +// 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 ( pBlock == null ){ + if ( sellAllItems.get(pBlock.getBlockNameSearch() ) == null ){ - Output.get().logDebug( "sellall edit: item does not exist in shop so it cannot be edited (%s)", pBlockKey.getBlockName()); + Output.get().logDebug( "sellall edit: item does not exist in shop so it cannot be edited (%s)", pBlock.getBlockName() ); return false; } if ( pBlock.isLoreAllowed() == value ){ Output.get().logDebug( "sellall edit: No change in 'allow lore' (%s %s)", - pBlockKey.getBlockName(), Boolean.toString( pBlock.isLoreAllowed() ) ); + pBlock.getBlockName(), Boolean.toString( pBlock.isLoreAllowed() ) ); return false; } @@ -2125,7 +2232,7 @@ public boolean editAllowLore(XMaterial xMaterial, boolean value) { File sellAllFile = new File(SpigotPrison.getInstance().getDataFolder() + "/SellAllConfig.yml"); FileConfiguration conf = YamlConfiguration.loadConfiguration(sellAllFile); - String itemName = key.toUpperCase(); + String itemName = pBlock.getBlockNameSearch().toUpperCase(); // conf.set("Items." + itemName + ".ITEM_ID", key ); conf.set("Items." + itemName + ".IS_LORE_ALLOWED", pBlock.isLoreAllowed() ); From c2de65aa148d271145450fe1399678eb4dd283f5 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 22 Dec 2024 23:20:51 -0500 Subject: [PATCH 229/323] PrisonBlock: Add isSellallOnly to prevent blocks added through sellall from being used in mines. --- docs/changelog_v3.3.x.md | 4 ++++ .../mcprison/prison/internal/block/Block.java | 4 ++-- .../prison/internal/block/PrisonBlock.java | 22 +++++++++++++++++++ .../internal/block/PrisonBlockTypes.java | 4 +++- .../resources/lang/mines/en_US.properties | 3 ++- .../resources/lang/mines/es_ES.properties | 3 ++- .../resources/lang/mines/fi_FI.properties | 3 ++- .../resources/lang/mines/fr_FR.properties | 5 +++-- .../resources/lang/mines/hu_HU.properties | 3 ++- .../resources/lang/mines/it_IT.properties | 3 ++- .../resources/lang/mines/nl_BE.properties | 3 ++- .../resources/lang/mines/nl_NL.properties | 3 ++- .../resources/lang/mines/pt_PT.properties | 3 ++- .../resources/lang/mines/ro_RO.properties | 3 ++- .../resources/lang/mines/zh-CN.properties | 5 +++-- .../resources/lang/mines/zh_TW.properties | 5 +++-- .../mines/commands/MinesBlockCommands.java | 6 +++++ .../prison/spigot/sellall/SellAllUtil.java | 4 ++++ 18 files changed, 68 insertions(+), 18 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index e9a059d07..b7774bbbd 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.19e 2024-12-22 +* **PrisonBlock: Add isSellallOnly to prevent blocks added through sellall from being used in mines.** + + + * **Sellall: Much better support for blocks with custom names.** Both for rejecting the wrong blocks, but also for now being able to sell them. These changes are not perfect and does not support some conditions. Prison currently does not support multiple custom blocks with the same material types and the same display name. 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 df65f516f..677eb1717 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 @@ -36,7 +36,7 @@ public interface Block { * * @return The {@link Location} of the block. */ - Location getLocation(); + public Location getLocation(); /** * Returns the {@link Block} at the position relative to this one. @@ -44,7 +44,7 @@ public interface Block { * @param face The {@link BlockFace} that the relative block touches. * @return The {@link Block} relative to this one. */ - Block getRelative(BlockFace face); + public Block getRelative(BlockFace face); // /** // * Returns the type of this block. 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 9a1601ea3..e0ee6ed29 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 @@ -40,6 +40,7 @@ public class PrisonBlock private boolean valid = true; private boolean block = true; + private boolean sellallOnly = false; private boolean legacyBlock = false; @@ -150,6 +151,8 @@ public PrisonBlock( PrisonBlock clonable ) { this.useBlockTypeAsPrefix = clonable.isUseBlockTypeAsPrefix(); this.valid = clonable.isValid(); this.block = clonable.isBlock(); + this.sellallOnly = clonable.isSellallOnly(); + this.legacyBlock = clonable.isLegacyBlock(); this.setLoreAllowed( clonable.isLoreAllowed() ); @@ -340,6 +343,25 @@ public void setBlock( boolean isBlock ){ this.block = isBlock; } + /** + *

If isSellallOnly, this item should never be used within a mine since prison + * cannot regenerate the block to place it in the mines. Custom blocks have + * many uncontrollable aspects on how they create and use blocks, of which + * prison cannot begin to magically guess all of these requirements. + *

+ * + *

If this value is set to true, then the PrisonBlock was added to prison as + * a custom block that is supported only within sellall. + *

+ * + * @return + */ + public boolean isSellallOnly() { + return sellallOnly; + } + public void setSellallOnly(boolean sellallOnly) { + this.sellallOnly = sellallOnly; + } /** *

This value isLegacyBlock indicates that there was not a direct match * with the stored (saved) name of the block, and list of valid block types diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/block/PrisonBlockTypes.java b/prison-core/src/main/java/tech/mcprison/prison/internal/block/PrisonBlockTypes.java index 05e2fe764..ba5cbfff2 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/block/PrisonBlockTypes.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/block/PrisonBlockTypes.java @@ -114,7 +114,9 @@ public List getBlockTypes( String searchTerm, boolean restrictToBlo searchTerm = searchTerm.toLowerCase().replace(" ", "_"); for ( PrisonBlock pBlock : getBlockTypes() ) { - if ( (!restrictToBlocks || restrictToBlocks && pBlock.isBlock()) && + if ( (!restrictToBlocks || + restrictToBlocks && + pBlock.isBlock() && !pBlock.isSellallOnly()) && pBlock.getBlockNameSearch().contains( searchTerm )) { results.add( pBlock ); } 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 325817eea..4ddf1717b 100644 --- a/prison-core/src/main/resources/lang/mines/en_US.properties +++ b/prison-core/src/main/resources/lang/mines/en_US.properties @@ -60,7 +60,7 @@ # -messages__version=5 +messages__version=6 messages__auto_refresh=true @@ -90,6 +90,7 @@ spawn_set=&7The mine spawnpoint has been set. spawn_removed=&7The mine spawnpoint has been removed. spawnpoint_same_world=&7The &cspawnpoint &7must be in the same &cworld &7as the mine. not_a_block=&c%1 &7is not a block. +not_a_block_sellall=&c%1 &7is not a block that can be used in mines. Its only for sellall usage. block_already_added=&7That block has already been added to the mine. mine_full=&cThe mine will be too full. &7Try lowering the percentage of this block and/or other blocks in the mine to make some room. block_added=&7Added block &3%1 &7to mine &3%2&7. 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 dcf8181ba..2f7de6a62 100644 --- a/prison-core/src/main/resources/lang/mines/es_ES.properties +++ b/prison-core/src/main/resources/lang/mines/es_ES.properties @@ -60,7 +60,7 @@ # -messages__version=5 +messages__version=6 messages__auto_refresh=true reset_warning=&7Todas las minas %1 se reiniciarán en &3%2&7. @@ -86,6 +86,7 @@ spawn_set=&7El punto de aparición (spawnpoint) de la mina ha sido definid. spawn_removed=&7The mine spawnpoint has been removed. spawnpoint_same_world=&7El &cpunto de aparición &7debe estar en el mismo &cmundo &7que la mina. not_a_block=&c%1 &7no es un bloque. +not_a_block_sellall=&c%1 &7is not a block that can be used in mines. Its only for sellall usage. block_already_added=&7Ese bloque ya ha sido añadido a la mina. mine_full=&cLa mina estará demasiado llena. &7Intenta reduciendo el porcentaje de este bloque y/u otros bloques en la mina para hacer más espacio. block_added=&7Se ha añadido el bloque &3%1 &7a la mina &3%2&7. 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 a17a07eae..d29b4e55c 100644 --- a/prison-core/src/main/resources/lang/mines/fi_FI.properties +++ b/prison-core/src/main/resources/lang/mines/fi_FI.properties @@ -60,7 +60,7 @@ # -messages__version=5 +messages__version=6 messages__auto_refresh=true @@ -90,6 +90,7 @@ spawn_set=&7Mainin spawni on asetettu. spawn_removed=&7Mainin spawni on onnistuneesti poistettu. spawnpoint_same_world=&cspawnpoint &7pitää olla samassa mailmassa kuin maini. not_a_block=&c%1 &7ei ole blockki. +not_a_block_sellall=&c%1 &7is not a block that can be used in mines. Its only for sellall usage. block_already_added=&7Tämä blockki on jo lisätty mainiin.. mine_full=&cMaini on jo täynnä. block_added=&7Lisätty &3%1 &7mainiin &3%2&7. 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 fccacf7cb..4cc5ac32d 100644 --- a/prison-core/src/main/resources/lang/mines/fr_FR.properties +++ b/prison-core/src/main/resources/lang/mines/fr_FR.properties @@ -60,7 +60,7 @@ # -messages__version=5 +messages__version=6 messages__auto_refresh=true @@ -89,7 +89,8 @@ mine_does_not_exist=&7Une mine du même nom existe déjà. spawn_set=&7Le point de spawn de la mine a été défini. spawn_removed=&7Le point de spawn de la mine a été supprimé. spawnpoint_same_world=&7Le &cpoint de spawn &7doit être dans le même &cmonde &7que la mine. -not_a_block=&c%1 &7n'est pas un bloc. +not_a_block=&c%1 &7n'est pas un bloc.. +not_a_block_sellall=&c%1 &7is not a block that can be used in mines. Its only for sellall usage. block_already_added=&7Ce bloc a déjà été ajouté dans la mine. mine_full=&cCette mine sera trop remplie. &7Essaye de réduire le percentage de ce block ou d'un autre dans la mine pour faire de la place. block_added=&7Le bloc &3%1 &7a été ajoutée à la mine &3%2&7. 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 83167c089..6ef77b837 100644 --- a/prison-core/src/main/resources/lang/mines/hu_HU.properties +++ b/prison-core/src/main/resources/lang/mines/hu_HU.properties @@ -60,7 +60,7 @@ # -messages__version=5 +messages__version=6 messages__auto_refresh=true @@ -90,6 +90,7 @@ spawn_set=&7A bánya spawnpontja beállítva. spawn_removed=&7The mine spawnpoint has been removed. spawnpoint_same_world=&7A &cspawnpont-nak&7 ugyanabban a &cvilágban&7 bányában kell lennie. not_a_block=&c%1 &7nem egy blokk. +not_a_block_sellall=&c%1 &7is not a block that can be used in mines. Its only for sellall usage. block_already_added=&7Ez a blokk már felkerült a bányába. mine_full=&cA bánya túlságosan tele lesz. &7Jobban próbáld csökkenteni a blokk és/vagy más blokkok százalékos arányát a bányában. block_added=&7A blokk hozzáadva &3%1 &7a(z) &3%2&7 bányához. 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 50773dfc3..06213227e 100644 --- a/prison-core/src/main/resources/lang/mines/it_IT.properties +++ b/prison-core/src/main/resources/lang/mines/it_IT.properties @@ -60,7 +60,7 @@ # -messages__version=5 +messages__version=6 messages__auto_refresh=true @@ -90,6 +90,7 @@ spawn_set=&7Il punto di spawn della miniera è stato settato. spawn_removed=&7The mine spawnpoint has been removed. spawnpoint_same_world=&7Il &cPunto di spawn &7deve essere nello stesso &cmondo &7della miniera. not_a_block=&c%1 &7non è un blocco. +not_a_block_sellall=&c%1 &7is not a block that can be used in mines. Its only for sellall usage. block_already_added=&7Quel blocco è già stato aggiunto alla miniera. mine_full=&cLa miniera con quel valore supera il limite. &7Prova ad abbassare la percentuale di questo blocco e / o altri blocchi nella miniera per fare spazio. block_added=&7Aggiunto il blocco &3%1 &7alla miniera &3%2&7. 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 7762b0988..a3464ed54 100644 --- a/prison-core/src/main/resources/lang/mines/nl_BE.properties +++ b/prison-core/src/main/resources/lang/mines/nl_BE.properties @@ -60,7 +60,7 @@ # -messages__version=5 +messages__version=6 messages__auto_refresh=true @@ -88,6 +88,7 @@ spawn_set=&7De mijn zijn startpunt is gezet. spawn_removed=&7The mine spawnpoint has been removed. spawnpoint_same_world=&7Het startpunt moet in dezelfde wereld als de mijn zijn . not_a_block=&c%1 &7is geen blok. +not_a_block_sellall=&c%1 &7is not a block that can be used in mines. Its only for sellall usage. block_already_added=&7Deze blok is al in de mijn toegevoegd. mine_full=&cDe mijn zal te vol worden. &7Probeer het precentage te verlagen van deze blok en/of andere bloken in de mijn om plaats te maken. block_added=&7blok &3%1 &7bijgevoeg &7bij mijn &3%2&7. 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 6d980bef4..b40f54a17 100644 --- a/prison-core/src/main/resources/lang/mines/nl_NL.properties +++ b/prison-core/src/main/resources/lang/mines/nl_NL.properties @@ -60,7 +60,7 @@ # -messages__version=5 +messages__version=6 messages__auto_refresh=true @@ -88,6 +88,7 @@ spawn_set=&7De mijn zijn startpunt is gezet. spawn_removed=&7The mine spawnpoint has been removed. spawnpoint_same_world=&7Het startpunt moet in dezelfde wereld als de mijn zijn . not_a_block=&c%1 &7is geen blok. +not_a_block_sellall=&c%1 &7is not a block that can be used in mines. Its only for sellall usage. block_already_added=&7Deze blok is al in de mijn toegevoegd. mine_full=&cDe mijn zal te vol worden. &7Probeer het precentage te verlagen van deze blok en/of andere bloken in de mijn om plaats te maken. block_added=&7blok &3%1 &7bijgevoeg &7bij mijn &3%2&7. 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 af7aa2c7b..0ef4465f9 100644 --- a/prison-core/src/main/resources/lang/mines/pt_PT.properties +++ b/prison-core/src/main/resources/lang/mines/pt_PT.properties @@ -60,7 +60,7 @@ # -messages__version=5 +messages__version=6 messages__auto_refresh=true @@ -90,6 +90,7 @@ spawn_set=&7O spawnpoint da mina foi defenido. spawn_removed=&7O spawnpoint da mina foi eliminado. spawnpoint_same_world=&7O &cspawnpoint &7tem de ser no mesmo &cmundo &7que a mina. not_a_block=&c%1 &7não é um bloco. +not_a_block_sellall=&c%1 &7is not a block that can be used in mines. Its only for sellall usage. block_already_added=&7Esse bloco já foi adicionado à mina. mine_full=&cA mina vai estar cheia demais. &7Tenta baixa a precentagem deste bloco e/ou outros blocos dentro da mina para fazer espaço. block_added=&7Bloco adicionado &3%1 &7á mina &3%2&7. 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 fe42318c2..0c2169975 100644 --- a/prison-core/src/main/resources/lang/mines/ro_RO.properties +++ b/prison-core/src/main/resources/lang/mines/ro_RO.properties @@ -60,7 +60,7 @@ # -messages__version=5 +messages__version=6 messages__auto_refresh=true @@ -90,6 +90,7 @@ spawn_set=&7Spawnpoint-ul minei a fost setat. spawn_removed=&7Spawnpoint-ul minei a fost È™ters. spawnpoint_same_world=&cSpawnpoint-ul &7trebuie să fie în aceeaÈ™i &clume &7cu mina. not_a_block=&c%1 &7nu este un block. +not_a_block_sellall=&c%1 &7is not a block that can be used in mines. Its only for sellall usage. block_already_added=&7Acel block a fost adăugat deja în mină. mine_full=&cMina va fi prea plină. &7ÃŽncearcă să scazi È™ansele apariÈ›iei acestui block È™i/sau altor block-uri din mină pentru a avea mai mult spaÈ›iu. block_added=&7Block-ul &3%1 &7a fost adăugat în mina &3%2&7. 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 d5e632a9b..3259e89a6 100644 --- a/prison-core/src/main/resources/lang/mines/zh-CN.properties +++ b/prison-core/src/main/resources/lang/mines/zh-CN.properties @@ -60,7 +60,7 @@ # -messages__version=4 +messages__version=6 messages__auto_refresh=true @@ -89,7 +89,8 @@ mine_does_not_exist=&7没有å«è¿™ä¸ªå字的矿区 spawn_set=&7矿区出生点已设置 spawn_removed=&7矿区出生点已移除 spawnpoint_same_world=&7&c出生点&7必须与矿区ä½äºŽåŒä¸€ä¸ª&c世界&7中 -not_a_block=&c%1 &7䏿˜¯ä¸€ä¸ªæ–¹å—,请检查拼写 +not_a_block=&c%1 &7䏿˜¯ä¸€ä¸ªæ–¹å—,请检查拼å +not_a_block_sellall=&c%1 &7is not a block that can be used in mines. Its only for sellall usage. block_already_added=&7该方å—å·²æˆåŠŸæ·»åŠ åˆ°çŸ¿åŒºä¸­ mine_full=&c矿区满了 &7试ç€é™ä½Žè¯¥æ–¹å—或其他方å—的百分比,以腾出一些空间 block_added=&7将方å—&3%1 &7添加到矿区&3%2&7. 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 7de3182b6..045bf9d92 100644 --- a/prison-core/src/main/resources/lang/mines/zh_TW.properties +++ b/prison-core/src/main/resources/lang/mines/zh_TW.properties @@ -60,7 +60,7 @@ # -messages__version=6 +messages__version=7 messages__auto_refresh=true @@ -89,7 +89,8 @@ mine_does_not_exist=&7此礦場å稱並ä¸å­˜åœ¨ spawn_set=&7礦場出生點 å·²æˆåŠŸ 設定 spawn_removed=&7The mine spawnpoint has been removed. spawnpoint_same_world=&7這個 &c出生點 &7必須與其他 礦場 在åŒä¸€å€‹ &c世界 -not_a_block=&c%1 &7䏿˜¯ä¸€å€‹æ–¹å¡Š +not_a_block=&c%1 &7䏿˜¯ä¸€å€‹æ–¹å¡ +not_a_block_sellall=&c%1 &7is not a block that can be used in mines. Its only for sellall usage. block_already_added=&7此方塊已經被新增到礦場 mine_full=&c此礦場已經滿了。 &7è«‹é™ä½Žç¤¦å ´ä¸­è©²æ–¹å¡Šæˆ–其他方塊的 百分比 以騰出更多空間 block_added=&7將方塊 &3%1 &7加入到礦場 &3%2&7 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 a1687677a..1448f02cc 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 @@ -70,6 +70,12 @@ public void addBlockCommand(CommandSender sender, return; } + if ( prisonBlock.isSellallOnly() ) { + pMines.getMinesMessages().getLocalizable("not_a_block_sellall"). + withReplacements(block).sendTo(sender); + return; + } + if ( !prisonBlock.isBlock() ) { pMines.getMinesMessages().getLocalizable("not_a_block"). withReplacements(block).sendTo(sender); 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 4adfd842b..1f5ec5758 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 @@ -1556,6 +1556,10 @@ public HashMap initSellAllItems(){ // create a prison block for this sellall item: pBlock = new PrisonBlock( key.trim().toLowerCase() ); + + // Prevent this item from being used within mines: + pBlock.setSellallOnly( true ); + // Add it: List newBlockTypes = new ArrayList<>(); newBlockTypes.add( pBlock ); From 24fad02a2b95f1d52c3bebbc09f59fe591eac472 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 18 Jan 2025 18:57:28 -0500 Subject: [PATCH 230/323] Ranks: Some rank commands were failing to work properly because they were not getting the correct player. Instead of getting the play by name, it was using the sender, which would have been the player issuing the command. This was an issue with '/ranks promote' and '/ranks demote' when issued in game. This was fixed by only allowing the named player to be resolved, without giving the sender an option to be used. This was changed in a number of areas to help protect form possible errors. --- docs/changelog_v3.3.x.md | 8 +- .../prison/commands/BaseCommands.java | 42 ++- .../prison/mines/commands/MinesCommands.java | 14 +- .../prison/ranks/commands/RankUpCommand.java | 254 ++++++++++++------ .../prison/ranks/commands/RanksCommands.java | 67 +++-- .../ranks/commands/RanksCommandsMessages.java | 14 + 6 files changed, 290 insertions(+), 109 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index b7774bbbd..deb1eb23e 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.19e 2024-12-22 +# 3.3.0-alpha.19e 2025-01-18 + + +* **Ranks: Some rank commands were failing to work properly because they were not getting the correct player.** +Instead of getting the play by name, it was using the sender, which would have been the player issuing the command. +This was an issue with '/ranks promote' and '/ranks demote' when issued in game. +This was fixed by only allowing the named player to be resolved, without giving the sender an option to be used. This was changed in a number of areas to help protect form possible errors. * **PrisonBlock: Add isSellallOnly to prevent blocks added through sellall from being used in mines.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/commands/BaseCommands.java b/prison-core/src/main/java/tech/mcprison/prison/commands/BaseCommands.java index ea05497a4..4f88645a1 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/commands/BaseCommands.java +++ b/prison-core/src/main/java/tech/mcprison/prison/commands/BaseCommands.java @@ -37,24 +37,50 @@ public void setCmdGroup( String cmdGroup ) { * ensure a player is always returned, if its a valid player. *

* + *

Never should this function return a Player based upon sender. + *

+ * * @param sender * @param playerName is optional, if not supplied, then sender will be used * @return Player if found, or null. */ - public Player getPlayer( CommandSender sender, String playerName ) { - return getPlayer( sender, playerName, null ); + public Player getPlayerByName( // CommandSender sender, + String playerName ) { + return getPlayerByName( // sender, + playerName, null ); } // public Player getPlayer( CommandSender sender ) { // return getPlayer( sender, null, null ); // } - public Player getPlayer( CommandSender sender, String playerName, UUID uuid ) { + + /** + *

This function should only return a Player based upon either the player's name + * or their UUID. It should never return a Player based upon sender. + *

+ * + *

Gets a player by name. If the player is not online, then try to get them from + * the offline player list. If not one is found, then return a null. + *

+ * + *

The getOfflinePlayer() will now include RankPlayer as a fall back to help + * ensure a player is always returned, if its a valid player. + *

+ * + * + * @param sender + * @param playerName + * @param uuid + * @return + */ + public Player getPlayerByName( // CommandSender sender, + String playerName, UUID uuid ) { Player result = null; - boolean console = sender == null ? true : "CONSOLE".equalsIgnoreCase( sender.getName() ); - - if ( !console ) { - playerName = sender.getName(); - } +// boolean console = sender == null ? true : "CONSOLE".equalsIgnoreCase( sender.getName() ); +// +// if ( !console ) { +// playerName = sender.getName(); +// } result = Prison.get().getPlatform().getRankPlayer( uuid, playerName ); 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 55e1516d6..ddea8d9ee 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 @@ -23,7 +23,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.Map.Entry; import java.util.Objects; import java.util.Optional; import java.util.Set; @@ -41,9 +40,7 @@ import tech.mcprison.prison.internal.World; import tech.mcprison.prison.internal.block.Block; import tech.mcprison.prison.internal.block.MineResetType; -import tech.mcprison.prison.internal.block.MineTargetPrisonBlock; import tech.mcprison.prison.internal.block.PrisonBlock; -import tech.mcprison.prison.internal.block.PrisonBlockStatusData; import tech.mcprison.prison.mines.PrisonMines; import tech.mcprison.prison.mines.data.Mine; import tech.mcprison.prison.mines.data.Mine.MineNotificationMode; @@ -3357,7 +3354,9 @@ public void mineTp(CommandSender sender, if ( mineName != null && "list".equals( mineName )) { - Player player = getPlayer( sender, playerName ); + Player player = playerName != null && playerName.trim().length() > 0 ? + getPlayerByName( playerName ) : + sender.getRankPlayer(); // Player playerAlt = getPlayer( playerName ); // @@ -5728,7 +5727,12 @@ else if ( world == null ) { player = sender.getPlatformPlayer(); } else { - player = getPlayer( sender, playerName ); + + // Get a Bukkit online player, which is needed to run the WorldGuard commands through: + Prison.get().getPlatform().getPlayer(playerName); + +// player = getPlayerByName( playerName ); +// player = getPlayer( sender, playerName ); } 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 c788a122b..c1b122ef3 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 @@ -104,22 +104,23 @@ public void rankUpMax(CommandSender sender, if ( !LadderManager.LADDER_PRESTIGES.equalsIgnoreCase( ladder ) && !LadderManager.LADDER_DEFAULT.equalsIgnoreCase( ladder )) { - success = rankUpPrivate(sender, "", ladder, mode, perms, cmdTasks, sbRanks ); + success = rankUpPrivate(sender, null, ladder, mode, perms, cmdTasks, sbRanks ); } else { // Run rankupmax on the default ladder only: - success = rankUpPrivate(sender, "", LadderManager.LADDER_DEFAULT, mode, perms, cmdTasks, sbRanks ); + success = rankUpPrivate(sender, null, LadderManager.LADDER_DEFAULT, mode, perms, cmdTasks, sbRanks ); // If they specified the prestiges ladder, then try to prestige that one rank: if ( success && LadderManager.LADDER_PRESTIGES.equalsIgnoreCase( ladder ) ) { - success = rankUpPrivate(sender, "", LadderManager.LADDER_PRESTIGES, RankupModes.ONE_RANK, perms, cmdTasks, sbRanks ); + success = rankUpPrivate(sender, null, LadderManager.LADDER_PRESTIGES, RankupModes.ONE_RANK, perms, cmdTasks, sbRanks ); } } - Player player = getPlayer( sender, null ); + Player player = getPlayerByName( sender.getName()); +// Player player = getPlayer( sender, null ); // submit cmdTasks if ( cmdTasks.size() > 0 ) { @@ -139,7 +140,8 @@ public void rankUpMax(CommandSender sender, } } else { - Player player = getPlayer( sender, null ); + Player player = getPlayerByName( sender.getName() ); +// Player player = getPlayer( sender, null ); Output.get().logDebug( DebugTarget.rankup, "Rankup: Failed: cmd '/rankupmax %s' Does not have the permission ranks.rankupmax.%s", ladder, ladder ); @@ -177,17 +179,37 @@ public void rankUp(CommandSender sender, boolean isPlayer = sender.isPlayer(); - if ( isPlayer ) { + if ( isPlayer && sender.isOp() && playerName != null && playerName.trim().length() > 0 ) { + // use playerName as is since the OP'd player is using this command on someone else: + } + else if ( isPlayer ) { playerName = ""; } // NOTE: If this is being ran from the console, the a 'playerName' parameter must be supplied: - if ( !isPlayer && playerName.length() == 0 ) { + else if ( !isPlayer && playerName.length() == 0 ) { Output.get().logInfo( rankupCannotRunFromConsoleMsg() ); return; } + + + + RankPlayer rPlayer = getRankPlayer(sender, null, playerName); + + if ( rPlayer == null ) { + rankupInvalidPlayerNameMsg( sender, playerName ); + return; + } + + +// Player player = getPlayerByName( playerName ); +// +// if ( player == null ) { +// rankupInvalidPlayerNameMsg( sender, playerName ); +// return; +// } // RankPlayer rPlayer = getRankPlayer(sender, null, playerName); @@ -261,7 +283,7 @@ public void rankUp(CommandSender sender, ); -; if ( isDefaultBypassPermCheck || + if ( isDefaultBypassPermCheck || isPrestigeBypassPermCheck || isLadderDefault && hasDefaultPerm || @@ -292,18 +314,20 @@ public void rankUp(CommandSender sender, List cmdTasks = new ArrayList<>(); - rankUpPrivate(sender, playerName, ladder, RankupModes.ONE_RANK, perms, cmdTasks, null ); + rankUpPrivate(sender, rPlayer, ladder, RankupModes.ONE_RANK, perms, cmdTasks, null ); +// rankUpPrivate(sender, playerName, ladder, RankupModes.ONE_RANK, perms, cmdTasks, null ); // submit cmdTasks - Player player = getPlayer( sender, playerName ); - submitCmdTasks( player, cmdTasks ); +// Player player = getPlayerByName( sender, playerName ); +// Player player = getPlayer( sender, playerName ); + submitCmdTasks( rPlayer, cmdTasks ); } else { - Player player = getPlayer( sender, playerName ); +// Player player = getPlayer( sender, playerName ); Output.get().logDebug( DebugTarget.rankup, "Rankup: Failed: cmd '/rankup %s' Does not have the permission %s. [%s]", ladder, permsLadder, permsCheck ); - rankupMaxNoPermissionMsg( sender, permsLadder, player.getRankPlayer() ); + rankupMaxNoPermissionMsg( sender, permsLadder, rPlayer ); } } @@ -467,11 +491,12 @@ public void prestigeCmd(CommandSender sender, List cmdTasks = new ArrayList<>(); String ladder = nRank.getLadder().getName(); - rankUpPrivate(sender, playerName, ladder, RankupModes.ONE_RANK, perms, cmdTasks, null ); + rankUpPrivate(sender, rPlayer, ladder, RankupModes.ONE_RANK, perms, cmdTasks, null ); +// rankUpPrivate(sender, playerName, ladder, RankupModes.ONE_RANK, perms, cmdTasks, null ); // submit cmdTasks - Player player = getPlayer( sender, playerName ); - submitCmdTasks( player, cmdTasks ); +// Player player = getPlayer( sender, playerName ); + submitCmdTasks( rPlayer, cmdTasks ); } else { // Player player = getPlayer( sender, playerName ); @@ -485,9 +510,43 @@ public void prestigeCmd(CommandSender sender, } } - - - private boolean rankUpPrivate(CommandSender sender, String playerName, String ladder, RankupModes mode, + + +// private boolean rankUpPrivateX(CommandSender sender, +// String playerName, +// String ladder, RankupModes mode, +// String permission, +// List cmdTasks, +// StringBuilder sbRanks ) { +// +// boolean rankupSuccess = false; +// +// if ( sender.isPlayer() ) { +// playerName = ""; +// } +// +// if ( !sender.isPlayer() && playerName.length() == 0 ) { +// Output.get().logInfo( rankupCannotRunFromConsoleMsg() ); +// return false; +// } +// +// +// // Player will always be the player since they have to be online and must be a player: +// Player player = getPlayerByName( playerName ); +// +// if ( player == null ) { +// rankupInvalidPlayerNameMsg( sender, playerName ); +// return false; +// } +// +// +// return rankupSuccess; +// } + + private boolean rankUpPrivate(CommandSender sender, + Player player, +// String playerName, + String ladder, RankupModes mode, String permission, List cmdTasks, StringBuilder sbRanks ) { @@ -532,27 +591,34 @@ private boolean rankUpPrivate(CommandSender sender, String playerName, String la } - if ( sender.isPlayer() ) { - playerName = ""; - } - - if ( !sender.isPlayer() && playerName.length() == 0 ) { - Output.get().logInfo( rankupCannotRunFromConsoleMsg() ); - return false; - } - +// if ( sender.isPlayer() ) { +// playerName = ""; +// } +// +// if ( !sender.isPlayer() && playerName.length() == 0 ) { +// Output.get().logInfo( rankupCannotRunFromConsoleMsg() ); +// return false; +// } +// +// +// // Player will always be the player since they have to be online and must be a player: +// Player player = getPlayer( sender, playerName ); +// +// if ( player == null ) { +// rankupInvalidPlayerNameMsg( sender, playerName ); +// return false; +// } - // Player will always be the player since they have to be online and must be a player: - Player player = getPlayer( sender, playerName ); - if ( player == null ) { - rankupInvalidPlayerNameMsg( sender, playerName ); - return false; - } - + //UUID playerUuid = player.getUUID(); - RankPlayer rankPlayer = getRankPlayer( sender, player.getUUID(), player.getName() ); + RankPlayer rankPlayer = + player == null ? + sender.getRankPlayer() : + player instanceof RankPlayer ? (RankPlayer) player : + player.getRankPlayer(); + ladder = confirmLadder( sender, ladder, rankPlayer ); if ( ladder == null ) { @@ -722,7 +788,7 @@ private boolean rankUpPrivate(CommandSender sender, String playerName, String la if (results.getStatus() == RankupStatus.RANKUP_SUCCESS && mode == RankupModes.MAX_RANKS ) { // if (results.getStatus() == RankupStatus.RANKUP_SUCCESS && mode == RankupModes.MAX_RANKS && // !ladder.equals(LadderManager.LADDER_PRESTIGES)) { - rankUpPrivate( sender, playerName, ladder, mode, permission, cmdTasks, sbRanks ); + rankUpPrivate( sender, rankPlayer, ladder, mode, permission, cmdTasks, sbRanks ); } if (results.getStatus() == RankupStatus.RANKUP_SUCCESS){ rankupSuccess = true; @@ -866,6 +932,18 @@ private void prestigePlayer(CommandSender sender, RankPlayer rankPlayer, } + + /** + *

This command requires that a target player be specified and that this can only be + * ran by an admin. The act of promoting a player cannot ever fall back on the person + * issuing the command. + *

+ * + * @param sender + * @param playerName + * @param ladder + * @param chargePlayer + */ @Command(identifier = "ranks promote", description = "Promotes a player to the next rank. This is an admin command. " + "This command can be used from the console. There is an " + @@ -880,34 +958,45 @@ public void promotePlayer(CommandSender sender, def = "no_charge") String chargePlayer ) { - Player player = getPlayer( sender, playerName ); - UUID playerUuid = player.getUUID(); - -// if (player == null) { -// ranksPromotePlayerMustBeOnlineMsg( sender ); -// return; -// } + + + RankPlayer rPlayer = getRankPlayer(sender, null, playerName); + + if ( rPlayer == null ) { + rankupInvalidPlayerNameMsg( sender, playerName ); + return; + } + + +// Player player = getPlayerByName( playerName ); +// +//// if (player == null) { +//// ranksPromotePlayerMustBeOnlineMsg( sender ); +//// return; +//// } + +// UUID playerUuid = player.getUUID(); RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); - RankPlayer rankPlayer = getRankPlayer( sender, playerUuid, player.getName() ); +// RankPlayer rankPlayer = getRankPlayer( sender, playerUuid, player.getName() ); PromoteForceCharge pForceCharge = PromoteForceCharge.fromString( chargePlayer ); if ( pForceCharge == null|| pForceCharge == PromoteForceCharge.refund_player ) { - ranksPromotePlayerInvalidChargeValueMsg( sender, rankPlayer ); + ranksPromotePlayerInvalidChargeValueMsg( sender, rPlayer ); return; } - ladder = confirmLadder( sender, ladder, rankPlayer ); + ladder = confirmLadder( sender, ladder, rPlayer ); if ( ladder == null ) { return; } - PlayerRank playerRank = rankPlayerFactory.getRank( rankPlayer, ladder ); + PlayerRank playerRank = rankPlayerFactory.getRank( rPlayer, ladder ); - if ( rankPlayer != null && playerRank != null ) { + if ( rPlayer != null && playerRank != null ) { Rank pRank = playerRank.getRank(); if ( pRank == null ) { @@ -922,13 +1011,13 @@ public void promotePlayer(CommandSender sender, List cmdTasks = new ArrayList<>(); - RankupResults results = new RankUtil().promotePlayer(player, rankPlayer, ladder, - player.getName(), sender.getName(), pForceCharge, cmdTasks ); + RankupResults results = new RankUtil().promotePlayer( rPlayer, rPlayer, ladder, + rPlayer.getName(), sender.getName(), pForceCharge, cmdTasks ); // submit cmdTasks... - submitCmdTasks( player, cmdTasks ); + submitCmdTasks( rPlayer, cmdTasks ); - processResults( sender, player.getName(), results, null, ladder, currency, null ); + processResults( sender, rPlayer.getName(), results, null, ladder, currency, null ); } else { @@ -955,23 +1044,32 @@ public void demotePlayer(CommandSender sender, def = "no_charge") String refundPlayer ) { - Player player = getPlayer( sender, playerName ); - - if (player == null) { - ranksPromotePlayerMustBeOnlineMsg( sender ); - return; - } + + RankPlayer rPlayer = getRankPlayer(sender, null, playerName); + + if ( rPlayer == null ) { + rankupInvalidPlayerNameMsg( sender, playerName ); + return; + } + + +// Player player = getPlayer( sender, playerName ); +// +// if (player == null) { +// ranksPromotePlayerMustBeOnlineMsg( sender ); +// return; +// } - UUID playerUuid = player.getUUID(); - RankPlayer rankPlayer = getRankPlayer( sender, playerUuid, player.getName() ); +// UUID playerUuid = player.getUUID(); +// RankPlayer rankPlayer = getRankPlayer( sender, playerUuid, player.getName() ); PromoteForceCharge pForceCharge = PromoteForceCharge.fromString( refundPlayer ); if ( pForceCharge == null || pForceCharge == PromoteForceCharge.charge_player ) { - ranksDemotePlayerInvalidRefundValueMsg( sender, rankPlayer ); + ranksDemotePlayerInvalidRefundValueMsg( sender, rPlayer ); return; } - ladder = confirmLadder( sender, ladder, rankPlayer ); + ladder = confirmLadder( sender, ladder, rPlayer ); if ( ladder == null ) { // Already displayed error message about ladder not existing: return; @@ -979,9 +1077,9 @@ public void demotePlayer(CommandSender sender, RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); - PlayerRank playerRank = rankPlayerFactory.getRank( rankPlayer, ladder ); + PlayerRank playerRank = rankPlayerFactory.getRank( rPlayer, ladder ); - if ( rankPlayer != null && playerRank != null ) { + if ( rPlayer != null && playerRank != null ) { Rank pRank = playerRank.getRank(); if ( pRank == null ) { @@ -996,13 +1094,13 @@ public void demotePlayer(CommandSender sender, List cmdTasks = new ArrayList<>(); - RankupResults results = new RankUtil().demotePlayer(player, rankPlayer, ladder, - player.getName(), sender.getName(), pForceCharge, cmdTasks ); + RankupResults results = new RankUtil().demotePlayer( rPlayer, rPlayer, ladder, + rPlayer.getName(), sender.getName(), pForceCharge, cmdTasks ); // submit cmdTasks - submitCmdTasks( player, cmdTasks ); + submitCmdTasks( rPlayer, cmdTasks ); - processResults( sender, player.getName(), results, null, ladder, currency, null ); + processResults( sender, rPlayer.getName(), results, null, ladder, currency, null ); } else { @@ -1032,8 +1130,8 @@ public void setRank(CommandSender sender, for ( RankPlayer player : pm.getPlayers() ) { - Player targetPlayer = getPlayer( null, player.getName() ); - if ( targetPlayer != null ) { +// Player targetPlayer = getPlayerByName( player.getName() ); +// if ( targetPlayer != null ) { boolean isSameRank = rank.equalsIgnoreCase("*same*"); @@ -1046,14 +1144,14 @@ public void setRank(CommandSender sender, pRank.getRank().getName() : ""; String targetRank = isSameRank ? rankNameCurrent : rank; - setPlayerRank( targetPlayer, targetRank, ladder, sender ); - } + setPlayerRank( player, targetRank, ladder, sender ); +// } } } else { - Player player = getPlayer( sender, playerName ); + Player player = getPlayerByName( playerName ); if (player == null) { ranksPromotePlayerMustBeOnlineMsg( sender ); @@ -1090,8 +1188,8 @@ public void setPlayerRank( RankPlayer rankPlayer, Rank pRank ) { cmdTasks ); // submit cmdTasks - Player player = getPlayer( null, rankPlayer.getName() ); - submitCmdTasks( player, cmdTasks ); +// Player player = getPlayerByName( rankPlayer.getName() ); + submitCmdTasks( rankPlayer, cmdTasks ); processResults( rankPlayer, rankPlayer.getName(), results, pRank.getName(), pRank.getLadder().getName(), @@ -1119,8 +1217,8 @@ public void setPlayerRankFirstJoin( RankPlayer rankPlayer, Rank pRank ) { cmdTasks ); // submit cmdTasks - Player player = getPlayer( null, rankPlayer.getName() ); - submitCmdTasks( player, cmdTasks ); +// Player player = getPlayer( null, rankPlayer.getName() ); + submitCmdTasks( rankPlayer, cmdTasks ); processResults( rankPlayer, rankPlayer.getName(), results, pRank.getName(), pRank.getLadder().getName(), 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 f7949cf19..210215e43 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 @@ -11,6 +11,7 @@ import java.util.Map; import java.util.Optional; import java.util.Set; +import java.util.UUID; import tech.mcprison.prison.Prison; import tech.mcprison.prison.PrisonAPI; @@ -1617,12 +1618,20 @@ public void rankPlayer(CommandSender sender, @Arg(name = "options", def = "", description = "Options [perms]") String options ){ - Player player = getPlayer( sender, playerName ); + RankPlayer rankPlayer = getRankPlayer(sender, null, playerName); + + if ( rankPlayer == null ) { + rankupInvalidPlayerNameMsg( sender, playerName ); + return; + } + - if (player == null) { - ranksPlayerOnlineMsg( sender ); - return; - } +// Player player = getPlayer( sender, playerName ); +// +// if (player == null) { +// ranksPlayerOnlineMsg( sender ); +// return; +// } List msgs = new ArrayList<>(); @@ -1634,7 +1643,7 @@ public void rankPlayer(CommandSender sender, //PlayerManager pm = PrisonRanks.getInstance().getPlayerManager(); - RankPlayer rankPlayer = player.getRankPlayer(); +// RankPlayer rankPlayer = player.getRankPlayer(); // RankPlayer rankPlayer = pm.getPlayer(player.getUUID(), player.getName()); // Get the cachedPlayer: @@ -1746,7 +1755,7 @@ public void rankPlayer(CommandSender sender, // The default currency first: double balance = rankPlayer.getBalance(); - String message = ranksPlayerBalanceDefaultMsg( player.getName(), dFmt.format( balance ) ); + String message = ranksPlayerBalanceDefaultMsg( rankPlayer.getName(), dFmt.format( balance ) ); msgs.add( message ); // sendToPlayerAndConsole( sender, message ); @@ -1754,18 +1763,18 @@ public void rankPlayer(CommandSender sender, for ( String currency : currencies ) { double balanceCurrency = rankPlayer.getBalance( currency ); String messageCurrency = ranksPlayerBalanceOthersMsg( - player.getName(), dFmt.format( balanceCurrency ), currency ); + rankPlayer.getName(), dFmt.format( balanceCurrency ), currency ); msgs.add( messageCurrency ); // sendToPlayerAndConsole( sender, messageCurrency ); } - boolean isOp = player.isOp(); - boolean isPlayer = player.isPlayer(); - boolean isOnline = player.isOnline(); + boolean isOp = rankPlayer.isOp(); + boolean isPlayer = rankPlayer.isPlayer(); + boolean isOnline = rankPlayer.isOnline(); - boolean isPrisonPlayer = (player instanceof Player); - boolean isPrisonOfflineMcPlayer = (player instanceof OfflineMcPlayer); + boolean isPrisonPlayer = (rankPlayer instanceof Player); + boolean isPrisonOfflineMcPlayer = (rankPlayer instanceof OfflineMcPlayer); if ( !isOnline ) { String msgOffline = ranksPlayerPermsOfflineMsg(); @@ -1789,7 +1798,7 @@ public void rankPlayer(CommandSender sender, // on the server, and they may not be their current listings. List sellallDetails = isOnline ? - player.getSellAllMultiplierListings() : + rankPlayer.getSellAllMultiplierListings() : rankPlayer.getSellallMultipliers(); @@ -1940,9 +1949,9 @@ public void rankPlayer(CommandSender sender, sendToPlayerAndConsole( sender, ranksPlayerPermsOfflineMsg() ); } - player.recalculatePermissions(); + rankPlayer.recalculatePermissions(); - List perms = player.getPermissions(); + List perms = rankPlayer.getPermissions(); listPermissions( sender, "bukkit", perms ); @@ -1958,7 +1967,7 @@ public void rankPlayer(CommandSender sender, PermissionIntegration integrationPerms = (PermissionIntegration) pIntegration; - List iPerms = integrationPerms.getPermissions( player, true ); + List iPerms = integrationPerms.getPermissions( rankPlayer, true ); String permSource = integrationPerms.getDisplayName(); listPermissions( sender, permSource, iPerms ); @@ -2638,4 +2647,28 @@ private boolean contains( String search, String... values ) { // } + + /** + * This gets the RankPlayer for the given UUID or playerName. The 'sender' generally is the + * console, or an admin that is trying to run the command for a player. + * So although the sender has a 'getRankPlayer()' function, it may be for the wrong player. + * + + * + * @param sender The one who should get an messages, but is not the one for RankPlayer. + * @param playerUuid + * @param playerName + * @return + */ + public RankPlayer getRankPlayer( CommandSender sender, UUID playerUuid, String playerName ) { + + RankPlayer player = PrisonRanks.getInstance().getPlayerManager().getPlayer(playerUuid, playerName); + + // Well, this isn't supposed to happen... + if ( player == null ) { + ranksRankupFailureToGetRankPlayerMsg( sender ); + } + + return player; + } } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommandsMessages.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommandsMessages.java index 67fbf342f..c98e55de7 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommandsMessages.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommandsMessages.java @@ -682,4 +682,18 @@ protected void ranksTopNPlayerDebugSaved( CommandSender sender ) { } + + protected void ranksRankupFailureToGetRankPlayerMsg( CommandSender sender ) { + PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( "ranks_rankup__rankup_failure_to_get_rankplayer" ) + .sendTo( sender ); + } + + + protected void rankupInvalidPlayerNameMsg(CommandSender sender, String playerName) { + PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( "ranks_rankup__invalid_player_name" ) + .withReplacements( playerName ) + .sendTo(sender); + } } From fa92eb9c64495c79ddcee63364a7aa0f142b1b07 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 19 Jan 2025 02:56:57 -0500 Subject: [PATCH 231/323] NBT-Lib: Upgrade from v2.14.0 to v2.14.1 so as to better support v1.21.4. --- docs/changelog_v3.3.x.md | 3 +++ gradle/libs.versions.toml | 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 deb1eb23e..434a2df8a 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.19e 2025-01-18 +* **NBT-Lib: Upgrade from v2.14.0 to v2.14.1 so as to better support v1.21.4.** + + * **Ranks: Some rank commands were failing to work properly because they were not getting the correct player.** Instead of getting the play by name, it was using the sender, which would have been the player issuing the command. This was an issue with '/ranks promote' and '/ranks demote' when issued in game. diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 3e2ea7dc4..8df8568ea 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -39,7 +39,7 @@ junit = "4.12" guava = "31.1-jre" spigotApi = "1.13.2-R0.1-SNAPSHOT" -nbtApi = "2.14.0" +nbtApi = "2.14.1" papi = "2.11.6" vault = "1.7.1" From ca782832bd111a20bec18f3aca1c99a0f5063299 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 20 Jan 2025 11:38:42 -0500 Subject: [PATCH 232/323] Sellall: Major changes to better support custom blocks. Not perfect overall, since some aspects are not fully handled, such as enchantments or filters on specific nbt values. These changes fixes most of the issues with identifying custom blocks and allows them to be sold. This also fixes a lot of the internals on sellall, which is forcing a lot of movement away from XMaterial and relying more on PrisonBlocks. Added better error messages to many functions, instead of just a generic stack trace. Need to do many more. --- docs/changelog_v3.3.x.md | 7 +- .../mcprison/prison/internal/ItemStack.java | 6 + .../mcprison/prison/spigot/SpigotCommand.java | 2 +- .../commands/PrisonSpigotSellAllCommands.java | 172 +++-- .../prison/spigot/game/SpigotPlayer.java | 2 +- .../gui/guiutility/SpigotGUIComponents.java | 36 +- .../prison/spigot/sellall/SellAllUtil.java | 598 ++++++++++++------ 7 files changed, 550 insertions(+), 273 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 434a2df8a..5c7b0774b 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.19e 2025-01-18 +# 3.3.0-alpha.19e 2025-01-20 + + +* **Sellall: Major changes to better support custom blocks. Not perfect overall, since some aspects are not fully handled, such as enchantments or filters on specific nbt values.** +These changes fixes most of the issues with identifying custom blocks and allows them to be sold. This also fixes a lot of the internals on sellall, which is forcing a lot of movement away from XMaterial and relying more on PrisonBlocks. +Added better error messages to many functions, instead of just a generic stack trace. Need to do many more. * **NBT-Lib: Upgrade from v2.14.0 to v2.14.1 so as to better support v1.21.4.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/ItemStack.java b/prison-core/src/main/java/tech/mcprison/prison/internal/ItemStack.java index dac4d23bc..69b47a971 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/ItemStack.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/ItemStack.java @@ -129,6 +129,12 @@ public void setAmount( int amount ) { * Returns the type of items in this stack. */ public PrisonBlock getMaterial() { + + if ( getDisplayName() != null && getDisplayName().trim().length() > 0 && + material.getDisplayName() == null || material.getDisplayName().trim().length() == 0 ) { + material.setDisplayName( getDisplayName() ); + } + return material; } public void setMaterial( PrisonBlock material ) { diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotCommand.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotCommand.java index 4907fbaac..9e2824307 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotCommand.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotCommand.java @@ -103,9 +103,9 @@ public void supportTroubleshootAutosellCmd(CommandSender sender ){ // Options.Sell_Per_Block_Permission: prison.sellall. // Options.SellAll_ignoreCustomNames: false + boolean saFullInvAutosell = SellAllUtil.isAutoSellEnabled(); boolean saPermsEnabled = saUtils.isSellAllSellPermissionEnabled; String saPermsStr = saUtils.permissionSellAllSell; - boolean saFullInvAutosell = saUtils.isAutoSellEnabled; boolean saUserToggle = saUtils.isAutoSellPerUserToggleable; boolean saUserTogglePermEnable = saUtils.isAutoSellPerUserToggleablePermEnabled; String saUserTogglePermStr = saUtils.permissionAutoSellPerUserToggleable; 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 5bced6afa..3325dcc1e 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 @@ -201,7 +201,7 @@ private void sellAllAutoSell(CommandSender sender, } boolean enableBoolean = getBoolean(enable); - if (sellAllUtil.isAutoSellEnabled == enableBoolean){ + if ( SellAllUtil.isAutoSellEnabled() == enableBoolean ) { if (enableBoolean){ Output.get().sendWarn(sender, messages.getString(MessagesConfig.StringID.spigot_message_sellall_auto_already_enabled)); } else { @@ -300,7 +300,7 @@ public void sellAllSellCommand(CommandSender sender, else if (p == null){ - if ( getPlayer( sender, playerName ) != null ) { + if ( getPlayerByName( playerName ) != null ) { sender.sendMessage( String.format( "&cSorry but the specified player must be online " + "[/sellall sell %s]", playerName ) ); @@ -464,7 +464,7 @@ public void sellAllValueOfCommand(CommandSender sender, else if (p == null){ - if ( getPlayer( sender, playerName ) != null ) { + if ( getPlayerByName( playerName ) != null ) { sender.sendMessage( String.format( "&cSorry but the specified player must be online " @@ -752,29 +752,34 @@ private void sellAllAddCommand(CommandSender sender, return; } - try { - XMaterial blockAdd; - try { - blockAdd = XMaterial.matchXMaterial(itemID).orElse(null); - } - catch (IllegalArgumentException ex){ - sender.sendMessage( messages.getString( - MessagesConfig.StringID.spigot_message_sellall_item_id_not_found) + - " [" + itemID + "]"); - return; - } - - if (sellAllUtil.addSellAllBlock(blockAdd, value)){ - sender.sendMessage( "&3 ITEM [" + itemID + ", " + value + "] " + - messages.getString(MessagesConfig.StringID.spigot_message_sellall_item_add_success)); - } - - } - catch (IllegalArgumentException ex){ - sender.sendMessage( messages.getString( - MessagesConfig.StringID.spigot_message_sellall_item_id_not_found) + - " [" + itemID + "]"); + if (sellAllUtil.addSellAllBlock( itemID, null, value )) { + sender.sendMessage( "&3 ITEM [" + itemID + ", " + value + "] " + + messages.getString(MessagesConfig.StringID.spigot_message_sellall_item_add_success)); } + +// try { +// XMaterial blockAdd; +// try { +// blockAdd = XMaterial.matchXMaterial(itemID).orElse(null); +// } +// catch (IllegalArgumentException ex){ +// sender.sendMessage( messages.getString( +// MessagesConfig.StringID.spigot_message_sellall_item_id_not_found) + +// " [" + itemID + "]"); +// return; +// } +// +// if (sellAllUtil.addSellAllBlock(blockAdd, value)){ +// sender.sendMessage( "&3 ITEM [" + itemID + ", " + value + "] " + +// messages.getString(MessagesConfig.StringID.spigot_message_sellall_item_add_success)); +// } +// +// } +// catch (IllegalArgumentException ex){ +// sender.sendMessage( messages.getString( +// MessagesConfig.StringID.spigot_message_sellall_item_id_not_found) + +// " [" + itemID + "]"); +// } } @@ -834,7 +839,7 @@ private void sellAllAddHandItemCommand(CommandSender sender, String sellallName = pBlock.getBlockNameSearch(); - if (sellAllUtil.sellAllConfig.getConfigurationSection("Items." + sellallName) != null){ + if (sellAllUtil.sellAllConfig.getConfigurationSection("Items." + sellallName.toUpperCase()) != null){ sender.sendMessage( sellallName + " " + messages.getString(MessagesConfig.StringID.spigot_message_sellall_item_already_added)); return; @@ -886,7 +891,7 @@ public void sellAllAddCommand(XMaterial blockAdd, Double value){ + "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){ + @Arg(name = "Item_ID", description = "The Item_ID you want to remove.") String itemID ) { if ( !isEnabled() ) { return; @@ -905,11 +910,15 @@ private void sellAllDeleteCommand(CommandSender sender, return; } - if (XMaterial.matchXMaterial(itemID).isPresent()) { - if (sellAllUtil.removeSellAllBlock(XMaterial.matchXMaterial(itemID).get())) { - Output.get().sendInfo(sender, itemID + " " + messages.getString(MessagesConfig.StringID.spigot_message_sellall_item_delete_success)); - } + if (sellAllUtil.removeSellAllBlock(itemID)) { + Output.get().sendInfo(sender, itemID + " " + messages.getString(MessagesConfig.StringID.spigot_message_sellall_item_delete_success)); } + +// if (XMaterial.matchXMaterial(itemID).isPresent()) { +// if (sellAllUtil.removeSellAllBlock(XMaterial.matchXMaterial(itemID).get())) { +// Output.get().sendInfo(sender, itemID + " " + messages.getString(MessagesConfig.StringID.spigot_message_sellall_item_delete_success)); +// } +// } } @Command(identifier = "sellall items edit", @@ -941,22 +950,33 @@ private void sellAllEditCommand(CommandSender sender, return; } - try { - XMaterial blockAdd; - try{ - blockAdd = XMaterial.matchXMaterial(itemID).orElse(null); - } catch (IllegalArgumentException ex){ - Output.get().sendError(sender, messages.getString(MessagesConfig.StringID.spigot_message_sellall_item_id_not_found) + " [" + itemID + "]"); - return; - } - - if (sellAllUtil.editPrice(blockAdd, value)){ - Output.get().sendInfo(sender, "&3ITEM [" + itemID + ", " + value + "] " + messages.getString(MessagesConfig.StringID.spigot_message_sellall_item_edit_success)); - } - - } catch (IllegalArgumentException ex){ + if ( sellAllUtil.editPrice( itemID, null, value ) ){ + Output.get().sendInfo(sender, "&3ITEM [" + itemID + ", " + value + "] " + messages.getString(MessagesConfig.StringID.spigot_message_sellall_item_edit_success)); + } + else { + Output.get().sendError(sender, messages.getString(MessagesConfig.StringID.spigot_message_sellall_item_id_not_found) + " [" + itemID + "]"); } + +// try { +// XMaterial blockAdd; +// try { +// String xMatName = itemID.lastIndexOf(":") > 0 ? itemID.substring(0, itemID.lastIndexOf(":") ) : itemID; +// +// blockAdd = XMaterial.matchXMaterial( xMatName ).orElse(null); +// } +// catch (IllegalArgumentException ex){ +// Output.get().sendError(sender, messages.getString(MessagesConfig.StringID.spigot_message_sellall_item_id_not_found) + " [" + itemID + "]"); +// return; +// } +// +// if (sellAllUtil.editPrice(blockAdd, value)){ +// Output.get().sendInfo(sender, "&3ITEM [" + itemID + ", " + value + "] " + messages.getString(MessagesConfig.StringID.spigot_message_sellall_item_edit_success)); +// } +// +// } catch (IllegalArgumentException ex){ +// Output.get().sendError(sender, messages.getString(MessagesConfig.StringID.spigot_message_sellall_item_id_not_found) + " [" + itemID + "]"); +// } } @@ -1773,11 +1793,18 @@ private void sellAllSetDefaultCommand(CommandSender sender){ @Command(identifier = "sellall list", description = "SellAll list all items", permissions = "prison.admin", onlyPlayers = false) - private void sellAllListItems( CommandSender sender ) { + private void sellAllListItems( CommandSender sender, + @Arg(name = "filter", def = "", + description = "Optionally, you can provide a filter word fragment " + + "that will include only sellall items that 'contains' the fragment. " + + "Example: 'gold', 'old', 'raw', 'ore'.") String filter ) { if ( !isEnabled() ) { return; } + + filter = filter == null || filter.trim().length() == 0 ? "" : filter.trim(); + SellAllUtil sellAllUtil = SellAllUtil.get(); TreeMap items = new TreeMap<>( sellAllUtil.getSellAllItems() ); @@ -1792,13 +1819,17 @@ private void sellAllListItems( CommandSender sender ) { // if ( key.toString().length() > maxLenKey ) { // maxLenKey = key.toString().length(); // } - if ( key.length() > maxLenCode ) { - maxLenCode = key.length(); - } - String val = fFmt.format( items.get( key ).getSalePrice() ); - if ( val.length() > maxLenVal ) { - maxLenVal = val.length(); - } + + if ( filter.length() == 0 || key.contains( filter ) ) { + + if ( key.length() > maxLenCode ) { + maxLenCode = key.length(); + } + String val = fFmt.format( items.get( key ).getSalePrice() ); + if ( val.length() > maxLenVal ) { + maxLenVal = val.length(); + } + } } @@ -1810,26 +1841,29 @@ private void sellAllListItems( CommandSender sender ) { for ( String key : keys ) { // boolean first = sb.length() == 0; - Double cost = items.get( key ).getSalePrice(); - - if ( sb.length() > 0 ) { - sb.append( " " ); - } - - sb.append( String.format( "%-" + maxLenCode + "s %" + maxLenVal + "s", - key, fFmt.format( cost ) ) ); + if ( filter.length() == 0 || key.contains( filter ) ) { + + Double cost = items.get( key ).getSalePrice(); + + if ( sb.length() > 0 ) { + sb.append( " " ); + } + + sb.append( String.format( "%-" + maxLenCode + "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 >= 3 ) { - chatDisplay.addText( sb.toString() ); - if ( ++lines % 10 == 0 && lines > 1 ) { - chatDisplay.addText( " " ); + if ( ++columns >= 3 ) { + chatDisplay.addText( sb.toString() ); + + if ( ++lines % 10 == 0 && lines > 1 ) { + chatDisplay.addText( " " ); + } + + sb.setLength( 0 ); + columns = 0; } - - sb.setLength( 0 ); - columns = 0; } } if ( sb.length() > 0 ) { 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 def2d537e..09885c94f 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 @@ -997,7 +997,7 @@ public boolean isAutoSellEnabled( StringBuilder debugInfo ) { boolean results = false; if ( SpigotPrison.getInstance().isSellAllEnabled() && - SellAllUtil.get().isAutoSellEnabled ) { + SellAllUtil.isAutoSellEnabled() ) { if ( SellAllUtil.get().isAutoSellPerUserToggleable ) { debugInfo.append( "(&7sellallEnabled:userToggleable&3)" ); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/guiutility/SpigotGUIComponents.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/guiutility/SpigotGUIComponents.java index 23ef463ea..40bc9b969 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/guiutility/SpigotGUIComponents.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/guiutility/SpigotGUIComponents.java @@ -37,7 +37,12 @@ public abstract class SpigotGUIComponents public static MessagesConfig messages = getMessages(); public static Configuration guiConfig = getGuiConfig(); - public static Configuration sellAllConfig = getSellAll(); + + public static Configuration sellAllConfig; + + static { + updateSellAllConfig(); + } // /** // * Bug: Cannot correctly create a button with Material variants with spigot versions less than 1.13: @@ -172,12 +177,12 @@ protected static MessagesConfig getMessages(){ return SpigotPrison.getInstance().getMessagesConfig(); } - /** - * Get SellAll config. - * */ - protected static Configuration getSellAll(){ - return SpigotPrison.getInstance().updateSellAllConfig(); - } +// /** +// * Get SellAll config. +// * */ +// protected static Configuration getSellAll(){ +// return SpigotPrison.getInstance().updateSellAllConfig(); +// } /** * Get GUI config. @@ -213,12 +218,17 @@ public static void updateMessages(){ /** * Reload sellall config for GUIs. * */ - public static void updateSellAllConfig(){ - SellAllUtil util = SpigotPrison.getInstance().getSellAllUtil(); - if ( util != null ) { - util.updateConfig(); - sellAllConfig = util.sellAllConfig; - } + public static void updateSellAllConfig() { + + if ( SellAllUtil.isAutoSellEnabled() ) { + + sellAllConfig = SellAllUtil.get().initCachedData(); + } + +// SellAllUtil util = SpigotPrison.getInstance().getSellAllUtil(); +// if ( util != null ) { +// sellAllConfig = util.sellAllConfig; +// } } public static void updateGUIConfig(){ 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 1f5ec5758..782985274 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 @@ -12,6 +12,7 @@ import org.bukkit.Bukkit; import org.bukkit.Sound; import org.bukkit.configuration.Configuration; +import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; @@ -53,10 +54,14 @@ public class SellAllUtil private static SellAllUtil instance; + + // private final Compatibility compat = SpigotPrison.getInstance().getCompatibility(); // private final ItemStack lapisLazuli = compat.getLapisItemStack(); public Configuration sellAllConfig; + + private static Boolean isAutoSellEnabled = null; private HashMap sellAllItems; // private HashMap sellAllBlocks; @@ -84,7 +89,6 @@ public class SellAllUtil public String permissionAutoSellPerUserToggleable; public String permissionItemTrigger; public boolean isPerBlockPermissionEnabled; - public boolean isAutoSellEnabled; public boolean isAutoSellPerUserToggleable; public boolean isAutoSellPerUserToggleablePermEnabled; public boolean isAutoSellNotificationEnabled; @@ -129,11 +133,33 @@ public static SellAllUtil get() { return instance; } + public static boolean isAutoSellEnabled() { + + if ( isAutoSellEnabled == null ) { + + isAutoSellEnabled = SpigotPrison.getInstance().isSellAllEnabled(); + } + + return isAutoSellEnabled == null ? false : isAutoSellEnabled; + } + /** * Init options that will be cached. + * @return * */ - private void initCachedData() { + public Configuration initCachedData() { + sellAllConfig = SpigotPrison.getInstance().updateSellAllConfig(); + + + refreshClassVariablesFromConfig(); + + return sellAllConfig; + } + + private void refreshClassVariablesFromConfig() { + + // messages = SpigotPrison.getInstance().getMessagesConfig(); permissionSellAllSell = sellAllConfig.getString("Options.Sell_Permission"); permissionBypassSign = sellAllConfig.getString("Options.SellAll_By_Sign_Bypass_Permission"); @@ -224,6 +250,67 @@ else if ( sellAllConfig.isBoolean(configName) ) { return results; } + + + + + + public ArrayList getSellAllItemTriggers() { + return sellAllItemTriggers; + } + public void setSellAllItemTriggers(ArrayList sellAllItemTriggers) { + this.sellAllItemTriggers = sellAllItemTriggers; + } + + public PrisonBlock getSellallItem( PrisonBlock blockKey ) { + + PrisonBlock pBlockSellAll = sellAllItems.get( blockKey.getBlockNameSearch() ); + + return pBlockSellAll; + } + public void putSellallItem( PrisonBlock pBlockKey ) { + sellAllItems.put( pBlockKey.getBlockNameSearch(), pBlockKey ); + } + + public HashMap getSellAllItems() { + return sellAllItems; + } + public void setSellAllItems(HashMap sellAllItems) { + this.sellAllItems = sellAllItems; + } + + public PrisonBlock getPrisonBlock( String itemName ) { + PrisonBlock pBlockKey = Prison.get().getPlatform().getPrisonBlock( itemName ); + return pBlockKey; + } + + + /** + * Return SellAll Prestige Multiplier HashMap read before from config on init. + * + * HashMap details: + * String is the name of the Prestige. + * Double is the multiplier (default 1). + * + * @return HashMap of String-Double. + * */ + public HashMap getPrestigeMultipliers() { + return sellAllPrestigeMultipliers; + } + + + + public PrisonBlock getSellAllPrisonBlockKey( String itemID ) { + + PrisonBlock pBlockKey = Prison.get().getPlatform().getPrisonBlock( itemID ); + if ( pBlockKey == null ) { + Output.get().logDebug( "sellall add: invalid block name (%s)", itemID); + return null; + } + + return pBlockKey; + } + // /** // * Return boolean value from String. @@ -320,26 +407,6 @@ public ArrayList getItemTriggerXMaterials(){ // return sellAllBlocks; // } - /** - * - * @return HashMap - */ - public HashMap getSellAllItems() { - return sellAllItems; - } - - /** - * Return SellAll Prestige Multiplier HashMap read before from config on init. - * - * HashMap details: - * String is the name of the Prestige. - * Double is the multiplier (default 1). - * - * @return HashMap of String-Double. - * */ - public HashMap getPrestigeMultipliers() { - return sellAllPrestigeMultipliers; - } // /** // * Get HashMap of XMaterials and amounts from an Inventory. @@ -1164,11 +1231,11 @@ private SellAllData sellItemStack( SpigotItemStack iStack, double multiplier ) { if ( iStack != null ) { - // This converts a bukkit ItemStackk to a PrisonBlock, and it also sets up the + // This converts a bukkit ItemStack to a PrisonBlock, and it also sets up the // displayName if that is set on the itemStack. PrisonBlock pBlockInv = iStack.getMaterial(); - PrisonBlock pBlockSellAll = sellAllItems.get( pBlockInv.getBlockNameSearch() ); + PrisonBlock pBlockSellAll = getSellallItem( pBlockInv ); if ( pBlockSellAll != null ) { @@ -1206,13 +1273,7 @@ else if ( !pBlockSellAll.isLoreAllowed() && iStack.getLore().size() > 0 ) { return soldItem; } - - public PrisonBlock getSellallItem( PrisonBlock block ) { - - PrisonBlock pBlockSellAll = sellAllItems.get( block.getBlockNameSearch() ); - - return pBlockSellAll; - } + // /** // * Get SellAll Sell Money, calculated from all the enabled backpacks (from sellAll config and integrations) and @@ -1434,7 +1495,7 @@ public boolean isSellallPlayerUserToggleEnabled( Player p ) { boolean results = false; // If autosell isn't enabled, then return false - if ( isAutoSellEnabled ) { + if ( isAutoSellEnabled() ) { if ( isAutoSellPerUserToggleable ) { @@ -1515,15 +1576,15 @@ public boolean isValidItem(String item){ return XMaterial.matchXMaterial(item).isPresent(); } - /** - * Update SellAll Cached config. - * */ - public void updateConfig(){ - - initCachedData(); - -// sellAllConfig = SpigotPrison.getInstance().updateSellAllConfig(); - } +// /** +// * Update SellAll Cached config. +// * */ +// public void updateConfig(){ +// +// initCachedData(); +// +//// sellAllConfig = SpigotPrison.getInstance().updateSellAllConfig(); +// } @@ -1694,7 +1755,7 @@ public ArrayList initSellAllItemTrigger(){ * @return boolean. * */ public boolean addSellAllBlock(XMaterial xMaterial, double value) { - return addSellAllBlock( xMaterial, null, value ); + return addSellAllBlock( xMaterial.name(), null, value ); } /** @@ -1708,11 +1769,11 @@ public boolean addSellAllBlock(XMaterial xMaterial, double value) { * @param value * @return */ - public boolean addSellAllBlock(XMaterial xMaterial, String displayName, double value) { + public boolean addSellAllBlock( String itemID, String displayName, double value) { - PrisonBlock pBlockKey = Prison.get().getPlatform().getPrisonBlock( xMaterial.name() ); + PrisonBlock pBlockKey = Prison.get().getPlatform().getPrisonBlock( itemID ); if ( pBlockKey == null ) { - Output.get().logDebug( "sellall add: invalid block name (%s)", xMaterial.name()); + Output.get().logDebug( "sellall add: invalid block name (%s)", itemID); return false; } @@ -1721,14 +1782,11 @@ public boolean addSellAllBlock(XMaterial xMaterial, String displayName, double v pBlockKey.setDisplayName( displayName ); } - String key = pBlockKey.getBlockNameSearch(); -// String key = pBlockKey.getBlockName().toLowerCase(); - - PrisonBlock pBlock = sellAllItems.get( key ); + PrisonBlock pBlock = getSellallItem( pBlockKey ); // If that is an invalid PrisonBlock, then exit if ( pBlock != null ) { - Output.get().logDebug( "sellall add: block already exists (%s)", xMaterial.name()); + Output.get().logDebug( "sellall add: block already exists (%s)", itemID); return false; } @@ -1738,29 +1796,39 @@ public boolean addSellAllBlock(XMaterial xMaterial, String displayName, double v try { - String itemName = pBlockKey.getBlockName().toUpperCase(); + File sellAllFile = new File(SpigotPrison.getInstance().getDataFolder() + "/SellAllConfig.yml"); + FileConfiguration conf = YamlConfiguration.loadConfiguration(sellAllFile); + + String itemName = pBlockKey.getBlockNameSearch().toUpperCase(); + String confKey = "Items." + itemName; + + ConfigurationSection confSection = conf.getConfigurationSection( confKey ); + + +// String itemName = pBlockKey.getBlockName().toUpperCase(); // BUG!! - File sellAllFile = new File(SpigotPrison.getInstance().getDataFolder() + "/SellAllConfig.yml"); - FileConfiguration conf = YamlConfiguration.loadConfiguration(sellAllFile); - conf.set("Items." + itemName + ".ITEM_ID", xMaterial.name()); - conf.set("Items." + itemName + ".ITEM_VALUE", value); - conf.set("Items." + itemName + ".IS_LORE_ALLOWED", pBlock.isLoreAllowed() ); + confSection.set("ITEM_ID", itemID ); + confSection.set("ITEM_VALUE", value); + confSection.set("IS_LORE_ALLOWED", pBlock.isLoreAllowed() ); if ( displayName != null ) { - conf.set("Items." + itemName + ".ITEM_DISPLAY_NAME", displayName ); + confSection.set("ITEM_DISPLAY_NAME", displayName ); } if (getBooleanValue("Options.Sell_Per_Block_Permission_Enabled")) { - String itemPerm = "Items." + itemName + ".ITEM_PERMISSION"; - conf.set( itemPerm, sellAllConfig.getString("Options.Sell_Per_Block_Permission") + xMaterial.name()); + confSection.set( "ITEM_PERMISSION", sellAllConfig.getString("Options.Sell_Per_Block_Permission") + itemID); } + conf.save(sellAllFile); - updateConfig(); + refreshClassVariablesFromConfig(); pBlockKey.setSalePrice( value ); - sellAllItems.put( pBlockKey.getBlockNameSearch(), pBlockKey ); + putSellallItem( pBlockKey ); +// sellAllItems.put( pBlockKey.getBlockNameSearch(), pBlockKey ); - } catch (IOException e) { + } + catch (IOException e) { + e.printStackTrace(); return false; } @@ -1787,7 +1855,9 @@ public boolean addSellAllBlock(XMaterial xMaterial, String displayName, double v */ public boolean addSellAllBlock( String itemNameSearch, double value, PrisonBlock pBlock ) { - PrisonBlock pBlockSellall = sellAllItems.get( itemNameSearch ); + PrisonBlock pBlockKey = getPrisonBlock( itemNameSearch ); + + PrisonBlock pBlockSellall = pBlockKey == null ? null : getSellallItem( pBlockKey ); // If that is an invalid PrisonBlock, then exit if ( pBlockSellall != null ) { @@ -1801,43 +1871,65 @@ public boolean addSellAllBlock( String itemNameSearch, double value, PrisonBlock try { - String itemName = itemNameSearch.toUpperCase(); - String displayName = pBlock.getDisplayName(); + if ( pBlockSellall == null ) { + + pBlockSellall = pBlock.clone(); + } + +// String itemName = itemNameSearch.toUpperCase(); + String displayName = pBlockSellall.getDisplayName(); File sellAllFile = new File(SpigotPrison.getInstance().getDataFolder() + "/SellAllConfig.yml"); FileConfiguration conf = YamlConfiguration.loadConfiguration(sellAllFile); - conf.set("Items." + itemName + ".ITEM_ID", itemNameSearch ); - conf.set("Items." + itemName + ".ITEM_VALUE", value); - conf.set("Items." + itemName + ".IS_LORE_ALLOWED", pBlock.isLoreAllowed() ); + String itemName = pBlockSellall.getBlockNameSearch().toUpperCase(); + String confKey = "Items." + itemName; + + conf.set(confKey + ".ITEM_ID", pBlockSellall.getBlockNameSearch() ); + conf.set(confKey + ".ITEM_VALUE", value); + conf.set(confKey + ".IS_LORE_ALLOWED", pBlockSellall.isLoreAllowed() ); if ( displayName != null ) { - conf.set("Items." + itemName + ".ITEM_DISPLAY_NAME", displayName ); + conf.set(confKey + ".ITEM_DISPLAY_NAME", displayName ); } if (getBooleanValue("Options.Sell_Per_Block_Permission_Enabled")) { - String itemPerm = "Items." + itemName + ".ITEM_PERMISSION"; - conf.set( itemPerm, sellAllConfig.getString("Options.Sell_Per_Block_Permission") + itemNameSearch ); + conf.set(confKey + ".ITEM_PERMISSION", sellAllConfig.getString("Options.Sell_Per_Block_Permission") + itemNameSearch ); } + conf.save(sellAllFile); - updateConfig(); + refreshClassVariablesFromConfig(); - pBlock.setSalePrice( value ); + pBlockSellall.setSalePrice( value ); - PrisonBlock pBlockKey = Prison.get().getPlatform().getPrisonBlock( itemNameSearch ); + + // NOTE: If PrisonBlock Key was null, then that means that prison does not have this setup as a + // valid block, so we must create a new prison block and add it. +// PrisonBlock pBlockKey = Prison.get().getPlatform().getPrisonBlock( itemNameSearch ); if ( pBlockKey == null ) { List pbList = new ArrayList<>(); - pbList.add( pBlock ); +// pBlockKey = pBlockSellall.clone(); + + pbList.add( pBlockSellall.clone() ); Prison.get().getPlatform().getPrisonBlockTypes().addBlockTypes( pbList ); } - sellAllItems.put( itemNameSearch, pBlock ); + putSellallItem( pBlockSellall ); +// sellAllItems.put( itemNameSearch, pBlock ); + + } + catch (IOException e) { + + String msg = String.format( + "SellAllUtil.addSellAllBlock: Failed to add a new block to SellAll. " + + "itemSearch: [%s] value: %s PrisonBlock: %s [%s]", + itemNameSearch, Prison.get().getDecimalFormatDouble().format( value ), + pBlock.getBlockNameSearch(), e.getMessage() ); + Output.get().logWarn( msg ); - } catch (IOException e) { - e.printStackTrace(); return false; } @@ -1867,6 +1959,7 @@ public boolean addSellAllBlock( String itemNameSearch, double value, PrisonBlock public boolean addSellallRankMultiplier(String rankName, double multiplier){ return addSellallRankMultiplier(rankName, multiplier, false); } + /** * Add Multiplier to SellAll depending on the Rank (Rank from any ladder). * @@ -1878,7 +1971,7 @@ public boolean addSellallRankMultiplier(String rankName, double multiplier){ * * @return boolean. * */ - public boolean addSellallRankMultiplier(String rankName, double multiplier, boolean applyToHigherRanks){ + public boolean addSellallRankMultiplier(String rankName, double multiplier, boolean applyToHigherRanks) { PrisonRanks rankPlugin = (PrisonRanks) (Prison.get().getModuleManager() == null ? null : Prison.get().getModuleManager().getModule(PrisonRanks.MODULE_NAME) ); @@ -1886,12 +1979,6 @@ public boolean addSellallRankMultiplier(String rankName, double multiplier, bool return false; } - -// boolean isPrestigeLadder = rankPlugin.getLadderManager().getLadder("prestiges") != null; -// if (!isPrestigeLadder) { -// return false; -// } - Rank rank = rankPlugin.getRankManager().getRank(rankName); if ( rank == null ) { @@ -1899,15 +1986,6 @@ public boolean addSellallRankMultiplier(String rankName, double multiplier, bool 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) { -// return false; -// } try { File sellAllFile = new File(SpigotPrison.getInstance().getDataFolder() + "/SellAllConfig.yml"); @@ -1928,12 +2006,20 @@ public boolean addSellallRankMultiplier(String rankName, double multiplier, bool conf.save(sellAllFile); } catch (IOException e) { - e.printStackTrace(); + + String msg = String.format( + "SellAllUtil.addSellAllMultiplier: Failed to add a new rank multiplier to SellAll. " + + "rankName: [%s] multiplier: %s applyToHigherRanks: %s [%s]", + rankName, Prison.get().getDecimalFormatDouble().format( multiplier ), + Boolean.toString( applyToHigherRanks ), + e.getMessage() ); + Output.get().logWarn( msg ); + return false; } sellAllPrestigeMultipliers.put( rank.getName(), multiplier); - updateConfig(); + refreshClassVariablesFromConfig(); return true; } @@ -1973,7 +2059,8 @@ public boolean addItemTrigger(XMaterial xMaterial){ return false; } sellAllItemTriggers.add(xMaterial); - updateConfig(); + + refreshClassVariablesFromConfig(); return true; } @@ -2148,65 +2235,146 @@ public boolean editPrice(XMaterial xMaterial, double value) { return editPrice( xMaterial, null, value ); } public boolean editPrice(XMaterial xMaterial, String displayName, double value) { + + return editPrice( xMaterial.name(), displayName, value ); - PrisonBlock pBlockKey = Prison.get().getPlatform().getPrisonBlock( xMaterial.name() ); - String key = pBlockKey.getBlockNameSearch(); +// PrisonBlock pBlockKey = Prison.get().getPlatform().getPrisonBlock( xMaterial.name() ); +// String key = pBlockKey.getBlockNameSearch(); +// +// 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 ( 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); +// +// String itemName = key.toUpperCase(); +// conf.set("Items." + itemName + ".ITEM_ID", key ); +// conf.set("Items." + itemName + ".ITEM_VALUE", value); +// conf.set("Items." + itemName + ".IS_LORE_ALLOWED", pBlock.isLoreAllowed() ); +// +// if ( displayName != null ) { +// conf.set("Items." + itemName + ".ITEM_DISPLAY_NAME", value); +// } +// else { +// //conf.set("Items." + itemName + ".ITEM_DISPLAY_NAME", null); +// } +// +// +// if ( pBlock.getPurchasePrice() != null ) { +// +// conf.set("Items." + itemName + ".PURCHASE_PRICE", pBlock.getPurchasePrice().doubleValue() ); +// } +// +// if (getBooleanValue("Options.Sell_Per_Block_Permission_Enabled")) { +// conf.set("Items." + itemName + ".ITEM_PERMISSION", sellAllConfig.getString("Options.Sell_Per_Block_Permission") + itemName ); +// } +// conf.save(sellAllFile); +// +// // Update only if successful +// refreshClassVariablesFromConfig(); +// } catch (IOException e) { +// e.printStackTrace(); +// return false; +// } +// +// // pBlock is still in the sellAllItems collection so no need to readd it +//// sellAllBlocks.put(xMaterial, value); +// +// return true; + } + + public boolean editPrice( String itemID, String displayName, double value) { - PrisonBlock pBlock = sellAllItems.get( key ); + PrisonBlock pBlockKey = getPrisonBlock( itemID ); + PrisonBlock pBlock = getSellallItem( pBlockKey ); + +// PrisonBlock pBlockKey = Prison.get().getPlatform().getPrisonBlock( itemID ); +// String key = pBlockKey.getBlockNameSearch(); +// +// 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 ( 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); - - String itemName = key.toUpperCase(); - conf.set("Items." + itemName + ".ITEM_ID", key ); - conf.set("Items." + itemName + ".ITEM_VALUE", value); - conf.set("Items." + itemName + ".IS_LORE_ALLOWED", pBlock.isLoreAllowed() ); - - if ( displayName != null ) { - conf.set("Items." + itemName + ".ITEM_DISPLAY_NAME", value); - } - else { - //conf.set("Items." + itemName + ".ITEM_DISPLAY_NAME", null); - } - - - if ( pBlock.getPurchasePrice() != null ) { - - conf.set("Items." + itemName + ".PURCHASE_PRICE", pBlock.getPurchasePrice().doubleValue() ); - } - - if (getBooleanValue("Options.Sell_Per_Block_Permission_Enabled")) { - 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; - } - - // pBlock is still in the sellAllItems collection so no need to readd it + 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); + + String itemName = pBlockKey.getBlockNameSearch().toUpperCase(); + String confKey = "Items." + itemName; + + ConfigurationSection confSection = conf.getConfigurationSection( confKey ); + + + confSection.set("ITEM_ID", pBlockKey.getBlockNameSearch() ); + confSection.set("ITEM_VALUE", value); + confSection.set("IS_LORE_ALLOWED", pBlock.isLoreAllowed() ); + + if ( displayName != null && displayName.trim().length() > 0 ) { + confSection.set("ITEM_DISPLAY_NAME", displayName.trim() ); + } + else { + //confSection.set("ITEM_DISPLAY_NAME", null); + } + + + if ( pBlock.getPurchasePrice() != null ) { + + confSection.set("PURCHASE_PRICE", pBlock.getPurchasePrice().doubleValue() ); + } + + if (getBooleanValue("Options.Sell_Per_Block_Permission_Enabled")) { + confSection.set("ITEM_PERMISSION", sellAllConfig.getString("Options.Sell_Per_Block_Permission") + itemName ); + } + conf.save(sellAllFile); + + // Update only if successful + refreshClassVariablesFromConfig(); + } + catch (IOException e) { + + String msg = String.format( + "SellAllUtil.editPrice: Failed to edit an item price. " + + "itemID: [%s] DisplayName: %s&r value: %s [%s]", + itemID, (displayName == null ? "" : displayName ), + Prison.get().getDecimalFormatDouble().format( value ), + e.getMessage() ); + Output.get().logWarn( msg ); + + return false; + } + + // pBlock is still in the sellAllItems collection so no need to readd it // sellAllBlocks.put(xMaterial, value); - - return true; + + return true; } @@ -2218,10 +2386,14 @@ public boolean editAllowLore( PrisonBlock pBlock, boolean value) { // PrisonBlock pBlock = sellAllItems.get( key ); + + // Use the block that is stored in sellall: + pBlock = getSellallItem( pBlock ); + // Do not allow an edit price if the material does not exist, or if the value has not changed: - if ( sellAllItems.get(pBlock.getBlockNameSearch() ) == null ){ + if ( pBlock == null ) { - Output.get().logDebug( "sellall edit: item does not exist in shop so it cannot be edited (%s)", pBlock.getBlockName() ); + Output.get().logDebug( "sellall edit: item does not exist in shop so it cannot be edited (%s)", pBlock.getBlockNameSearch() ); return false; } if ( pBlock.isLoreAllowed() == value ){ @@ -2243,9 +2415,18 @@ public boolean editAllowLore( PrisonBlock pBlock, boolean value) { conf.save(sellAllFile); // Update only if successful - updateConfig(); - } catch (IOException e) { - e.printStackTrace(); + refreshClassVariablesFromConfig(); + } + catch (IOException e) { + + String msg = String.format( + "SellAllUtil.editAllowLore: Failed to edit the allow lore setting. " + + "itemID: [%s] allow Lore?: %s [%s]", + pBlock.getBlockNameSearch(), + Boolean.toString( value ), + e.getMessage() ); + Output.get().logWarn( msg ); + return false; } @@ -2289,6 +2470,11 @@ public boolean editPrestigeMultiplier(String prestigeName, double multiplier) { return addSellallRankMultiplier(prestigeName, multiplier); } +// public boolean removeSellAllBlock(XMaterial xMaterial){ +// +// return removeSellAllBlock( xMaterial.name() ); +// } + /** * Remove block by XMaterial name. * @@ -2298,30 +2484,34 @@ public boolean editPrestigeMultiplier(String prestigeName, double multiplier) { * * @return boolean. * */ - public boolean removeSellAllBlock(XMaterial xMaterial){ + public boolean removeSellAllBlock( String itemID ) { + + PrisonBlock pBlockKey = getSellallItem( getPrisonBlock( itemID )); + +// PrisonBlock pBlockKey = Prison.get().getPlatform().getPrisonBlock( itemID ); +// String key = pBlockKey.getBlockNameSearch(); +// +// PrisonBlock pBlock = sellAllItems.get( key ); - PrisonBlock pBlockKey = Prison.get().getPlatform().getPrisonBlock( xMaterial.name() ); - String key = pBlockKey.getBlockNameSearch(); - - PrisonBlock pBlock = sellAllItems.get( key ); - if ( pBlock == null ){ + if ( pBlockKey == null ){ return false; } try { File sellAllFile = new File(SpigotPrison.getInstance().getDataFolder() + "/SellAllConfig.yml"); FileConfiguration conf = YamlConfiguration.loadConfiguration(sellAllFile); - conf.set("Items." + pBlock.getBlockName().toUpperCase(), null); + conf.set("Items." + pBlockKey.getBlockName().toUpperCase(), null); conf.save(sellAllFile); - updateConfig(); - } catch (IOException e) { + refreshClassVariablesFromConfig(); + } + catch (IOException e) { e.printStackTrace(); return false; } - sellAllItems.remove( key ); + getSellAllItems().remove( pBlockKey.getBlockNameSearch() ); // sellAllBlocks.remove(xMaterial); return true; } @@ -2362,11 +2552,12 @@ public boolean removeSellallRankMultiplier(String rankName){ FileConfiguration conf = YamlConfiguration.loadConfiguration(sellAllFile); conf.set("Multiplier." + rankName, null); conf.save(sellAllFile); - } catch (IOException e) { + } + catch (IOException e) { return false; } sellAllPrestigeMultipliers.remove(rankName); - updateConfig(); + refreshClassVariablesFromConfig(); return true; } @@ -2391,12 +2582,13 @@ public boolean removeItemTrigger(XMaterial xMaterial){ conf.set("ShiftAndRightClickSellAll.Items." + xMaterial.name() + ".ITEM_ID", null); conf.set("ShiftAndRightClickSellAll.Items." + xMaterial.name(), null); conf.save(sellAllFile); - } catch (IOException e) { + } + catch (IOException e) { e.printStackTrace(); return true; } sellAllItemTriggers.remove(xMaterial); - updateConfig(); + refreshClassVariablesFromConfig(); return true; } @@ -2723,11 +2915,22 @@ public boolean setItemTrigger(Boolean isEnabled){ FileConfiguration conf = YamlConfiguration.loadConfiguration(sellAllFile); conf.set("Options.ShiftAndRightClickSellAll.Enabled", isEnabled); conf.save(sellAllFile); - } catch (IOException e) { + } + catch (IOException e) { + + String msg = String.format( + "SellAllUtil.setItemTrigger: Failed to set the config setting " + + "'Options.ShiftAndRightClickSellAll.Enabled' to a value of %s " + + "since there was a problem trying to save the SellAllConfig.yml file. " + + "[%s]", + Boolean.toString( isEnabled ), + e.getMessage() ); + Output.get().logWarn( msg ); + return true; } isSellAllItemTriggerEnabled = isEnabled; - updateConfig(); + refreshClassVariablesFromConfig(); return true; } @@ -2741,7 +2944,7 @@ public boolean setItemTrigger(Boolean isEnabled){ * @return boolean. * */ public boolean setAutoSell(Boolean isEnabled){ - if (isAutoSellEnabled == isEnabled){ + if ( isAutoSellEnabled() == isEnabled ) { return false; } @@ -2750,13 +2953,22 @@ public boolean setAutoSell(Boolean isEnabled){ FileConfiguration conf = YamlConfiguration.loadConfiguration(sellAllFile); conf.set("Options.Full_Inv_AutoSell", isEnabled); conf.save(sellAllFile); - } catch (IOException e) { - e.printStackTrace(); - return false; + } + catch (IOException e) { + + String msg = String.format( + "SellAllUtil.setAutoSell: Failed to set 'Options.Full_Inv_AutoSell' to a value of %s since " + + "there was a problem trying to save the SellAllConfig.yml file. " + + "[%s]", + Boolean.toString( isAutoSellEnabled() ), + e.getMessage() ); + Output.get().logWarn( msg ); + + return false; } isAutoSellEnabled = isEnabled; - updateConfig(); + refreshClassVariablesFromConfig(); return true; } @@ -2771,9 +2983,9 @@ public boolean setAutoSell(Boolean isEnabled){ * @return boolean. * */ public boolean setAutoSellPlayer(Player p, boolean enable){ - if (!(isAutoSellEnabled || + if (!( isAutoSellEnabled() || AutoFeaturesWrapper.getInstance().isBoolean(AutoFeatures.isAutoSellPerBlockBreakEnabled)) || - !isAutoSellPerUserToggleable){ + !isAutoSellPerUserToggleable ) { return false; } @@ -2786,12 +2998,22 @@ public boolean setAutoSellPlayer(Player p, boolean enable){ FileConfiguration conf = YamlConfiguration.loadConfiguration(sellAllFile); conf.set("Users." + p.getUniqueId() + ".isEnabled", enable); conf.save(sellAllFile); - } catch (IOException e) { - e.printStackTrace(); + } + catch (IOException e) { + + String msg = String.format( + "SellAllUtil.setAutoSellPlayer: Failed to set user %s autoSell Per Bbock toggle to a value " + + "of %s since there was a problem trying to save the SellAllConfig.yml file. " + + "[%s]", + p.getName(), + Boolean.toString( enable ), + e.getMessage() ); + Output.get().logWarn( msg ); + return false; } - updateConfig(); + refreshClassVariablesFromConfig(); return true; } @@ -2819,7 +3041,7 @@ public boolean setAutoSellPerUserToggleable(boolean isEnabled){ return false; } isAutoSellPerUserToggleable = isEnabled; - updateConfig(); + refreshClassVariablesFromConfig(); return true; } @@ -2848,7 +3070,7 @@ public boolean setCurrency(String currency){ return false; } sellAllCurrency = currency; - updateConfig(); + refreshClassVariablesFromConfig(); return true; } @@ -2872,7 +3094,7 @@ public boolean setDelayEnable(boolean enabled){ return false; } isSellAllDelayEnabled = enabled; - updateConfig(); + refreshClassVariablesFromConfig(); return true; } @@ -2896,7 +3118,7 @@ public boolean setDelay(int delay){ return false; } defaultSellAllDelay = delay; - updateConfig(); + refreshClassVariablesFromConfig(); return true; } @@ -2985,7 +3207,7 @@ public boolean sellAllSell(Player p, return false; } - if (sellAllItems.isEmpty()){ + if ( getSellAllItems().isEmpty() ) { if (!completelySilent){ sellallShopIsEmptyMsg( new SpigotCommandSender(p) ); @@ -3264,7 +3486,7 @@ public ArrayList sellAllSell(Player p, ArrayList itemStack return itemStacks; } - if (sellAllItems.isEmpty()){ + if ( getSellAllItems().isEmpty()){ if (!completelySilent){ sellallShopIsEmptyMsg( new SpigotCommandSender(p) ); From 77b6a69e8dd9e648295fe56cdc1fc90233cb1b79 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 20 Jan 2025 11:44:48 -0500 Subject: [PATCH 233/323] Startup block checks: Had to make changes to the handling of XMaterial since the latest versions are more brittle since they tend to be conflictive with itself. There are now a few block types that actually cause problems if used or accessed. It appears as if 1.21.4 made major changes in how some blocks are identified, and XMaterial has not yet fully caught up with those changes? This change captures exceptions caused byXMaterial, when in the past, it would only return a null value instead of throwing an exception. --- docs/changelog_v3.3.x.md | 6 ++++++ .../tech/mcprison/prison/spigot/SpigotUtil.java | 14 +++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 5c7b0774b..63aa256e1 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.19e 2025-01-20 +* **Startup block checks: Had to make changes to the handling of XMaterial since the latest versions are more brittle since they tend to be conflictive with itself.** +There are now a few block types that actually cause problems if used or accessed. +It appears as if 1.21.4 made major changes in how some blocks are identified, and XMaterial has not yet fully caught up with those changes? +This change captures exceptions caused byXMaterial, when in the past, it would only return a null value instead of throwing an exception. + + * **Sellall: Major changes to better support custom blocks. Not perfect overall, since some aspects are not fully handled, such as enchantments or filters on specific nbt values.** These changes fixes most of the issues with identifying custom blocks and allows them to be sold. This also fixes a lot of the internals on sellall, which is forcing a lot of movement away from XMaterial and relying more on PrisonBlocks. Added better error messages to many functions, instead of just a generic stack trace. Need to do many more. 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 a01f6e656..668295a2d 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 @@ -939,8 +939,20 @@ public static void testAllPrisonBlockTypes() { for ( Material spigotMaterial : Material.values() ) { + XMaterial xMat = null; + + try { + xMat = XMaterial.matchXMaterial( spigotMaterial ); + } + catch (Exception e) { + // Ignore since this version of spigot/paper does not support this block type + // within XMaterial. + } + if ( spigotMaterial.isBlock() && - XMaterial.matchXMaterial( spigotMaterial ) == null + + xMat == null +// XMaterial.matchXMaterial( spigotMaterial ) == null // BlockType.getBlock( spigotMaterial.name() ) == null ) { From 591102ab34c02b238f160dbcbd23730613576e2f Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 20 Jan 2025 20:51:38 -0500 Subject: [PATCH 234/323] Sellall: Worked on more enhancements and fixed issue with selling a custom block. The bukkit function to remove item stacks was not working correctly for our needs since it was not able to match the blocks due to other unknown issues that may be related to the enchantments and lore may not have been a complete match. Now the remove will work based upon the block/item's search name, which will align with what is setup in sellall. Keep in mind, that sellall currently ignores enchantments and lore detail (either on or off, but no filters). --- .../mcprison/prison/internal/ItemStack.java | 3 +- .../prison/internal/block/PrisonBlock.java | 8 ++- .../prison/spigot/block/SpigotBlock.java | 20 ++++++- .../spigot/inventory/SpigotInventory.java | 57 +++++++++++++++++-- .../prison/spigot/sellall/SellAllData.java | 2 +- 5 files changed, 79 insertions(+), 11 deletions(-) diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/ItemStack.java b/prison-core/src/main/java/tech/mcprison/prison/internal/ItemStack.java index 69b47a971..58108b602 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/ItemStack.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/ItemStack.java @@ -131,7 +131,8 @@ public void setAmount( int amount ) { public PrisonBlock getMaterial() { if ( getDisplayName() != null && getDisplayName().trim().length() > 0 && - material.getDisplayName() == null || material.getDisplayName().trim().length() == 0 ) { + material.getDisplayName() == null || + material.getDisplayName() != null && material.getDisplayName().trim().length() == 0 ) { material.setDisplayName( getDisplayName() ); } 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 e0ee6ed29..b66242977 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 @@ -168,9 +168,11 @@ public String toString() { StringBuilder sb = new StringBuilder(); - sb.append( getBlockType().name() ) - .append( ":" ) - .append( getBlockName() ); + sb.append( getBlockNameSearch() ); + +// sb.append( getBlockType().name() ) +// .append( ":" ) +// .append( getBlockName() ); if ( getChance() > 0 ) { sb.append( " " ) diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/SpigotBlock.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/SpigotBlock.java index 0ace4bf8c..eca1acb35 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/SpigotBlock.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/SpigotBlock.java @@ -126,12 +126,30 @@ else if ( xMat != null ) { public String toString() { StringBuilder sb = new StringBuilder(); - sb.append( getPrisonBlock().getBlockName() ).append( " " ) + sb.append( getPrisonBlock().getBlockNameSearch() ) + .append( " " ) .append( getLocation().toWorldCoordinates() ); + if ( getChance() > 0 ) { + sb.append( " chance:" ) + .append( Double.toString( getChance()) ); + } + + if ( getSalePrice() > 0 ) { + sb.append( " sell:" ) + .append( Double.toString( getSalePrice()) ); + } + + if ( getPurchasePrice() > 0 ) { + sb.append( " purch:" ) + .append( Double.toString( getPurchasePrice()) ); + } + return sb.toString(); } + + // public String getBlockName() { // return super.getBlockName(); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/inventory/SpigotInventory.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/inventory/SpigotInventory.java index e8c71c822..1a38070e9 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/inventory/SpigotInventory.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/inventory/SpigotInventory.java @@ -37,6 +37,7 @@ import tech.mcprison.prison.internal.inventory.InventoryHolder; import tech.mcprison.prison.internal.inventory.InventoryType; import tech.mcprison.prison.spigot.SpigotUtil; +import tech.mcprison.prison.spigot.block.SpigotItemStack; import tech.mcprison.prison.spigot.game.SpigotPlayer; /** @@ -207,11 +208,57 @@ public void addItem(ItemStack... itemStack) { @Override public void removeItem(ItemStack... itemStack) { - ArrayList stacks = new ArrayList<>(); - for (ItemStack stack : itemStack) { - stacks.add(SpigotUtil.prisonItemStackToBukkit(stack)); - } - wrapper.removeItem(stacks.toArray(new org.bukkit.inventory.ItemStack[]{})); + + int size = wrapper.getSize(); + + // This may be sub optimal, but when dealing with modified items, such as with + // custom names, prison cannot faithfully reproduce them such that the bukkit's + // ItemStack.removeItem() will work correctly. We cannot properly reproduce + // all enchantments, NBTs, and other alterations. So much match on individual + // field values such as types and display names. + for (ItemStack stack : itemStack) { + + String itemName = stack.getMaterial().getBlockNameSearch(); + int amt = stack.getAmount(); + + for ( int i = 0; i < size && amt > 0; i++ ) { + org.bukkit.inventory.ItemStack item = wrapper.getItem(i); + + if ( item != null ) { + + SpigotItemStack sItemStack = new SpigotItemStack( item ); + String sItemName = sItemStack.getMaterial().getBlockNameSearch(); + + if ( itemName.equalsIgnoreCase( sItemName ) ) { + + // We have a match on item's blockNameSearch, so remove the requested + // quantity. Set the current bukkit ItemStack's amount to what we + // need to remove, then use the bukkit item stack to remove it. + // Exit out of the bukkit for loop by seeing amt to zero. + + // If the amount is more than what can be removed in one item stack, + // bukkit will remove the total requested amount from multiple item stacks, + // so we only need to Process one item stack. + item.setAmount(amt); + + wrapper.remove( item ); + + amt = 0; + + } + } + } + } + + + +// ArrayList stacks = new ArrayList<>(); +// +// for (ItemStack stack : itemStack) { +// stacks.add(SpigotUtil.prisonItemStackToBukkit(stack)); +// } +// +// wrapper.removeItem(stacks.toArray(new org.bukkit.inventory.ItemStack[]{})); } @Override 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 9d7555fba..7f00c1fb6 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 @@ -37,7 +37,7 @@ public String toString() { StringBuilder sb = new StringBuilder(); DecimalFormat dFmt = new DecimalFormat( "#,##0.00" ); - sb.append( getPrisonBlock().getBlockName() ) + sb.append( getPrisonBlock().getBlockNameSearch() ) .append( ":" ) .append( getQuantity() ) .append( ":" ) From 37e6fa02a354007829d0dcb642d75a851329a560 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 1 Feb 2025 13:19:46 -0500 Subject: [PATCH 235/323] Rankup: Fixed a problem with rankup commands not using the correct player objects. Simplified how some of the player objects are used to eliminate this issue. --- docs/changelog_v3.3.x.md | 6 +- .../prison/ranks/commands/RankUpCommand.java | 60 +++++++++++-------- 2 files changed, 40 insertions(+), 26 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 63aa256e1..9dd48470d 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.19e 2025-01-20 +# 3.3.0-alpha.19e 2025-02-01 + + +* **Rankup: Fixed a problem with rankup commands not using the correct player objects.** +Simplified how some of the player objects are used to eliminate this issue. * **Startup block checks: Had to make changes to the handling of XMaterial since the latest versions are more brittle since they tend to be conflictive with itself.** 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 c1b122ef3..1c4f52310 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 @@ -119,18 +119,20 @@ public void rankUpMax(CommandSender sender, } - Player player = getPlayerByName( sender.getName()); + RankPlayer rPlayer = sender.getRankPlayer(); +// Player player = getPlayerByName( sender.getName()); // Player player = getPlayer( sender, null ); // submit cmdTasks if ( cmdTasks.size() > 0 ) { - submitCmdTasks( player, cmdTasks ); + submitCmdTasks( rPlayer, cmdTasks ); } if ( sbRanks.length() > 0 ) { - ranksRankupMaxSuccessMsg( sender, sbRanks, player.getRankPlayer() ); + ranksRankupMaxSuccessMsg( sender, sbRanks, rPlayer ); +// ranksRankupMaxSuccessMsg( sender, sbRanks, player.getRankPlayer() ); } // If the ran rankupmax for prestiges, and the last prestige was successful, then @@ -140,12 +142,14 @@ public void rankUpMax(CommandSender sender, } } else { - Player player = getPlayerByName( sender.getName() ); + RankPlayer rPlayer = sender.getRankPlayer(); +// Player player = getPlayerByName( sender.getName() ); // Player player = getPlayer( sender, null ); Output.get().logDebug( DebugTarget.rankup, "Rankup: Failed: cmd '/rankupmax %s' Does not have the permission ranks.rankupmax.%s", ladder, ladder ); - rankupMaxNoPermissionMsg( sender, "ranks.rankupmax." + ladder, player.getRankPlayer() ); + rankupMaxNoPermissionMsg( sender, "ranks.rankupmax." + ladder, rPlayer ); +// rankupMaxNoPermissionMsg( sender, "ranks.rankupmax." + ladder, player.getRankPlayer() ); } } @@ -196,7 +200,9 @@ else if ( !isPlayer && playerName.length() == 0 ) { - RankPlayer rPlayer = getRankPlayer(sender, null, playerName); + RankPlayer rPlayer = isPlayer ? + sender.getRankPlayer() : + getRankPlayer(sender, null, playerName); if ( rPlayer == null ) { rankupInvalidPlayerNameMsg( sender, playerName ); @@ -379,7 +385,9 @@ public void prestigeCmd(CommandSender sender, return; } - RankPlayer rPlayer = getRankPlayer(sender, null, playerName); + RankPlayer rPlayer = isPlayer ? + sender.getRankPlayer() : + getRankPlayer(sender, null, playerName); if ( rPlayer == null ) { rankupInvalidPlayerNameMsg( sender, playerName ); @@ -544,7 +552,7 @@ public void prestigeCmd(CommandSender sender, // } private boolean rankUpPrivate(CommandSender sender, - Player player, + RankPlayer rankPlayer, // String playerName, String ladder, RankupModes mode, String permission, @@ -613,11 +621,11 @@ private boolean rankUpPrivate(CommandSender sender, //UUID playerUuid = player.getUUID(); - RankPlayer rankPlayer = - player == null ? - sender.getRankPlayer() : - player instanceof RankPlayer ? (RankPlayer) player : - player.getRankPlayer(); +// RankPlayer rankPlayer = +// player == null ? +// sender.getRankPlayer() : +// player instanceof RankPlayer ? (RankPlayer) player : +// player.getRankPlayer(); ladder = confirmLadder( sender, ladder, rankPlayer ); @@ -777,11 +785,13 @@ private boolean rankUpPrivate(CommandSender sender, if (rankPlayer != null ) { // Performs the actual rankup here: - RankupResults results = new RankUtil().rankupPlayer(player, rankPlayer, ladder, + RankupResults results = new RankUtil().rankupPlayer(rankPlayer, rankPlayer, ladder, sender.getName(), cmdTasks ); +// RankupResults results = new RankUtil().rankupPlayer(player, rankPlayer, ladder, +// sender.getName(), cmdTasks ); - processResults( sender, player.getName(), results, null, ladder, currency, sbRanks ); + processResults( sender, rankPlayer.getName(), results, null, ladder, currency, sbRanks ); // If the last rankup attempt was successful and they are trying to rankup as many times as possible: // Note they used to restrict rankupmax from working on prestige ladder... @@ -1128,6 +1138,8 @@ public void setRank(CommandSender sender, if ( "*all*".equalsIgnoreCase( playerName )) { PlayerManager pm = PrisonRanks.getInstance().getPlayerManager(); + RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); + for ( RankPlayer player : pm.getPlayers() ) { // Player targetPlayer = getPlayerByName( player.getName() ); @@ -1135,8 +1147,6 @@ public void setRank(CommandSender sender, boolean isSameRank = rank.equalsIgnoreCase("*same*"); - RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); - PlayerRank pRank = rankPlayerFactory.getRank( player, ladder ); String rankNameCurrent = isSameRank && pRank != null && @@ -1158,7 +1168,7 @@ public void setRank(CommandSender sender, return; } - setPlayerRank( player, rank, ladder, sender ); + setPlayerRank( player.getRankPlayer(), rank, ladder, sender ); } } @@ -1245,12 +1255,12 @@ private void setPlayerRank( RankPlayer rankPlayer, RankLadder ladder, Rank pRank } - private void setPlayerRank( Player player, String rank, String ladderName, CommandSender sender ) { - UUID playerUuid = player.getUUID(); + private void setPlayerRank( RankPlayer rankPlayer, String rank, String ladderName, CommandSender sender ) { +// UUID playerUuid = player.getUUID(); Output.get().logDebug( DebugTarget.rankup, "Rankup: setPlayerRank: "); - RankPlayer rankPlayer = getRankPlayer( sender, playerUuid, player.getName() ); +// RankPlayer rankPlayer = getRankPlayer( sender, playerUuid, player.getName() ); ladderName = confirmLadder( sender, ladderName, rankPlayer ); @@ -1265,13 +1275,13 @@ private void setPlayerRank( Player player, String rank, String ladderName, Comma List cmdTasks = new ArrayList<>(); - RankupResults results = new RankUtil().setRank(player, rankPlayer, ladderName, rank, - player.getName(), sender.getName(), cmdTasks ); + RankupResults results = new RankUtil().setRank(rankPlayer, rankPlayer, ladderName, rank, + rankPlayer.getName(), sender.getName(), cmdTasks ); // submit cmdTasks - submitCmdTasks( player, cmdTasks ); + submitCmdTasks( rankPlayer, cmdTasks ); - processResults( sender, player.getName(), results, rank, ladderName, currency, null ); + processResults( sender, rankPlayer.getName(), results, rank, ladderName, currency, null ); } } From ad200ebe32a0d8ed41775e6132cfcc7cd568a4d5 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 7 Feb 2025 10:29:27 -0500 Subject: [PATCH 236/323] NBT & MineBombs: addresses an issue with NBT-Lib caused stack traces when used on a newer platform that the NBT lib has not been updated for. This also fixes the issue (my fault) where the exception that was being thrown was NoClassDefFoundError extends from Error, not Exception, which is what the try-catch was trying to intercept. This now will prevent the exception and it will fail silently. --- docs/changelog_v3.3.x.md | 8 +++++++- .../tech/mcprison/prison/spigot/nbt/PrisonNBTUtil.java | 2 +- .../mcprison/prison/spigot/utils/PrisonBombListener.java | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 9dd48470d..1d1f45860 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.19e 2025-02-01 +# 3.3.0-alpha.19e 2025-02-07 + + + +* **NBT & MineBombs: addresses an issue with NBT-Lib caused stack traces when used on a newer platform that the NBT lib has not been updated for.** +This also fixes the issue (my fault) where the exception that was being thrown was NoClassDefFoundError extends from Error, not Exception, which is what the try-catch was trying to intercept. +This now will prevent the exception and it will fail silently. * **Rankup: Fixed a problem with rankup commands not using the correct player objects.** 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 097d23303..02f14af1e 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 @@ -70,7 +70,7 @@ public static String getNBTString( ItemStack bukkitStack, String key ) { results = NBT.get(bukkitStack, gsFnc ); // results = NBT.get(bukkitStack, nbt -> nbt.getString(key)); } - catch (Exception e) { + catch (NoClassDefFoundError | Exception e) { // ignore exception... these are very common if there are no NBTs on the ItemStack // Output.get().logInfo( 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 8ce5ae8a5..65b367044 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 @@ -435,7 +435,7 @@ private String checkMineBombItemStack( ItemStack iStack ) { // // } // } } - catch (Exception e) { + catch (Exception | Error e) { // Ignore... not a mine bomb. } From 0f9887915389266e7388f6d4669c9cebd4285a7a Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 7 Feb 2025 11:16:27 -0500 Subject: [PATCH 237/323] Rankup: Found that a parameter that should not be null was being passed null in a few places. This was a problem in a few places for 'rankupmax'. The RankPlayer object that was expected was available so it was a simple fix. --- docs/changelog_v3.3.x.md | 4 ++++ .../prison/ranks/commands/RankUpCommand.java | 12 +++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 1d1f45860..9e33cd197 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.19e 2025-02-07 +* **Rankup: Found that a parameter that should not be null was being passed null in a few places.** +This was a problem in a few places for 'rankupmax'. +The RankPlayer object that was expected was available so it was a simple fix. + * **NBT & MineBombs: addresses an issue with NBT-Lib caused stack traces when used on a newer platform that the NBT lib has not been updated for.** This also fixes the issue (my fault) where the exception that was being thrown was NoClassDefFoundError extends from Error, not Exception, which is what the try-catch was trying to intercept. 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 1c4f52310..8c4896ed0 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 @@ -85,6 +85,8 @@ public void rankUpMax(CommandSender sender, boolean isLadderPrestiges = ladder.equalsIgnoreCase(LadderManager.LADDER_PRESTIGES); // boolean isLadderDefault = ladder.equalsIgnoreCase(LadderManager.LADDER_DEFAULT); + RankPlayer rPlayer = sender.getRankPlayer(); + if ( (isPrestigesEnabled && isLadderPrestiges || !isLadderPrestiges ) && sender.hasPermission( permsLadder) @@ -104,22 +106,22 @@ public void rankUpMax(CommandSender sender, if ( !LadderManager.LADDER_PRESTIGES.equalsIgnoreCase( ladder ) && !LadderManager.LADDER_DEFAULT.equalsIgnoreCase( ladder )) { - success = rankUpPrivate(sender, null, ladder, mode, perms, cmdTasks, sbRanks ); + success = rankUpPrivate(sender, rPlayer, ladder, mode, perms, cmdTasks, sbRanks ); } else { // Run rankupmax on the default ladder only: - success = rankUpPrivate(sender, null, LadderManager.LADDER_DEFAULT, mode, perms, cmdTasks, sbRanks ); + success = rankUpPrivate(sender, rPlayer, LadderManager.LADDER_DEFAULT, mode, perms, cmdTasks, sbRanks ); // If they specified the prestiges ladder, then try to prestige that one rank: if ( success && LadderManager.LADDER_PRESTIGES.equalsIgnoreCase( ladder ) ) { - success = rankUpPrivate(sender, null, LadderManager.LADDER_PRESTIGES, RankupModes.ONE_RANK, perms, cmdTasks, sbRanks ); + success = rankUpPrivate(sender, rPlayer, LadderManager.LADDER_PRESTIGES, RankupModes.ONE_RANK, perms, cmdTasks, sbRanks ); } } - RankPlayer rPlayer = sender.getRankPlayer(); +// RankPlayer rPlayer = sender.getRankPlayer(); // Player player = getPlayerByName( sender.getName()); // Player player = getPlayer( sender, null ); @@ -142,7 +144,7 @@ public void rankUpMax(CommandSender sender, } } else { - RankPlayer rPlayer = sender.getRankPlayer(); +// RankPlayer rPlayer = sender.getRankPlayer(); // Player player = getPlayerByName( sender.getName() ); // Player player = getPlayer( sender, null ); Output.get().logDebug( DebugTarget.rankup, From c301fba07dfe0c1b6458e8fe8483e4b08131ea25 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 7 Feb 2025 11:19:21 -0500 Subject: [PATCH 238/323] Prison versions: Updated the internal references to java versions up to java 29. 25 is the highest official value, but extended it by four extra versions just in case this is not revised between now and then. --- docs/changelog_v3.3.x.md | 4 ++ .../prison/util/PrisonJarReporter.java | 39 +++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 9e33cd197..7a46c6376 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.19e 2025-02-07 +* **Prison versions: Updated the internal references to java versions up to java 29.** +25 is the highest official value, but extended it by four extra versions just in case this is not revised between now and then. + + * **Rankup: Found that a parameter that should not be null was being passed null in a few places.** This was a problem in a few places for 'rankupmax'. The RankPlayer object that was expected was available so it was a simple fix. diff --git a/prison-core/src/main/java/tech/mcprison/prison/util/PrisonJarReporter.java b/prison-core/src/main/java/tech/mcprison/prison/util/PrisonJarReporter.java index ba8047870..9f29a2ec6 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/util/PrisonJarReporter.java +++ b/prison-core/src/main/java/tech/mcprison/prison/util/PrisonJarReporter.java @@ -60,6 +60,14 @@ public enum JavaVersion { JavaSE_20("40"), JavaSE_21("41"), JavaSE_22("42"), + JavaSE_23("43"), + JavaSE_24("44"), + JavaSE_25("45"), + + JavaSE_26("46"), // Confirm with wiki above when it's defined. + JavaSE_27("47"), // Confirm with wiki above when it's defined. + JavaSE_28("48"), // Confirm with wiki above when it's defined. + JavaSE_29("49"), // Confirm with wiki above when it's defined. JavaSE_UnknownVersion("UnknownJavaVersion") ; @@ -96,6 +104,37 @@ public PrisonJarReporter() { this.jarsByPluginName = new TreeMap<>(); } + public List getBukkitVersion() { + List versionMajMin = new ArrayList<>(); + + String version = getBukkitVersionRaw(); + + String versionStr = version.substring( + version.indexOf( "(MC:" ) + 4, version.lastIndexOf( ")" ) ); + String[] vMN = versionStr.split( "\\." ); + + for ( int x = 0; x < vMN.length; x++ ) { + String ver = vMN[x]; + + try { + versionMajMin.add( + Integer.parseInt( ver.trim() ) ); + } + catch ( NumberFormatException e ) { + // ignore... just break out: + break; + } + } + + return versionMajMin; + } + + public String getBukkitVersionRaw() { + + return Prison.get().getMinecraftVersion(); +// return Bukkit.getVersion(); + } + public class JarFileData { private String pluginName; From ec6158f19decbbc572781d3664920d7040b726b8 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 7 Feb 2025 11:23:26 -0500 Subject: [PATCH 239/323] Prison Commands: Added a new prison command placeholder '{range: }` that can be inserted in commands used in ranks, mines, or block events. This inserts a random integer value in the specified range. This is good to provide some variation when issuing commands like give or other type of events. --- docs/changelog_v3.3.x.md | 5 ++ .../prison/tasks/PrisonCommandTaskData.java | 55 +++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 7a46c6376..28213faee 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.19e 2025-02-07 +* **Prison Commands: Added a new prison command placeholder '{range: }` that can be inserted in commands used in ranks, mines, or block events.** +This inserts a random integer value in the specified range. +This is good to provide some variation when issuing commands like give or other type of events. + + * **Prison versions: Updated the internal references to java versions up to java 29.** 25 is the highest official value, but extended it by four extra versions just in case this is not revised between now and then. diff --git a/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonCommandTaskData.java b/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonCommandTaskData.java index 44d7f0bff..f04308df9 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonCommandTaskData.java +++ b/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonCommandTaskData.java @@ -14,6 +14,8 @@ public class PrisonCommandTaskData { + private boolean fail = false; + private RankLadder ladder; private PlayerRank rankTarget; private PlayerRank rankOriginal; @@ -108,6 +110,10 @@ public enum CustomPlaceholders { "{syncPlayer} runs the command as the payer in a new sync task."), + range(CommandEnvironment.all_commands, + "{range: } inserts a randomly choosen number within the " + + "range specified, all inclusive."), + ifPerm(CommandEnvironment.all_commands, "{ifPerm:} Continues executing commands in the chain if " + "the player has the perm ''.", @@ -318,11 +324,60 @@ public PrisonCommandTaskData( String errorMessagePrefix, command = command.replace( "{syncPlayer}", "" ); } + if ( command.contains( "{range:") ) { + command = taskInsertRange( command ); + } + this.cmd = command; this.taskMode = taskMode; } + protected String taskInsertRange(String command) { + + int idx = command.indexOf("{range:"); + if ( idx != -1 ) { + + int idxEnd = command.indexOf("}", idx ); + if ( idxEnd != -1 ) { + try { + String oValue = command.substring( idx, idxEnd + 1); + String results = ""; + + String nValues = oValue.replace( "{range:", "").replace( "}", "" ).trim(); + String[] lowHigh = nValues.split( " " ); + + int low = Integer.parseInt( lowHigh[0] ); + int high = Integer.parseInt( lowHigh[1] ); + + if ( high < low ) { + int temp = low; + low = high; + high = temp; + } + + if ( low == high ) { + results = Integer.toString( low ); + } + else { + int range = high - low; + int rnd = ((int) Math.round(Math.random() * range)); + results = Integer.toString( low + rnd ); + } + + command = command.replace( oValue, results ); + } + catch (NumberFormatException e) { + // ignore: invalid numbers + } + + } + + } + + return command; + } + public String getDebugDetails() { StringBuilder sb = new StringBuilder(); From 183c230c976bd0beb10a1f6c9ebb43c90a4ac432 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 7 Feb 2025 11:25:48 -0500 Subject: [PATCH 240/323] Sellall: Removed use of ConfigurationSection since it works fine until a new value is being added. It was easier to roll back to how it was than to add a bunch of other code to add it if it does not exist. --- docs/changelog_v3.3.x.md | 4 +++ .../prison/spigot/sellall/SellAllUtil.java | 28 ++++++++----------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 28213faee..6d68bdf98 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.19e 2025-02-07 +* **Sellall: Removed use of ConfigurationSection since it works fine until a new value is being added.** +It was easier to roll back to how it was than to add a bunch of other code to add it if it does not exist. + + * **Prison Commands: Added a new prison command placeholder '{range: }` that can be inserted in commands used in ranks, mines, or block events.** This inserts a random integer value in the specified range. This is good to provide some variation when issuing commands like give or other type of events. 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 782985274..fe46356b4 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 @@ -12,7 +12,6 @@ import org.bukkit.Bukkit; import org.bukkit.Sound; import org.bukkit.configuration.Configuration; -import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; @@ -1801,22 +1800,19 @@ public boolean addSellAllBlock( String itemID, String displayName, double value) String itemName = pBlockKey.getBlockNameSearch().toUpperCase(); String confKey = "Items." + itemName; - - ConfigurationSection confSection = conf.getConfigurationSection( confKey ); - // String itemName = pBlockKey.getBlockName().toUpperCase(); // BUG!! - confSection.set("ITEM_ID", itemID ); - confSection.set("ITEM_VALUE", value); - confSection.set("IS_LORE_ALLOWED", pBlock.isLoreAllowed() ); + conf.set( confKey + ".ITEM_ID", itemID ); + conf.set( confKey + ".ITEM_VALUE", value); + conf.set( confKey + ".IS_LORE_ALLOWED", pBlock.isLoreAllowed() ); if ( displayName != null ) { - confSection.set("ITEM_DISPLAY_NAME", displayName ); + conf.set( confKey + ".ITEM_DISPLAY_NAME", displayName ); } if (getBooleanValue("Options.Sell_Per_Block_Permission_Enabled")) { - confSection.set( "ITEM_PERMISSION", sellAllConfig.getString("Options.Sell_Per_Block_Permission") + itemID); + conf.set( confKey + ".ITEM_PERMISSION", sellAllConfig.getString("Options.Sell_Per_Block_Permission") + itemID); } conf.save(sellAllFile); @@ -2330,15 +2326,15 @@ public boolean editPrice( String itemID, String displayName, double value) { String itemName = pBlockKey.getBlockNameSearch().toUpperCase(); String confKey = "Items." + itemName; - ConfigurationSection confSection = conf.getConfigurationSection( confKey ); +// ConfigurationSection confSection = conf.getConfigurationSection( confKey ); - confSection.set("ITEM_ID", pBlockKey.getBlockNameSearch() ); - confSection.set("ITEM_VALUE", value); - confSection.set("IS_LORE_ALLOWED", pBlock.isLoreAllowed() ); + conf.set( confKey + ".ITEM_ID", pBlockKey.getBlockNameSearch() ); + conf.set( confKey + ".ITEM_VALUE", value); + conf.set( confKey + ".IS_LORE_ALLOWED", pBlock.isLoreAllowed() ); if ( displayName != null && displayName.trim().length() > 0 ) { - confSection.set("ITEM_DISPLAY_NAME", displayName.trim() ); + conf.set( confKey + ".ITEM_DISPLAY_NAME", displayName.trim() ); } else { //confSection.set("ITEM_DISPLAY_NAME", null); @@ -2347,11 +2343,11 @@ public boolean editPrice( String itemID, String displayName, double value) { if ( pBlock.getPurchasePrice() != null ) { - confSection.set("PURCHASE_PRICE", pBlock.getPurchasePrice().doubleValue() ); + conf.set( confKey + ".PURCHASE_PRICE", pBlock.getPurchasePrice().doubleValue() ); } if (getBooleanValue("Options.Sell_Per_Block_Permission_Enabled")) { - confSection.set("ITEM_PERMISSION", sellAllConfig.getString("Options.Sell_Per_Block_Permission") + itemName ); + conf.set( confKey + ".ITEM_PERMISSION", sellAllConfig.getString("Options.Sell_Per_Block_Permission") + itemName ); } conf.save(sellAllFile); From 825b314ec2c1854dd2c653a11065fc9d1079cff8 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 8 Feb 2025 03:54:55 -0500 Subject: [PATCH 241/323] Players: On reloading players, and also sometimes on server restarts, player's ranks were being reset back to the default ranks on each ladder. This was caused by a bug where the rankId was trying to be used instead of the rank name. RankId is obsolete, but is still in the code so older player files can be loaded and converted to the new format. The code that handles this conversion, and the basic loading, was rewritten to properly handle the rank name and rankId if it is still required. --- docs/changelog_v3.3.x.md | 7 +- .../prison/ranks/data/RankLadder.java | 25 +++++++ .../prison/ranks/data/RankPlayer.java | 18 ++++- .../prison/ranks/data/RankPlayerFactory.java | 70 +++++++++++++++++-- 4 files changed, 112 insertions(+), 8 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 6d68bdf98..b1272b56c 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.19e 2025-02-07 +# 3.3.0-alpha.19e 2025-02-08 + + +* **Players: On reloading players, and also sometimes on server restarts, player's ranks were being reset back to the default ranks on each ladder.** +This was caused by a bug where the rankId was trying to be used instead of the rank name. RankId is obsolete, but is still in the code so older player files can be loaded and converted to the new format. +The code that handles this conversion, and the basic loading, was rewritten to properly handle the rank name and rankId if it is still required. * **Sellall: Removed use of ConfigurationSection since it works fine until a new value is being added.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/ranks/data/RankLadder.java b/prison-core/src/main/java/tech/mcprison/prison/ranks/data/RankLadder.java index 9e6169aed..27408f455 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/ranks/data/RankLadder.java +++ b/prison-core/src/main/java/tech/mcprison/prison/ranks/data/RankLadder.java @@ -301,6 +301,31 @@ public Rank getRank( String rank ) { return results; } + + /** + * This function should never be used since magic numbers as used in + * the rank ID are no longer valid. This function is ONLY used when loading + * old player file data so it can be converted to the newer format. + * + * @param rankId + * @return + */ + public Rank getRank( int rankId ) { + Rank results = null; + + if ( rankId != -1 ) { + + for ( Rank r : ranks ) { + if ( r.getId() != -1 && r.getId() == rankId ) { + results = r; + break; + } + } + } + + return results; + } + /** * Add a rank to this ladder. * 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 8fad9ad29..161b56858 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 @@ -90,6 +90,8 @@ public class RankPlayer private TreeMap ladderRanks; + // Obsolete: rank ids no longer are being used... + // except when loading old format data prior to being converted. // ranks is the storage structure used to save the player's ladder & ranks: private HashMap ranksRefs; // @@ -582,7 +584,7 @@ public String filenameCache() */ public void addRank( Rank rank) { if ( rank.getLadder() == null ) { - throw new IllegalArgumentException("Rank must be on ladder."); + throw new IllegalArgumentException("Rank must be on ladder."); } String ladderName = rank.getLadder().getName(); @@ -762,7 +764,19 @@ public void removeRank(Rank rank) { } public boolean hasLadder( String ladderName ) { - return ranksRefs.containsKey( ladderName ); + boolean results = false; + + Set ladders = getLadderRanks().keySet(); + + for (RankLadder ladder : ladders) { + if ( ladderName != null && ladder.getName().equalsIgnoreCase(ladderName) ) { + results = true; + break; + } + } + + return results; +// return ranksRefs.containsKey( ladderName ); } // /** diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactory.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactory.java index 835182d03..1828d5d89 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactory.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactory.java @@ -20,6 +20,7 @@ import tech.mcprison.prison.ranks.commands.RankUpCommand; import tech.mcprison.prison.ranks.events.FirstJoinEvent; import tech.mcprison.prison.ranks.managers.LadderManager; +import tech.mcprison.prison.ranks.managers.PlayerManager; import tech.mcprison.prison.store.Document; import tech.mcprison.prison.util.ConversionUtil; @@ -50,6 +51,7 @@ public RankPlayer createRankPlayer(Document document) { // LinkedTreeMap blocksMinedLocal = // (LinkedTreeMap) document.get("blocksMined"); + LadderManager ladderManager = PrisonRanks.getInstance().getLadderManager(); for (String key : ranksLocal.keySet()) { @@ -57,17 +59,75 @@ public RankPlayer createRankPlayer(Document document) { Object rankObj = ranksLocal.get(key); if ( rankObj instanceof Double ) { + + // Example of this kind of data: + // "ranks": { + // "default": 2 + // }, + + int rankId = ConversionUtil.doubleToInt( rankObj ); - rankPlayer.getRanksRefs().put(key, rankId ); - } + + RankLadder ladder = ladderManager.getLadder( key ); + Rank rank = ladder.getRank( rankId ); + + // Setups up the rank for the player and recalculates all of the rank multipliers: + rankPlayer.addRank( rank ); + + // Obsolete, but used when upgrading from an older version of prison. +// rankPlayer.getRanksRefs().put(key, rankId ); + } else { + + // Example of this newer format of data: + // Note; rankId should always be -1 when using this format so ignore it. + // "ranks": { + // "default": { + // "ladderName": "default", + // "rankId": -1, + // "rankName": "C" + // } + // }, + + // It's a json object: - // We only need to get the rankId from the json String, but the other fields are there - // for human readability. + // RankID should be obsolete, so use ladderName and rankName. String json = rankObj.toString(); RankPlayerFactoryDataRank rData = jfIO.fromString( json, RankPlayerFactoryDataRank.class ); if ( rData != null ) { - rankPlayer.getRanksRefs().put( rData.getLadderName(), rData.getRankId() ); + String ladderName = rData.getLadderName(); + String rankName = rData.getRankName(); + + // Use of rankId is obsolete so ignore it: + int rankId = rData.getRankId(); +// rankPlayer.getRanksRefs().put( rData.getLadderName(), rankId ); + + + RankLadder ladder = ladderManager.getLadder( ladderName ); + Rank rank = ladder.getRank( rankName ); + + if ( rank == null && rankId != -1 ) { + // Fall back to rankId since there was a short time when rankId was used in this + // json format without a valid rankName. + rank = ladder.getRank( rankId ); + } + + // Setups up the rank for the player and recalculates all of the rank multipliers: + if ( rank != null ) { + + rankPlayer.addRank( rank ); + } + else { + String msg = String.format( + "RankPlayerFactory.createRankPlayer: Failed to add a player rank. " + + "Player: %s json: %s", + rankPlayer.getName(), + json + ); + + Output.get().logWarn( msg ); + } + } } From 620e637598b4dbf6e0ba9a62891f5e6910eece77 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 8 Feb 2025 05:47:13 -0500 Subject: [PATCH 242/323] Placeholders: Updated the docs to include the new command placeholder: '{range: }' --- docs/changelog_v3.3.x.md | 4 + docs/prison_docs_310_guide_placeholders.md | 1980 ++++++++++---------- 2 files changed, 999 insertions(+), 985 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index b1272b56c..82008b568 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.19e 2025-02-08 +* **Placeholders: Updated the docs to include the new command placeholder: '{range: }'** + + + * **Players: On reloading players, and also sometimes on server restarts, player's ranks were being reset back to the default ranks on each ladder.** This was caused by a bug where the rankId was trying to be used instead of the rank name. RankId is obsolete, but is still in the code so older player files can be loaded and converted to the new format. The code that handles this conversion, and the basic loading, was rewritten to properly handle the rank name and rankId if it is still required. diff --git a/docs/prison_docs_310_guide_placeholders.md b/docs/prison_docs_310_guide_placeholders.md index e17f9e1a7..e28600cd9 100644 --- a/docs/prison_docs_310_guide_placeholders.md +++ b/docs/prison_docs_310_guide_placeholders.md @@ -1,985 +1,995 @@ - -### Prison Documentation -[Prison Documents - Table of Contents](prison_docs_000_toc.md) - -## Prison - Placeholder Guide - -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: 2023-09-21* - - -
- - -# Overview - -Placeholders allow the sharing of data from one plugin with another plugin, and without either plugin knowing anything about each other. - -On the surface they appear to be simple, but there are a lot of moving parts below the surface, and with Prison, there are even more complicated things going on. - -Add in to the mix, that different plugins deal with placeholders in slightly different ways, and you can wind up with a challenge to get them to work under different circumstances. - - -**New Feature!** Custom Placeholders! - -Prison now supports the creation of custom placeholders, which can include any text, with formatting, and any number of placeholders too. Even non-prison placeholders. The benefit of custom placeholders is that you can create complex placeholders in one place, within prison, at any length, and then use them in any of your other plugins such as holographic displays, scoreboards, etc... Prison will expand all placeholders, including from other plugins, and provide the final result. - - -
- - - - -# Placeholder Commands - - -*Since Prison v3.2.1-alpha.13* - - -There are a few useful commands within prison that will allow you list placeholders, search for placeholders, and to test random text that includes placeholders. - - -Sub-command listing of all placeholders commands: - -* **/prison placeholders** - -> Shows a list of all of the placeholder related commands. - - -* **/prison placeholders list** - -> Lists all placeholders that are available, including their aliases. Placeholders are grouped by their type, of which there are 10 different kinds. Some are player specific, rank or ladder specific, mine specific, or even hybrid combinations such as player-mine were the mine stats are based upon which mine the player is in. - - -* **/prison placeholders search** - -> Provides a simple search for placeholders, optionally using a player's name, and it shows the results with actual live placeholder values. Search values can be one or more word fragments. - - -* **/prison placeholders test** - -> Somewhat like search, but you have to provide the whole placeholder surrounded by escape characcters. Can provide more than one placeholder too. This is more like testing what you would place within a chat prefix or holographic sign. - - -* **/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 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** - -> Reloads and rebuilds all placeholders and then reregisters them. This is performed when adding or removing a new mine or rank. - - - -NOTE: the `/prison placeholders reload` command only reloads and registers the placeholders with the placeholder integrations. This would be required to enable placeholders when adding a new mine, a new rank, or a new ladder. If you reload another plugin, such as papi, you may need to reload the placeholders which will re-register them. Prison has been setup to survive a papi restart, but there could still be issues. - - -NOTE: Information on these command are provided in detail below. - - -
- - -# Placeholder Types and Counts - -Prison has numerous placeholders, with number of different types. Each of these types have different internal requirements and conditions of usage. This is a high overview of the various types and their counts. - - -* **Total Available Placeholders:** 294 including aliases - - -* **Player Related:** 112 including aliases - * **Rank Related:** 8 including aliases - * **Rankup Related:** 20 including aliases - * **Player Balance Related:** 8 including aliases - * **Player Token Balance Related:** 12 including aliases - * **Player Blocks Totals Related: 4 including aliases - * **Player Tool Related:** 34 including aliases - * **Player Health Related:** 14 including aliases - * **Player XP and Levels Related:** 6 including aliases - * **Player Walk Speed:** 2 including aliases - - -* **Ladders Related:** 34 including aliases **times** each ladder - -> A LADDERS placeholder must include the ladder's name in the placeholder and therefore is static. - -> The ladder based placeholders end with `_laddername`, but they include the following possible prefixes, which may not be exclusive to ladder based placeholders. - -> Ladder placeholder prefixes: - * `prison_rank_` - * `prison_rankup_` - * `prison_player_` - - - -* **Ranks Related:** 24 including aliases **times** each rank - -> A RANKS placeholder needs to specify the Rank name as part of the placeholder. Each placeholder must specify a Rank and is static. - -> The ranks based placeholders end with `_rankname` but do not require a player to work. They also have a prefix of `prison_rank__` but these prefixes and suffixes are also shared with **RankPlayers** placeholders. See them for specifics. - -> Ranks placeholder prefixes: - * `prison_rank__` - - -* **RankPlayers Related:** 12 including aliases **times** each rank - -> A RANKPLAYERS placeholder is one that will change based upon the player's own Rank. Each player could have a different rank. Because of this relationship, these can only be used with instances of players such as scoreboards and chat prefixes; they will not work in holographic displays or with signs. - -> RankPlayers placeholders are very similar to the Rank placeholders in respect to the prefixes and suffixes, but these placeholders MUST include a player or they cannot work. Without a player, they cannot return a valid value, and therefore will return either a blank or zero. - -> What makes these placeholders stand out from rank placeholders is the prefix includes `player_`. For example: - -> RankPlayers placeholder prefixes: - * `prison_rank__player_` - - -> **Performance Warning:** There is a high risk of performance issues when calculating a full GUI page of items that includes the use of placeholders that are based upon the placeholders: `prison_rank__player_cost_rankname`. The reason for this is related to a progressively great number of calculations required to calculate high ranked prestige ranks. The performance impact can include processing and memory usages. - -> For example, if there are 26 default ranks, and the player is at rank A with no prestiges, then to calculate rank P4 would include the following ranks: -b --> z + p1 + a --> z + p2 + a --> z + p3 + a --> z + p4. -This results in a total of 107 ranks that must be collected, then the player's cost for each rank will have to be calculated. Then all of these must be added together to get the player's cost on rank P4. - -> So if there are thousands of prestige ranks, then the calculations will be numerous for each placeholder. - - -* **Player Ladder Balance Related:** 32 including aliases **times** each Mine - - -* **Mines Related:** 28 including aliases **times** each ladder - -> A MINES placeholder must specify the Mine mine as part of the placeholder. - -> The Mines related placeholders have the following prefixes, but they are also shared with the MinePlayers placeholders. -* `prison_mines_` -* `prison_top_mine_` - - - -* **MinePlayers Related:** 32 including aliases - -> A MINEPLAYERS placholder is similar to a RankPlayers placeholder in that it is dynamic and you cannot specify a mine's name with it. How it works, is that it provides the related stats for the mine in which the player is standing in. When the player leaves the mine, then these placeholders returns an empty string value (a blank). - -> The MinePLayers placeholders includ the following prefixes, but they are also similar to the Mines related placeholder too: - * `prison_player_` - * `prison_mines_` - - -* **PLAYERBLOCKS:** 4 including aliases - -> Every block type that a player breaks within a mine is tracked. These provide the stats on those blocks. - - -* **STATSMINES Related:** 18 including aliases - -> These list the blocks within a mine. They are referred to with a `_nnn_` notation where "nnn" is the line number - - -* **STATSRANKS Related:** 6 including aliases - -> Top-n stats for each rank. The rank name must be specified on the placeholder. - - -* **STATSPLAYERS:** 30 including aliases - -> Various placeholders for the top-n ranked players. These are over all ranks. There are a couple of shortcut placehodlders where one placeholders contain multiple fileds for easier usage. - - - -* **ONLY_DEFAULT_OR_PRESTIGES:** 4 including aliases - -> A couple of placeholders that will only include the default and prestige ladder's rank tag name. These are handy such that you only need to use the one, and it will ensure none of the other ladder's ranks will be included. - - - -* **CUSTOM:** Depends upon how many are configured on your server. - -> Custom placeholders allow for the creation of complex text that can include many other placeholders, including their placeholder attributes and other plugin placeholders. The benefit is that when using these in another plugin, you just need to use the short simple placeholder name and it will auto expand everything for you. - - - -
- - -# Requirements - -There is always more than one way to do things, and the same goes for having more than one way to use placeholders. This documentation, and our test servers, primarily rely on the use of PlaceholderAPI as the core component to making placeholders work. Depending upon other plugins that you may use, they may have other dependencies too. - -**PlaceholderAPI** - [Setting up PlaceholderAPI](prison_docs_0xx_setting_up_PlaceholderAPI.md) - Strongly Suggested if using placeholders. - - -**Holographs** and **Scoreboards** - There are actual a couple of holograph display plugins. Most of the references in this document refer to Holographic Displays, but some of the newer plugins can provide the same functionality, plus many new features. - -Some of example of other holographic plugins are: AnimatedScoreboard, DecentHolograms, Scoreboard Revision, and etc.. - - -
- - -# Placeholder Theory for Prison - -*(needs updating: Prison now has 10 types of placeholders including top-n variations)* - - -There are few major types of placeholders in prison: Player, Ranks, Ladders, Mines, and Stats based. With the most recent releases of prison, there have been hybrids added that are a combination of the player placeholders and with mines and ranks. For example there are now ladder based placeholder that allow targeting ranks on a specific ladder, instead of all ladders. Also there are player mine placeholders that report on the mine stats for the mine in which the player is physically located in. The player mine placeholders have no value when the player is not in a mine, and they will change as the player goes from mine to mine. - -There are also different types of data that are returned in placeholders. Text, numbers, formatted numbers, and bar graphs. - -The player based placeholders can only report on the player that is initiating the command, or request. These placeholders pertain to the player's attributes, such as rank, next rank, their balance, how more they need before reaching the next rank, and etc. Internally, all of these requests must include the player's UUID, which is why you cannot just add them to a sign, since the sign does not know any player's UUID. - -There are actually two major kinds of player based placeholders; a third type is "related" more to mines and not specifically to the player's ranks. Rank placeholders that returns all of the player's current attributes for all active ladders they are associated with. For example, if they are active on four ladders, then they will have four active ranks on four ladders with possible values. So it may look something like this: `[mod][Zeus][+2][B]`, of which the ladders could be mod, donor, prestige, and default. The thing to remember about player rank placeholders is that they may return more than one value, and you cannot control the order of the values. - -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. - -Prison has integrations for direct use of providing placeholder values to to the other plugins. Some of those other plugins request placeholder values using partial placeholder names. Therefore to improve performance and to prevent having to always reconstructing the full placeholder names, prison precomputes the fragments for all placeholders. Therefore, with our example of 40 mines and 10 placeholders, the actual internal number of placeholder combinations that prison will respond to is 800: 40 mines x 10 placeholders per mine x 2 for aliases = 800 placeholders for prison. - -Off hand this may sound bad, but Prison utilizes enumerations for identifying placeholders, so they may be objects, but they are lightweight and helps ensure placeholders align with the code at compile time. This not only provides better performance, and less memory consumption, but programming errors and typos are caught at compile time and not runtime, so they also provide for a more stable and reliable Prison environment. - -Internally, placeholders within Prison are case insensitive. But Prison uses lower cased placeholder names to register with any placeholder integration. Therefore, although prison may be case insensitive, the placeholder plugins may not recognize the placeholders unless you use them as all lower case names. - -Also, internally, prison only responds to the placeholder name without the escape characters. The escape characters are generally curly braces { }, or percents % %, but may be other characters. All placeholder plugins strip off the escape characters before passing anything to prison. So proper use of placeholders is dependent upon what is being required by your placeholder plugin and may require a mix of escape characters. - -
- - -# Placeholder Attributes - Customize almost any Prison Placeholder - -*Since Prison v3.2.4-alpha.2* - - -Placeholders within prison can now be dynamically customized without having to make any changes to any configurations. The same placeholder can be used in multiple place, each with different configurations. This is now possible through the use of placeholder attributes and offers a large degree of customization. - - -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=<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. - - - -The following shows how a few placeholder need to have the "minename" replaced with the actual mine's name. For these examples, we will use a mine named **temp5**. - -* **prison_mines_size_minename** - `{prison_mines_size_temp5}` -* **prison_mines_remaining_minename** - `{prison_mines_remaining_temp5}` -* **prison_mines_remaining_bar_minename** - `{prison_mines_remaining_bar_temp5}` -* **prison_mines_timeleft_bar_minename** - `{prison_mines_timeleft_bar_temp5}` - - - -A few Examples using Placeholder Attributes: - -* `{prison_mines_size_temp5::nFormat:#,##0}` - **654,321** -* `{prison_mines_size_temp5::nFormat:#,##0:0:none}` - **654,321** -* `{prison_mines_size_temp5::nFormat:#,##0.00:1:kmg}` - **654.32 k** -* `{prison_mines_size_temp5::nFormat:#,##0:0:kmg}` - **654k** - - -* `{prison_mines_remaining_bar_temp5}` - Normally displays as (no color) - * **>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<** -* `{prison_mines_remaining_bar_temp5::bar:10}` - Using default values, but change length to 10 - * **>>>>>>>>><** -* `{prison_mines_remaining_bar_temp5::bar:10:&2:#:&d:-}` - Change all settings - * **#######---** -* `{prison_mines_timeleft_bar_temp5::bar:40:&2:O:&d:x:debug}` - Enable debug mode for the attribute - * **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: - - -The placeholder: `{prison_mines_timeleft_bar_temp5::bar:40:&2:O:&d:x:debug}` - -The full command: -`/prison placeholders test {prison_mines_timeleft_bar_temp5::bar:40:&2:O:&d:x:debug}` - - -Example of an attribute with debug - -When debug mode is enabled, it will print to the console information about the placeholder attribute, as seen in the above screen print. This could be useful when testing the configuration of placeholder attributes - - -Using the command `/prison placeholders test` should be used to test and perfect the use of the placeholder attributes. - -
- - - -## Placeholder Attribute: nFormat - Numeric Formats - - -The Numeric Format attribute will only work on placeholders that return plain numbers. If there is a "_format" version of the placeholder, then an attribute will override the default formatting. - -Example of this attribute's usage is as follows, using descriptions for each parameter. - -`::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. Examples of - how the formatting can be used: - * #,### - * #,###.00 - * #,###.00000 - -- **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 the placeholder type that is used. - - * **none**: No display of units. No transformations. - * **kmg**: Uses one character units: kMGTPEZY. Transforms results by - dividing by 1000.0 until value is less than 1000.0, and - each time it increments the unit character. - k=1,000, M=1,000,000 and etc. These are metric SI codes. - * **kmbt**: Uses one character units: KMBTqQsS. Transforms results by - dividing by 1000.0 until value is less than 1000.0, and - each time it increments the unit character. - k=1,000, M=1,000,000 and etc. These are non-standard codes. - * **binary**: Uses a base-two divisor of 1024 along with the units: - KB, MB, GB, TB, PB, EB, ZB, and YB. - - * *Note:* Other unitTypes can be added along with different style of - 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 - 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. 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. - - - -The parameters that are optional do not have to be included, unless another parameter after the optional ones are needed. Then the optional parameter must be supplied and cannot be empty. - - -`{prison_mines_size_temp5::nFormat:#,##0.00:1:kmg}` - - - -Although it is not suggested to include color codes in the formatting of numbers, it may be possible with the addition of the quoting them with single quotes. The following use of **hex2** format works well with testing on a scoreboard that does not support hex colors, and is a way to inject the hex color when it cannot be used directly in the scoreboard configs. - -``` -{prison_mines_size_temp5::nFormat:'#af33ff'#,##0.00:1:kmg:hex} -{prison_mines_size_temp5::nFormat:'#af33ff'#,##0.00:1:kmg:hex2} -``` - - - -
- - - - -## Placeholder Attribute: bar - Bar Graphs - - -The bar placeholder attribute only works with placeholders with the word bar in them. - - -Example of this attribute's usage is as follows, using descriptions for each parameter. - -`::bar:size:posColor:posSeg:negColor:negSeg:reverse:hex:hex2:debug:player=` - - - -- **bar**: the keyword to identify this attribute. -- **size**: The number of segments to generate. -- **Positive Color**: The color code to use for the positive segments. - Color codes should start with an &. -- **Positive Segment**: The value that will be used for the positive - segment. -- **Negative Color**: The color code to use for the negative segments. - Color codes should start with an &. -- **Negative Segment**: The value that will be used for the negative - segment. - - -- **reverse**: **Optional.** Case sensitive. Non-positional; can be placed anywhere. - When enabled, this will reverse the bar graph. - - -- **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. 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. - - - -The parameters are all optional and if they are not supplied then the default values for the bar graph will be used instead. - -`{prison_mines_remaining_bar_temp5::bar:10}` - -`{prison_mines_remaining_bar_temp5::bar:10:&2:#:&d:-}` - -`{prison_mines_timeleft_bar_temp5::bar:40:&2:O:&d:x:debug}` - - -To use hex color codes within the bar graphs, the plugins that are requesting them, may not always support hex colors. So the options of **hex** and **hex2** are options to provide pre-formatting of the hex colors so that way the hex colors could work with plugins that do not support them. If the use of **hex** does not work, then **hex2** may. - - -Examples of using hex color codes in a bar graph placeholder. Try it first with **hex**, and if that does not work, then try **hex2**. - -``` -{prison_mines_timeleft_bar_a::bar:15:#abcdef:O:#5a3c7f:x:hex} -{prison_mines_timeleft_bar_a::bar:15:#abcdef:O:#5a3c7f:x:hex2} -``` - - - -
- - - - -## Placeholder Attribute: text - Text - - -This placeholder attribute is for text formatting the placeholder results. The only thing it does is to process the hex, hex2, and debug options. - - -This placeholder attribute can be used with any placeholder, even for placeholders -that have other attributes to format their content. Since this is strictly processing -the hex color codes, it will operate upon the final text output from the other -placeholders. - - - -Example of this attribute's usage is as follows, using descriptions for each parameter. - -`::text:hex:hex2:debug:player=` - - - -- **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. 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. - - - - -
- - -# Prison's Custom Placeholders - - -Have you ever tried to setup one row in a scoreboard that included three or four placeholders? Did any of them include placeholder attributes? Some scoreboards even impose limits on how many characters you can use in the config settings. - -With Prison's new Custom Placeholders, you can define any number of them within the prison's `config.yml` file, and then use just the custom placeholder's short name. Prison will automatically expand all included placeholders, even non-prison placeholders. - - -
- -### Custom Placeholder Configurations - -Prison's custom placeholders are defined in the `plugins/Prison/config.yml` file, under the grouping of `placeholder`. - - -```yaml -placeholder: - - # Custom Placeholders: - # They MUST begin with 'prison__', which has two underscores, or they will not work. - # Custom placeholders can have an abbreviated format where it is the placeholder - # with the quoted value, which can be multi-lined. - # The extended format can have additonal settings. The actual placeholder is - # paired with 'placeholder'. - # If the custom placeholder contains non-prison placeholders, then you can set - # the 'papi_expansion' to true. - # If a description is provided, it will be shown within the placeholder listing. - # Note that the use of hex colors will not work with bukkit versions prior to - # spigot 1.14. - custom-placeholders: - prison__chat_prefix: - placeholder: "{prison_rank_tag_default}{prison_rank_tag_prestiges}" - papi_expansion: true - description: "Can use this in your chat prefix. May have to use %% instead of {}." - prison__player_stats: "{prison_rank_tag_default} -> {prison_rankup_rank_tag_default} - {prison_rankup_cost_remaining_bar_default::bar:50:&a:|:&d:|} - {prison_rankup_cost_remaining_formatted_default} needed to rankup" - -# Pre-spigot 1.14: Cannot do RGB colors: - prison__branding_pre_1_14: "&2P&3r&4o &5M&6i&4n&3e&2s" - - prison__branding: "&#e81416P&#ffa500r&#faeb36o - Oc314Mǧde7ib369dn𑋡de&#ac7ad1s" - -``` - - -
- - -### Custom Placeholders Format - Name - -A custom placeholder is only identified as a custom placeholder by the prefix of it's name. Therefore, all custom placeholders must start with `prison__`. That is two underscores. If it does not have two underscores, it will be ignored. - -The remainder of the custom placeholder's name can be any valid character combination, excluding any white space. We strongly suggest it is kept to alpha-numeric with underscores. But you may be able to use dashes, other symbols, including colons. If you try to use something other than alpha-numeric plus underscores, then do so at your own risk because other plugins, including Prison, may not handle them correctly or successfully. - - -
- - -#### Custom Placeholders Format - Abbreviated (simple) - -The abbreviated form of a custom placeholder is simply the name of the placeholder, followed by the String value. - -Two examples are as follows, where the first is a one liner, and the other is a multi-line example. - -```yaml -placeholder: - custom-placeholders: - prison__branding: "&2P&3r&4o &5M&6i&4n&3e&2s" - prison__multi_line: "This is a simple example with - no placeholders, but it's on multiple lines - as this placeholder implies." - -``` - -Please note that multi-line String values wraps to the next line, indented two character more than the placeholder's name. - - -
- - -#### Custom Placeholders Format - Expanded (complex) - -The complex form of a custom placeholder has at least one attribute, and potentially other settings that can expand the functionality of a placeholder. - -**placeholder** attribute - This contains the actual placeholder String value. It can be multiple lines in length, and can have none, or many other placeholders in it. - -**papi_expansion** attribute - Defaults to a value of `false`. If this value is `true`, then after prison expands all prison placeholders, Prison will then have PAPI expand all non-prison placeholders. If a non-prison placeholder is used in the abbreviated placeholders, or if this one is set to `false`, then it will be ignored and you may see it displayed in the final text. - -**description** attribute - This is a description of the custom placeholder, which is optional. It is ONLY displayed in the placeholder listings: `/prison placeholders list` - - -Two examples are as follows, where the first is a one liner, and the other is a multi-line example. - -```yaml -placeholder: - custom-placeholders: - prison__branding: "&2P&3r&4o &5M&6i&4n&3e&2s" - prison__chat_prefix: - placeholder: "{prison_rank_tag_default}{prison_rank_tag_prestiges}: &3{player}:&r" - papi_expansion: true - description: "Can use this in your chat prefix. May have to use %% instead of {}." - -``` - -Please note that multi-line String values wraps to the next line, indented two character more than the placeholder's name. - - -
- - - -# Prison Command Placeholders - Mines, Ranks, Ladders, and Block Commands - -This document is not intended to cover Prison command placeholders, but within Prison there are many areas where you can setup commands. Each of them have their own set of placeholders. Prison supports many placeholders to allow you to better customize command. - -The commands can contain more than one command. Keep them all on one line, but end each command with a semi-colon: `;`. - - -To see the list of placeholders, most commands have command parameter that will show all of them. This is a list of all of these commands, and their related placeholders. Please run these commands in the console, for yourself, to confirm that there have not been any new updates since this document was last updated. - -Keep in mind that the use of these placeholder are very strict. They include the curly braces, and they must be in case in which they are listed. - -`/ranks command add placeholders` - -**{player} {player_uid} {msg} {broadcast} {title} {actionBar} {inline} {inlinePlayer} {sync} {syncPlayer} {ifPerm:} {ifNotPerm:} {firstJoin} {promote} {demote} {balanceInitial} {balanceFinal} {currency} {originalRankCost} {rankupCost} {ladder} {rank} {rankTag} {targetRank} {targetRankTag}** - -`/ranks ladder command add placeholders` - -**{player} {player_uid} {msg} {broadcast} {title} {actionBar} {inline} {inlinePlayer} {sync} {syncPlayer} {ifPerm:} {ifNotPerm:} {firstJoin} {promote} {demote} {balanceInitial} {balanceFinal} {currency} {originalRankCost} {rankupCost} {ladder} {rank} {rankTag} {targetRank} {targetRankTag}** - -`/mines command add placeholders` - -**{player} {player_uid} {msg} {broadcast} {title} {actionBar} {inline} {inlinePlayer} {sync} {syncPlayer} {ifPerm:} {ifNotPerm:}** - -`/mines blockevent add placeholders` - -**{player} {player_uid} {msg} {broadcast} {title} {actionBar} {inline} {inlinePlayer} {sync} {syncPlayer} {ifPerm:} {ifNotPerm:} {blockName} {mineName} {locationWorld} {locationX} {locationY} {locationZ} {coordinates} {worldCoordinates} {blockCoordinates} {blockChance} {blockIsAir} {blocksPlaced} {blockRemaining} {blocksMinedTotal} {mineBlocksRemaining} {mineBlocksRemainingPercent} {mineBlocksTotalMined} {mineBlocksSize} {blockMinedName} {blockMinedNameFormal} {blockMinedBlockType} {eventType} {eventTriggered} {utilsDecay}** - - - - -#### Prison Command Placeholder Descriptions - - -Detailed information on what exactly each of these placeholders do, is not intended to be a part of this document. But the following is a brief description. - -Additional information on the BlockEvent placeholders can be found in the [BlockEvent documentation](prison_docs_115_using_BlockEvents.md). - -If a placeholder is marked with **Non-Positional**, that means that the placeholder can appear anywhere in the command to trigger the effect. It's non-positional since it's removed when detected, therefore when the command is ran, it will not be encountered. - - -* **{player}** - The player's name. -* **{player_uid}** - The player's UUID. -* **{msg}** - Send a message to the player. The message follows this placeholder. -* **{broadcast}** - Broadcast a message to all players on the server. -* **{title}** - Send a message to the player, but show in the screen's title region. -* **{actionBar}** - Send a message to the player, but show in the action bar. - - -* **{inline}** - Run the command "inline" with the processing of the original prison command, but run as console. **Non-Postional.** -* **{inlinePlayer}** - Run the command "inline" with the processing of the original prison command, but run the command as the player. **Non-Postional.** -* **{sync}** - Submit the command to run in a synchronous thread at the first opportunity. This runs the command as console. Since the command is submitted, it may have to wait behind other tasks. **Non-Postional.** -* **{syncPlayer}** - Submit the command to run in a synchronous thread at the first opportunity. This runs the command as the player; if the player does not have access to run the specified command, then it will fail. Since the command is submitted, it may have to wait behind other tasks. **Non-Postional.** - - -* **{ifPerm:};** - Runs the commands that follows this placeholder, only if the player has the specified permission. NOTE: In order for this to work properly, it must be immediately be followed by a semi-colon so it's treated as it's own "command". -* **{ifNotPerm:};** - Runs the commands that follows this placeholder, but only if the player DOES NOT have the specified permission. NOTE: In order for this to work properly, it must be immediately be followed by a semi-colon so it's treated as it's own "command". - - -* **{firstJoin}** - Runs the commands that follows this placeholder, only if the rankup is based upon first join. This protects the commands that follows from being ran each time when the player hits the specified rank in the future. Example would be Rank A's command such that it runs on first join, but it will not run when the player prestiges and they are set back to A on the default ladder. **Non-Positional.** - - -* **{promote}** - This runs the command only on promotions such as rankup, promote, and setRank. **Non-Positional.** -* **{demote}** - This runs the command only on demotions such as demote. **Non-Positional.**c - -* **{balanceInitial}** - The player's balance before the rankup event was ran. -* **{balanceFinal}** - The player's balance after the rankup event was ran. -* **{targetRank}** - The next rank's name. * **{targetRankTag}** - The next ranks's tag value. -* **{currency}** - If the rank is using a different currency, then this parameter would provide the name of that currency. * **{originalRankCost}** - The rank cost for ranking up, but without the global rank cost multipliers. * **{rankupCost}** - The rank cost for ranking up, including the global rank cost multipliers. * **{ladder}** - The current ladder name. * **{rank}** - The current rank name. * **{rankTag}** - The current rank's tag value. - -* **{blockName}** - The name of the block that was mined. -* **{mineName}** - The mine where the block was mined. -* **{locationWorld}** - The world name where the mine exists. - - - -* **{locationX}** - The **X** coordinates for the broken block. This is an integer value. -* **{locationY}** - The **Y** coordinates for the broken block. This is an integer value. -* **{locationZ}** - The **Z** coordinates for the broken block. This is an integer value. - - -* **{coordinates}** - This provides the X, Y, and Z coordinates for the broken block. These are double values, surrounded by parenthesis and separated by commas. Format: **(X,Y,Z)** Example: `(183.2,88.3792,-3828.248)` -* **{blockCoordinates}** - This is similar to the **{coordinates}** placeholder, except for the use of integer values. Format: **(blockName,world,X,Y,Z)** Example: `(,prisonWorld,183,88,-3828)` -* **{worldCoordinates}** - This combines both the **{locationWorld}** and **{blockCoordinates}** placeholder in to one placeholder. The coordinates are integer values. Format: **(world,X,Y,Z)** Example: `(prisonWorld,183,88,-3828)` - - -* **{blockChance}** - For the block type that was mined, what was the chance of it's spawn rate. -* **{blockIsAir}** - Indicates if the block being processed was AIR. This could be true if an included block within an explosion was already replaced with AIR. -* **{blocksPlaced}** - -* **{blockRemaining}** - -* **{blocksMinedTotal}** - -* **{mineBlocksRemaining}** - -* **{mineBlocksRemainingPercent}** - -* **{mineBlocksTotalMined}** - -* **{mineBlocksSize}** - -* **{blockMinedName}** - -* **{blockMinedNameFormal}** - -* **{blockMinedBlockType}** - -* **{eventType}** - This contains the name of the event that prison is handling. This is an internal event name as specified by Prison. -* **{eventTriggered}** - If Prison was handling a multi-block event, such as an explosion, and if that event supports identifying what triggered it, then this will contain that information. Example could be what enchantment was used to produce the explosion, or the name of the potion, etc. -* **{utilsDecay}** - - - - -This is mentioned here since these rank command placeholders are not part of all the other placeholders, so as such, it may be difficult to find information for these items. - - - -
- - - - -# Prison Placeholder Command Listing - - -Prison Placeholder Commands - -Example of placeholder command listings - - -

Prison Placeholder Listings

- -Prison Placeholder Listing -Prison Placeholder Listing - -Example of the list of placeholders that is available through **/prison placeholders list**. Please note that this list may evolve as new placeholders are added. Use these commands to get the current listing that is available on your server. - - -

Prison Placeholder Search with Two Search Patterns

- - -Prison Placeholder Search - -This is an example of searching for placeholders using a player's name plus two search patterns: *temp5* and *format*. The term temp5 is the name of a mine and is an example of a the dynamic construction of placeholders, and that you can still perform a search with them. The search patterns can be any String fragment found in either the placeholder, or it's alias. - -If more than one search pattern is provided, then all patters must hit on the same placeholder to be included in the results. They behave as a logical AND relationship. - -A player's is provided, but results do not include any player, rank, or ladder entries. This shows that if a player's name is provide, it is recognized as a player and will not prevent valid hits. - - -The following example shows what the command is like when specifying the player's name, a page numer for the results, and three search parameters: - -``` -/prison placeholders search RoyalCoffeeBeans 1 rankup cost default -``` - -This example shows the current placeholder values for that player, including an example of a bar graph. - -Prison Placeholder Search - - -

Prison Placeholder Listings - All Placeholders

- -Prison Placeholder Listing - -In this contrived example, since all placeholders begin with "prison", this search returns a listing of all placeholders. In this example, using the current Prison v3.2.1-alpha.13 release, it has generated 65 pages of results, at 6 placeholders per page which includes the alias. - -The following shows an example of all placeholders that are active with Prison_v3.2.2-alpha.10.jar. It includes a total of 1,294 placeholders, on 108 pages. This is based upon 4 ladders, 13 ranks, and 41 mines. - - -Prison Placeholder Listing - - - - -

Prison Placeholder Listings

- -Prison Placeholder Listing - - - -
- - -# Chat Placeholders - -There are two major ways a placeholder can be resolved within Prison: through chat or through a placeholder integration. - -Chat based placeholders do not rely on other plugins for them to work. Instead they use the org.bukkit.event.player.AsyncPlayerChatEvent, of which Prison will respond and provide translations to prison related placeholders that it find with the chat message. - -Although no plugin is required for Prison to properly handle chat based placeholders, other plugins may be required to generate their use. Such as EssentialsX's Chat plugin. It provides a way to prefix chat messages with placeholders. - - - -
- - - -# Enabling EssentialX's Chat Placeholders - -Set up the EssentialX's Chat plugin: [Setting up EssentialsX](prison_docs_0xx_setting_up_EssentialsX.md). - -Enabling the chat placeholder just requires editing one line within the `config.yml` file. Search for the keyword **EssentialsChat** in that file, then edit the `format:` tag. For example: - - format: '<{prison_rank_tag}:{DISPLAYNAME}>{MESSAGE}' - -Once setup, restart the server. Or use **/essentials reload**. Do not force all the plugins to be reloaded with a tool such as plugman since Prison (and other plugins) may fail to re-load properly. - - -This will include all placeholders that are active for the player, including the prestige chat prefixes. The only issue is that you cannot control the order of how they will display. - - -It is possible to manually set the order by using the individual placeholders for each rank you want to show. This allows you to omit certain placeholders too. Please see the next section of this document to learn how to set them up. - - -You can preview all of the placeholders with the placeholder search command. - - -``` -/prison placeholder search rank_tag - -/prison placeholder search RoyalCoffeeBeans rank_tag -/prison placeholder search RoyalCoffeeBeans 2 rank_tag -``` - - -Reviewing all placeholder tags - - -The placeholders are interested in are: `prison_rank_tag_pretiges` and `prison_rank_tag_default`. - - -So to set them up in the EsstentialsX Chat prefix would be as follows: - - - format: '<{prison_rank_tag_prestiges}{prison_rank_tag_default}:{DISPLAYNAME}>{MESSAGE}' - - - -

Ladder Specific Placeholders

- -One of the newer features available for placeholders has to do with ladder specific placeholders. This is similar to the mines placeholders but for ladders specifically. These player ladder placeholders are just the same a the player rank, but only for one ladder. The player rank placeholders will return all ranks on all ladders for that placeholder. - -This is an example of specifying the rank tag for both the prestige and default ladder. This ensures the expected order of these two tags, but it will also exclude other tags from other ladders, such as donor ladders or mod ladders. - - format: '<{prison_rank_tag_prestiges}{prison_rt_default}:{DISPLAYNAME}>{MESSAGE}' - - -Use the placeholder tools under `/prison placeholders` for more information and to see what is available for use. - - - -For example, to preview all of the placeholders with the placeholder search command. - - -``` -/prison placeholder search rank_tag - -/prison placeholder search RoyalCoffeeBeans rank_tag -/prison placeholder search RoyalCoffeeBeans 2 rank_tag -``` - - -Reviewing all placeholder tags - - - - -
- - - - -# Enabling HolographicDisplays Placeholders - -Follow directions on how to install and configure the HolographicDisplays plugin. - - -An important detail to realize, is that HolographicDisplays can only use placeholders that related to the server. It cannot access any of the prison placeholders on its own. It needs the help of other plugins to extend it's functionality. - -* [HolographicDisplays Download](https://dev.bukkit.org/projects/holographic-displays) -* [HolographicDisplays' Documentation](https://filoghost.me/docs/holographic-displays) - -* [HolographicExtension](https://www.spigotmc.org/resources/holographicextension.18461/) -* [PlaceholderAPI Setup Details](prison_docs_0xx_setting_up_PlaceholderAPI.md) -* [ProtocolLib](https://www.spigotmc.org/resources/protocollib.1997/) - -The simple directions on how to get everything to work is to download these plugins, and place them all in to your server's plugin directory. There is no need to modify any config files to get them to work with prison. Prison will register all of the internal placeholders with PlaceholderAPI so it knows they are valid and where to find them (where to send them to be resolved). - -The simplest way to create a HolographicDisplay would be to stand where you want one. Then enter the following command: - -``` -/hd create test -``` - -Then on the server file system, open the file: - -``` -plugins\HolographicDisplays\database.yml -``` - -Then edit the file. Keep in mind it is a yml file and must be valid yml. - -This is an example of a holographic sign: - -``` -temp5: - location: world, -99.832, 74.500, 191.215 - lines: - - 'Welcome to Prison Mine: temp5' - - 'Reset Interval: {slowest}%prison_mines_interval_temp5% - {slowest}%prison_mines_interval_formatted_temp5%' - - 'Reset Time Left: {medium}%prison_mines_timeleft_temp5% - {fast}%prison_mtlf_temp5%' - - 'Reset Time Left: {slowest}%prison_mines_timeleft_bar_temp5%' - - 'Reset Count: {medium}%prison_mines_reset_count_temp5%' - - 'Mine Size: {slowest}%prison_mines_size_temp5%' - - 'Blocks Remaining: {slowest}%prison_mr_temp5% {slowest}%prison_mp_temp5%%' - - 'Players in Mine: {slowest}%prison_mines_player_count_temp5%' -``` - -Notice that the prison placeholders are wrapped in the % % escape characters. The prefixed placeholders such as {slowest} and {fast} are for the plugin HolographicExtensions and they control how frequently the placeholders are refreshed. - -This is an example of the above settings, including the bar graph. Notice that the bar graph's properties can be adjusted for both the characters that are used, and the total number of characters (width). See the configuration within the file `/plugins/Prison/config.yml`. -Prison Holographic Displays - - -Once you update and save the database.yml file, you can have HolographicDisaplys reload from the files: - -``` -/hd reload -``` - -The above example will produce a holograph that is too tall and the bottom part will be underground. You can raise it up by manually increasing the **Y** value stored in *location:*. As you raise it up, and save the file, then you use **/hd reload** to refresh. It's also easier to make changes directly to the database.yml file. Repeat until it looks right. - - -One word of warning about editing the yml file, is that it must be valid yml, if not, then it could fail to load, or it may reset to a default file. If you're unsure about the file being proper yml, make sure you save a backup before trying to reload the HolographicDisplays settings. You can also run it through an online yml validator to fix any issues. To find an online yml validator, search for: "online yaml lint" or "online yaml validator". - - - - - -
- - + +### Prison Documentation +[Prison Documents - Table of Contents](prison_docs_000_toc.md) + +## Prison - Placeholder Guide + +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: 2023-09-21* + + +
+ + +# Overview + +Placeholders allow the sharing of data from one plugin with another plugin, and without either plugin knowing anything about each other. + +On the surface they appear to be simple, but there are a lot of moving parts below the surface, and with Prison, there are even more complicated things going on. + +Add in to the mix, that different plugins deal with placeholders in slightly different ways, and you can wind up with a challenge to get them to work under different circumstances. + + +**New Feature!** Custom Placeholders! + +Prison now supports the creation of custom placeholders, which can include any text, with formatting, and any number of placeholders too. Even non-prison placeholders. The benefit of custom placeholders is that you can create complex placeholders in one place, within prison, at any length, and then use them in any of your other plugins such as holographic displays, scoreboards, etc... Prison will expand all placeholders, including from other plugins, and provide the final result. + + +
+ + + + +# Placeholder Commands + + +*Since Prison v3.2.1-alpha.13* + + +There are a few useful commands within prison that will allow you list placeholders, search for placeholders, and to test random text that includes placeholders. + + +Sub-command listing of all placeholders commands: + +* **/prison placeholders** + +> Shows a list of all of the placeholder related commands. + + +* **/prison placeholders list** + +> Lists all placeholders that are available, including their aliases. Placeholders are grouped by their type, of which there are 10 different kinds. Some are player specific, rank or ladder specific, mine specific, or even hybrid combinations such as player-mine were the mine stats are based upon which mine the player is in. + + +* **/prison placeholders search** + +> Provides a simple search for placeholders, optionally using a player's name, and it shows the results with actual live placeholder values. Search values can be one or more word fragments. + + +* **/prison placeholders test** + +> Somewhat like search, but you have to provide the whole placeholder surrounded by escape characcters. Can provide more than one placeholder too. This is more like testing what you would place within a chat prefix or holographic sign. + + +* **/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 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** + +> Reloads and rebuilds all placeholders and then reregisters them. This is performed when adding or removing a new mine or rank. + + + +NOTE: the `/prison placeholders reload` command only reloads and registers the placeholders with the placeholder integrations. This would be required to enable placeholders when adding a new mine, a new rank, or a new ladder. If you reload another plugin, such as papi, you may need to reload the placeholders which will re-register them. Prison has been setup to survive a papi restart, but there could still be issues. + + +NOTE: Information on these command are provided in detail below. + + +
+ + +# Placeholder Types and Counts + +Prison has numerous placeholders, with number of different types. Each of these types have different internal requirements and conditions of usage. This is a high overview of the various types and their counts. + + +* **Total Available Placeholders:** 294 including aliases + + +* **Player Related:** 112 including aliases + * **Rank Related:** 8 including aliases + * **Rankup Related:** 20 including aliases + * **Player Balance Related:** 8 including aliases + * **Player Token Balance Related:** 12 including aliases + * **Player Blocks Totals Related: 4 including aliases + * **Player Tool Related:** 34 including aliases + * **Player Health Related:** 14 including aliases + * **Player XP and Levels Related:** 6 including aliases + * **Player Walk Speed:** 2 including aliases + + +* **Ladders Related:** 34 including aliases **times** each ladder + +> A LADDERS placeholder must include the ladder's name in the placeholder and therefore is static. + +> The ladder based placeholders end with `_laddername`, but they include the following possible prefixes, which may not be exclusive to ladder based placeholders. + +> Ladder placeholder prefixes: + * `prison_rank_` + * `prison_rankup_` + * `prison_player_` + + + +* **Ranks Related:** 24 including aliases **times** each rank + +> A RANKS placeholder needs to specify the Rank name as part of the placeholder. Each placeholder must specify a Rank and is static. + +> The ranks based placeholders end with `_rankname` but do not require a player to work. They also have a prefix of `prison_rank__` but these prefixes and suffixes are also shared with **RankPlayers** placeholders. See them for specifics. + +> Ranks placeholder prefixes: + * `prison_rank__` + + +* **RankPlayers Related:** 12 including aliases **times** each rank + +> A RANKPLAYERS placeholder is one that will change based upon the player's own Rank. Each player could have a different rank. Because of this relationship, these can only be used with instances of players such as scoreboards and chat prefixes; they will not work in holographic displays or with signs. + +> RankPlayers placeholders are very similar to the Rank placeholders in respect to the prefixes and suffixes, but these placeholders MUST include a player or they cannot work. Without a player, they cannot return a valid value, and therefore will return either a blank or zero. + +> What makes these placeholders stand out from rank placeholders is the prefix includes `player_`. For example: + +> RankPlayers placeholder prefixes: + * `prison_rank__player_` + + +> **Performance Warning:** There is a high risk of performance issues when calculating a full GUI page of items that includes the use of placeholders that are based upon the placeholders: `prison_rank__player_cost_rankname`. The reason for this is related to a progressively great number of calculations required to calculate high ranked prestige ranks. The performance impact can include processing and memory usages. + +> For example, if there are 26 default ranks, and the player is at rank A with no prestiges, then to calculate rank P4 would include the following ranks: +b --> z + p1 + a --> z + p2 + a --> z + p3 + a --> z + p4. +This results in a total of 107 ranks that must be collected, then the player's cost for each rank will have to be calculated. Then all of these must be added together to get the player's cost on rank P4. + +> So if there are thousands of prestige ranks, then the calculations will be numerous for each placeholder. + + +* **Player Ladder Balance Related:** 32 including aliases **times** each Mine + + +* **Mines Related:** 28 including aliases **times** each ladder + +> A MINES placeholder must specify the Mine mine as part of the placeholder. + +> The Mines related placeholders have the following prefixes, but they are also shared with the MinePlayers placeholders. +* `prison_mines_` +* `prison_top_mine_` + + + +* **MinePlayers Related:** 32 including aliases + +> A MINEPLAYERS placholder is similar to a RankPlayers placeholder in that it is dynamic and you cannot specify a mine's name with it. How it works, is that it provides the related stats for the mine in which the player is standing in. When the player leaves the mine, then these placeholders returns an empty string value (a blank). + +> The MinePLayers placeholders includ the following prefixes, but they are also similar to the Mines related placeholder too: + * `prison_player_` + * `prison_mines_` + + +* **PLAYERBLOCKS:** 4 including aliases + +> Every block type that a player breaks within a mine is tracked. These provide the stats on those blocks. + + +* **STATSMINES Related:** 18 including aliases + +> These list the blocks within a mine. They are referred to with a `_nnn_` notation where "nnn" is the line number + + +* **STATSRANKS Related:** 6 including aliases + +> Top-n stats for each rank. The rank name must be specified on the placeholder. + + +* **STATSPLAYERS:** 30 including aliases + +> Various placeholders for the top-n ranked players. These are over all ranks. There are a couple of shortcut placehodlders where one placeholders contain multiple fileds for easier usage. + + + +* **ONLY_DEFAULT_OR_PRESTIGES:** 4 including aliases + +> A couple of placeholders that will only include the default and prestige ladder's rank tag name. These are handy such that you only need to use the one, and it will ensure none of the other ladder's ranks will be included. + + + +* **CUSTOM:** Depends upon how many are configured on your server. + +> Custom placeholders allow for the creation of complex text that can include many other placeholders, including their placeholder attributes and other plugin placeholders. The benefit is that when using these in another plugin, you just need to use the short simple placeholder name and it will auto expand everything for you. + + + +
+ + +# Requirements + +There is always more than one way to do things, and the same goes for having more than one way to use placeholders. This documentation, and our test servers, primarily rely on the use of PlaceholderAPI as the core component to making placeholders work. Depending upon other plugins that you may use, they may have other dependencies too. + +**PlaceholderAPI** - [Setting up PlaceholderAPI](prison_docs_0xx_setting_up_PlaceholderAPI.md) - Strongly Suggested if using placeholders. + + +**Holographs** and **Scoreboards** - There are actual a couple of holograph display plugins. Most of the references in this document refer to Holographic Displays, but some of the newer plugins can provide the same functionality, plus many new features. + +Some of example of other holographic plugins are: AnimatedScoreboard, DecentHolograms, Scoreboard Revision, and etc.. + + +
+ + +# Placeholder Theory for Prison + +*(needs updating: Prison now has 10 types of placeholders including top-n variations)* + + +There are few major types of placeholders in prison: Player, Ranks, Ladders, Mines, and Stats based. With the most recent releases of prison, there have been hybrids added that are a combination of the player placeholders and with mines and ranks. For example there are now ladder based placeholder that allow targeting ranks on a specific ladder, instead of all ladders. Also there are player mine placeholders that report on the mine stats for the mine in which the player is physically located in. The player mine placeholders have no value when the player is not in a mine, and they will change as the player goes from mine to mine. + +There are also different types of data that are returned in placeholders. Text, numbers, formatted numbers, and bar graphs. + +The player based placeholders can only report on the player that is initiating the command, or request. These placeholders pertain to the player's attributes, such as rank, next rank, their balance, how more they need before reaching the next rank, and etc. Internally, all of these requests must include the player's UUID, which is why you cannot just add them to a sign, since the sign does not know any player's UUID. + +There are actually two major kinds of player based placeholders; a third type is "related" more to mines and not specifically to the player's ranks. Rank placeholders that returns all of the player's current attributes for all active ladders they are associated with. For example, if they are active on four ladders, then they will have four active ranks on four ladders with possible values. So it may look something like this: `[mod][Zeus][+2][B]`, of which the ladders could be mod, donor, prestige, and default. The thing to remember about player rank placeholders is that they may return more than one value, and you cannot control the order of the values. + +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. + +Prison has integrations for direct use of providing placeholder values to to the other plugins. Some of those other plugins request placeholder values using partial placeholder names. Therefore to improve performance and to prevent having to always reconstructing the full placeholder names, prison precomputes the fragments for all placeholders. Therefore, with our example of 40 mines and 10 placeholders, the actual internal number of placeholder combinations that prison will respond to is 800: 40 mines x 10 placeholders per mine x 2 for aliases = 800 placeholders for prison. + +Off hand this may sound bad, but Prison utilizes enumerations for identifying placeholders, so they may be objects, but they are lightweight and helps ensure placeholders align with the code at compile time. This not only provides better performance, and less memory consumption, but programming errors and typos are caught at compile time and not runtime, so they also provide for a more stable and reliable Prison environment. + +Internally, placeholders within Prison are case insensitive. But Prison uses lower cased placeholder names to register with any placeholder integration. Therefore, although prison may be case insensitive, the placeholder plugins may not recognize the placeholders unless you use them as all lower case names. + +Also, internally, prison only responds to the placeholder name without the escape characters. The escape characters are generally curly braces { }, or percents % %, but may be other characters. All placeholder plugins strip off the escape characters before passing anything to prison. So proper use of placeholders is dependent upon what is being required by your placeholder plugin and may require a mix of escape characters. + +
+ + +# Placeholder Attributes - Customize almost any Prison Placeholder + +*Since Prison v3.2.4-alpha.2* + + +Placeholders within prison can now be dynamically customized without having to make any changes to any configurations. The same placeholder can be used in multiple place, each with different configurations. This is now possible through the use of placeholder attributes and offers a large degree of customization. + + +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=<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. + + + +The following shows how a few placeholder need to have the "minename" replaced with the actual mine's name. For these examples, we will use a mine named **temp5**. + +* **prison_mines_size_minename** - `{prison_mines_size_temp5}` +* **prison_mines_remaining_minename** - `{prison_mines_remaining_temp5}` +* **prison_mines_remaining_bar_minename** - `{prison_mines_remaining_bar_temp5}` +* **prison_mines_timeleft_bar_minename** - `{prison_mines_timeleft_bar_temp5}` + + + +A few Examples using Placeholder Attributes: + +* `{prison_mines_size_temp5::nFormat:#,##0}` - **654,321** +* `{prison_mines_size_temp5::nFormat:#,##0:0:none}` - **654,321** +* `{prison_mines_size_temp5::nFormat:#,##0.00:1:kmg}` - **654.32 k** +* `{prison_mines_size_temp5::nFormat:#,##0:0:kmg}` - **654k** + + +* `{prison_mines_remaining_bar_temp5}` - Normally displays as (no color) + * **>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<** +* `{prison_mines_remaining_bar_temp5::bar:10}` - Using default values, but change length to 10 + * **>>>>>>>>><** +* `{prison_mines_remaining_bar_temp5::bar:10:&2:#:&d:-}` - Change all settings + * **#######---** +* `{prison_mines_timeleft_bar_temp5::bar:40:&2:O:&d:x:debug}` - Enable debug mode for the attribute + * **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: + + +The placeholder: `{prison_mines_timeleft_bar_temp5::bar:40:&2:O:&d:x:debug}` + +The full command: +`/prison placeholders test {prison_mines_timeleft_bar_temp5::bar:40:&2:O:&d:x:debug}` + + +Example of an attribute with debug + +When debug mode is enabled, it will print to the console information about the placeholder attribute, as seen in the above screen print. This could be useful when testing the configuration of placeholder attributes + + +Using the command `/prison placeholders test` should be used to test and perfect the use of the placeholder attributes. + +
+ + + +## Placeholder Attribute: nFormat - Numeric Formats + + +The Numeric Format attribute will only work on placeholders that return plain numbers. If there is a "_format" version of the placeholder, then an attribute will override the default formatting. + +Example of this attribute's usage is as follows, using descriptions for each parameter. + +`::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. Examples of + how the formatting can be used: + * #,### + * #,###.00 + * #,###.00000 + +- **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 the placeholder type that is used. + + * **none**: No display of units. No transformations. + * **kmg**: Uses one character units: kMGTPEZY. Transforms results by + dividing by 1000.0 until value is less than 1000.0, and + each time it increments the unit character. + k=1,000, M=1,000,000 and etc. These are metric SI codes. + * **kmbt**: Uses one character units: KMBTqQsS. Transforms results by + dividing by 1000.0 until value is less than 1000.0, and + each time it increments the unit character. + k=1,000, M=1,000,000 and etc. These are non-standard codes. + * **binary**: Uses a base-two divisor of 1024 along with the units: + KB, MB, GB, TB, PB, EB, ZB, and YB. + + * *Note:* Other unitTypes can be added along with different style of + 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 + 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. 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. + + + +The parameters that are optional do not have to be included, unless another parameter after the optional ones are needed. Then the optional parameter must be supplied and cannot be empty. + + +`{prison_mines_size_temp5::nFormat:#,##0.00:1:kmg}` + + + +Although it is not suggested to include color codes in the formatting of numbers, it may be possible with the addition of the quoting them with single quotes. The following use of **hex2** format works well with testing on a scoreboard that does not support hex colors, and is a way to inject the hex color when it cannot be used directly in the scoreboard configs. + +``` +{prison_mines_size_temp5::nFormat:'#af33ff'#,##0.00:1:kmg:hex} +{prison_mines_size_temp5::nFormat:'#af33ff'#,##0.00:1:kmg:hex2} +``` + + + +
+ + + + +## Placeholder Attribute: bar - Bar Graphs + + +The bar placeholder attribute only works with placeholders with the word bar in them. + + +Example of this attribute's usage is as follows, using descriptions for each parameter. + +`::bar:size:posColor:posSeg:negColor:negSeg:reverse:hex:hex2:debug:player=` + + + +- **bar**: the keyword to identify this attribute. +- **size**: The number of segments to generate. +- **Positive Color**: The color code to use for the positive segments. + Color codes should start with an &. +- **Positive Segment**: The value that will be used for the positive + segment. +- **Negative Color**: The color code to use for the negative segments. + Color codes should start with an &. +- **Negative Segment**: The value that will be used for the negative + segment. + + +- **reverse**: **Optional.** Case sensitive. Non-positional; can be placed anywhere. + When enabled, this will reverse the bar graph. + + +- **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. 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. + + + +The parameters are all optional and if they are not supplied then the default values for the bar graph will be used instead. + +`{prison_mines_remaining_bar_temp5::bar:10}` + +`{prison_mines_remaining_bar_temp5::bar:10:&2:#:&d:-}` + +`{prison_mines_timeleft_bar_temp5::bar:40:&2:O:&d:x:debug}` + + +To use hex color codes within the bar graphs, the plugins that are requesting them, may not always support hex colors. So the options of **hex** and **hex2** are options to provide pre-formatting of the hex colors so that way the hex colors could work with plugins that do not support them. If the use of **hex** does not work, then **hex2** may. + + +Examples of using hex color codes in a bar graph placeholder. Try it first with **hex**, and if that does not work, then try **hex2**. + +``` +{prison_mines_timeleft_bar_a::bar:15:#abcdef:O:#5a3c7f:x:hex} +{prison_mines_timeleft_bar_a::bar:15:#abcdef:O:#5a3c7f:x:hex2} +``` + + + +
+ + + + +## Placeholder Attribute: text - Text + + +This placeholder attribute is for text formatting the placeholder results. The only thing it does is to process the hex, hex2, and debug options. + + +This placeholder attribute can be used with any placeholder, even for placeholders +that have other attributes to format their content. Since this is strictly processing +the hex color codes, it will operate upon the final text output from the other +placeholders. + + + +Example of this attribute's usage is as follows, using descriptions for each parameter. + +`::text:hex:hex2:debug:player=` + + + +- **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. 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. + + + + +
+ + +# Prison's Custom Placeholders + + +Have you ever tried to setup one row in a scoreboard that included three or four placeholders? Did any of them include placeholder attributes? Some scoreboards even impose limits on how many characters you can use in the config settings. + +With Prison's new Custom Placeholders, you can define any number of them within the prison's `config.yml` file, and then use just the custom placeholder's short name. Prison will automatically expand all included placeholders, even non-prison placeholders. + + +
+ +### Custom Placeholder Configurations + +Prison's custom placeholders are defined in the `plugins/Prison/config.yml` file, under the grouping of `placeholder`. + + +```yaml +placeholder: + + # Custom Placeholders: + # They MUST begin with 'prison__', which has two underscores, or they will not work. + # Custom placeholders can have an abbreviated format where it is the placeholder + # with the quoted value, which can be multi-lined. + # The extended format can have additonal settings. The actual placeholder is + # paired with 'placeholder'. + # If the custom placeholder contains non-prison placeholders, then you can set + # the 'papi_expansion' to true. + # If a description is provided, it will be shown within the placeholder listing. + # Note that the use of hex colors will not work with bukkit versions prior to + # spigot 1.14. + custom-placeholders: + prison__chat_prefix: + placeholder: "{prison_rank_tag_default}{prison_rank_tag_prestiges}" + papi_expansion: true + description: "Can use this in your chat prefix. May have to use %% instead of {}." + prison__player_stats: "{prison_rank_tag_default} -> {prison_rankup_rank_tag_default} + {prison_rankup_cost_remaining_bar_default::bar:50:&a:|:&d:|} + {prison_rankup_cost_remaining_formatted_default} needed to rankup" + +# Pre-spigot 1.14: Cannot do RGB colors: + prison__branding_pre_1_14: "&2P&3r&4o &5M&6i&4n&3e&2s" + + prison__branding: "&#e81416P&#ffa500r&#faeb36o + Oc314Mǧde7ib369dn𑋡de&#ac7ad1s" + +``` + + +
+ + +### Custom Placeholders Format - Name + +A custom placeholder is only identified as a custom placeholder by the prefix of it's name. Therefore, all custom placeholders must start with `prison__`. That is two underscores. If it does not have two underscores, it will be ignored. + +The remainder of the custom placeholder's name can be any valid character combination, excluding any white space. We strongly suggest it is kept to alpha-numeric with underscores. But you may be able to use dashes, other symbols, including colons. If you try to use something other than alpha-numeric plus underscores, then do so at your own risk because other plugins, including Prison, may not handle them correctly or successfully. + + +
+ + +#### Custom Placeholders Format - Abbreviated (simple) + +The abbreviated form of a custom placeholder is simply the name of the placeholder, followed by the String value. + +Two examples are as follows, where the first is a one liner, and the other is a multi-line example. + +```yaml +placeholder: + custom-placeholders: + prison__branding: "&2P&3r&4o &5M&6i&4n&3e&2s" + prison__multi_line: "This is a simple example with + no placeholders, but it's on multiple lines + as this placeholder implies." + +``` + +Please note that multi-line String values wraps to the next line, indented two character more than the placeholder's name. + + +
+ + +#### Custom Placeholders Format - Expanded (complex) + +The complex form of a custom placeholder has at least one attribute, and potentially other settings that can expand the functionality of a placeholder. + +**placeholder** attribute - This contains the actual placeholder String value. It can be multiple lines in length, and can have none, or many other placeholders in it. + +**papi_expansion** attribute - Defaults to a value of `false`. If this value is `true`, then after prison expands all prison placeholders, Prison will then have PAPI expand all non-prison placeholders. If a non-prison placeholder is used in the abbreviated placeholders, or if this one is set to `false`, then it will be ignored and you may see it displayed in the final text. + +**description** attribute - This is a description of the custom placeholder, which is optional. It is ONLY displayed in the placeholder listings: `/prison placeholders list` + + +Two examples are as follows, where the first is a one liner, and the other is a multi-line example. + +```yaml +placeholder: + custom-placeholders: + prison__branding: "&2P&3r&4o &5M&6i&4n&3e&2s" + prison__chat_prefix: + placeholder: "{prison_rank_tag_default}{prison_rank_tag_prestiges}: &3{player}:&r" + papi_expansion: true + description: "Can use this in your chat prefix. May have to use %% instead of {}." + +``` + +Please note that multi-line String values wraps to the next line, indented two character more than the placeholder's name. + + +
+ + + +# Prison Command Placeholders - Mines, Ranks, Ladders, and Block Commands + +This document is not intended to cover Prison command placeholders, but within Prison there are many areas where you can setup commands. Each of them have their own set of placeholders. Prison supports many placeholders to allow you to better customize command. + +The commands can contain more than one command. Keep them all on one line, but end each command with a semi-colon: `;`. + + +To see the list of placeholders, most commands have command parameter that will show all of them. This is a list of all of these commands, and their related placeholders. Please run these commands in the console, for yourself, to confirm that there have not been any new updates since this document was last updated. + +Keep in mind that the use of these placeholder are very strict. They include the curly braces, and they must be in case in which they are listed. + +`/ranks command add placeholders` + +**{player} {player_uid} {msg} {broadcast} {title} {actionBar} {inline} {inlinePlayer} {sync} {syncPlayer} {range: } {ifPerm:} {ifNotPerm:} {firstJoin} {promote} {demote} {balanceInitial} {balanceFinal} {currency} {originalRankCost} {rankupCost} {ladder} {rank} {rankTag} {targetRank} {targetRankTag}** + +`/ranks ladder command add placeholders` + +**{player} {player_uid} {msg} {broadcast} {title} {actionBar} {inline} {inlinePlayer} {sync} {syncPlayer} {range: } {ifPerm:} {ifNotPerm:} {firstJoin} {promote} {demote} {balanceInitial} {balanceFinal} {currency} {originalRankCost} {rankupCost} {ladder} {rank} {rankTag} {targetRank} {targetRankTag}** + +`/mines command add placeholders` + +**{player} {player_uid} {msg} {broadcast} {title} {actionBar} {inline} {inlinePlayer} {sync} {syncPlayer} {range: } {ifPerm:} {ifNotPerm:}** + +`/mines blockevent add placeholders` + +**{player} {player_uid} {msg} {broadcast} {title} {actionBar} {inline} {inlinePlayer} {sync} {syncPlayer} {range: } {ifPerm:} {ifNotPerm:} {blockName} {mineName} {locationWorld} {locationX} {locationY} {locationZ} {coordinates} {worldCoordinates} {blockCoordinates} {blockChance} {blockIsAir} {blocksPlaced} {blockRemaining} {blocksMinedTotal} {mineBlocksRemaining} {mineBlocksRemainingPercent} {mineBlocksTotalMined} {mineBlocksSize} {blockMinedName} {blockMinedNameFormal} {blockMinedBlockType} {eventType} {eventTriggered} {utilsDecay}** + + + + +#### Prison Command Placeholder Descriptions + + +Detailed information on what exactly each of these placeholders do, is not intended to be a part of this document. But the following is a brief description. + +Additional information on the BlockEvent placeholders can be found in the [BlockEvent documentation](prison_docs_115_using_BlockEvents.md). + +If a placeholder is marked with **Non-Positional**, that means that the placeholder can appear anywhere in the command to trigger the effect. It's non-positional since it's removed when detected, therefore when the command is ran, it will not be encountered. + + +* **{player}** - The player's name. +* **{player_uid}** - The player's UUID. +* **{msg}** - Send a message to the player. The message follows this placeholder. +* **{broadcast}** - Broadcast a message to all players on the server. +* **{title}** - Send a message to the player, but show in the screen's title region. +* **{actionBar}** - Send a message to the player, but show in the action bar. + + +* **{inline}** - Run the command "inline" with the processing of the original prison command, but run as console. **Non-Postional.** +* **{inlinePlayer}** - Run the command "inline" with the processing of the original prison command, but run the command as the player. **Non-Postional.** +* **{sync}** - Submit the command to run in a synchronous thread at the first opportunity. This runs the command as console. Since the command is submitted, it may have to wait behind other tasks. **Non-Postional.** +* **{syncPlayer}** - Submit the command to run in a synchronous thread at the first opportunity. This runs the command as the player; if the player does not have access to run the specified command, then it will fail. Since the command is submitted, it may have to wait behind other tasks. **Non-Postional.** + + +* **{range: }** - This is a global placeholder that will insert an integer value that is randomly selected from the specified range from to , inclusive of the high value. So `{range: 5 7}` would have possible values of 5, 6, and 7. These randomly selected values are not weighted and may not present an even distribution. Negative values are also supported too. + + +* **{ifPerm:};** - Runs the commands that follows this placeholder, only if the player has the specified permission. NOTE: In order for this to work properly, it must be immediately be followed by a semi-colon so it's treated as it's own "command". +* **{ifNotPerm:};** - Runs the commands that follows this placeholder, but only if the player DOES NOT have the specified permission. NOTE: In order for this to work properly, it must be immediately be followed by a semi-colon so it's treated as it's own "command". + + +* **{firstJoin}** - Runs the commands that follows this placeholder, only if the rankup is based upon first join. This protects the commands that follows from being ran each time when the player hits the specified rank in the future. Example would be Rank A's command such that it runs on first join, but it will not run when the player prestiges and they are set back to A on the default ladder. **Non-Positional.** + + +* **{promote}** - This runs the command only on promotions such as rankup, promote, and setRank. **Non-Positional.** +* **{demote}** - This runs the command only on demotions such as demote. **Non-Positional.**c + + +* **{balanceInitial}** - The player's balance before the rankup event was ran. +* **{balanceFinal}** - The player's balance after the rankup event was ran. +* **{targetRank}** - The next rank's name. +* **{targetRankTag}** - The next ranks's tag value. +* **{currency}** - If the rank is using a different currency, then this parameter would provide the name of that currency. +* **{originalRankCost}** - The rank cost for ranking up, but without the global rank cost multipliers. +* **{rankupCost}** - The rank cost for ranking up, including the global rank cost multipliers. +* **{ladder}** - The current ladder name. +* **{rank}** - The current rank name. +* **{rankTag}** - The current rank's tag value. + +* **{blockName}** - The name of the block that was mined. +* **{mineName}** - The mine where the block was mined. +* **{locationWorld}** - The world name where the mine exists. + + + +* **{locationX}** - The **X** coordinates for the broken block. This is an integer value. +* **{locationY}** - The **Y** coordinates for the broken block. This is an integer value. +* **{locationZ}** - The **Z** coordinates for the broken block. This is an integer value. + + +* **{coordinates}** - This provides the X, Y, and Z coordinates for the broken block. These are double values, surrounded by parenthesis and separated by commas. Format: **(X,Y,Z)** Example: `(183.2,88.3792,-3828.248)` +* **{blockCoordinates}** - This is similar to the **{coordinates}** placeholder, except for the use of integer values. Format: **(blockName,world,X,Y,Z)** Example: `(,prisonWorld,183,88,-3828)` +* **{worldCoordinates}** - This combines both the **{locationWorld}** and **{blockCoordinates}** placeholder in to one placeholder. The coordinates are integer values. Format: **(world,X,Y,Z)** Example: `(prisonWorld,183,88,-3828)` + + +* **{blockChance}** - For the block type that was mined, what was the chance of it's spawn rate. +* **{blockIsAir}** - Indicates if the block being processed was AIR. This could be true if an included block within an explosion was already replaced with AIR. +* **{blocksPlaced}** - +* **{blockRemaining}** - +* **{blocksMinedTotal}** - +* **{mineBlocksRemaining}** - +* **{mineBlocksRemainingPercent}** - +* **{mineBlocksTotalMined}** - +* **{mineBlocksSize}** - +* **{blockMinedName}** - +* **{blockMinedNameFormal}** - +* **{blockMinedBlockType}** - +* **{eventType}** - This contains the name of the event that prison is handling. This is an internal event name as specified by Prison. +* **{eventTriggered}** - If Prison was handling a multi-block event, such as an explosion, and if that event supports identifying what triggered it, then this will contain that information. Example could be what enchantment was used to produce the explosion, or the name of the potion, etc. +* **{utilsDecay}** - + + + +This is mentioned here since these rank command placeholders are not part of all the other placeholders, so as such, it may be difficult to find information for these items. + + + +
+ + + + +# Prison Placeholder Command Listing + + +Prison Placeholder Commands + +Example of placeholder command listings + + +

Prison Placeholder Listings

+ +Prison Placeholder Listing +Prison Placeholder Listing + +Example of the list of placeholders that is available through **/prison placeholders list**. Please note that this list may evolve as new placeholders are added. Use these commands to get the current listing that is available on your server. + + +

Prison Placeholder Search with Two Search Patterns

+ + +Prison Placeholder Search + +This is an example of searching for placeholders using a player's name plus two search patterns: *temp5* and *format*. The term temp5 is the name of a mine and is an example of a the dynamic construction of placeholders, and that you can still perform a search with them. The search patterns can be any String fragment found in either the placeholder, or it's alias. + +If more than one search pattern is provided, then all patters must hit on the same placeholder to be included in the results. They behave as a logical AND relationship. + +A player's is provided, but results do not include any player, rank, or ladder entries. This shows that if a player's name is provide, it is recognized as a player and will not prevent valid hits. + + +The following example shows what the command is like when specifying the player's name, a page numer for the results, and three search parameters: + +``` +/prison placeholders search RoyalCoffeeBeans 1 rankup cost default +``` + +This example shows the current placeholder values for that player, including an example of a bar graph. + +Prison Placeholder Search + + +

Prison Placeholder Listings - All Placeholders

+ +Prison Placeholder Listing + +In this contrived example, since all placeholders begin with "prison", this search returns a listing of all placeholders. In this example, using the current Prison v3.2.1-alpha.13 release, it has generated 65 pages of results, at 6 placeholders per page which includes the alias. + +The following shows an example of all placeholders that are active with Prison_v3.2.2-alpha.10.jar. It includes a total of 1,294 placeholders, on 108 pages. This is based upon 4 ladders, 13 ranks, and 41 mines. + + +Prison Placeholder Listing + + + + +

Prison Placeholder Listings

+ +Prison Placeholder Listing + + + +
+ + +# Chat Placeholders + +There are two major ways a placeholder can be resolved within Prison: through chat or through a placeholder integration. + +Chat based placeholders do not rely on other plugins for them to work. Instead they use the org.bukkit.event.player.AsyncPlayerChatEvent, of which Prison will respond and provide translations to prison related placeholders that it find with the chat message. + +Although no plugin is required for Prison to properly handle chat based placeholders, other plugins may be required to generate their use. Such as EssentialsX's Chat plugin. It provides a way to prefix chat messages with placeholders. + + + +
+ + + +# Enabling EssentialX's Chat Placeholders + +Set up the EssentialX's Chat plugin: [Setting up EssentialsX](prison_docs_0xx_setting_up_EssentialsX.md). + +Enabling the chat placeholder just requires editing one line within the `config.yml` file. Search for the keyword **EssentialsChat** in that file, then edit the `format:` tag. For example: + + format: '<{prison_rank_tag}:{DISPLAYNAME}>{MESSAGE}' + +Once setup, restart the server. Or use **/essentials reload**. Do not force all the plugins to be reloaded with a tool such as plugman since Prison (and other plugins) may fail to re-load properly. + + +This will include all placeholders that are active for the player, including the prestige chat prefixes. The only issue is that you cannot control the order of how they will display. + + +It is possible to manually set the order by using the individual placeholders for each rank you want to show. This allows you to omit certain placeholders too. Please see the next section of this document to learn how to set them up. + + +You can preview all of the placeholders with the placeholder search command. + + +``` +/prison placeholder search rank_tag + +/prison placeholder search RoyalCoffeeBeans rank_tag +/prison placeholder search RoyalCoffeeBeans 2 rank_tag +``` + + +Reviewing all placeholder tags + + +The placeholders are interested in are: `prison_rank_tag_pretiges` and `prison_rank_tag_default`. + + +So to set them up in the EsstentialsX Chat prefix would be as follows: + + + format: '<{prison_rank_tag_prestiges}{prison_rank_tag_default}:{DISPLAYNAME}>{MESSAGE}' + + + +

Ladder Specific Placeholders

+ +One of the newer features available for placeholders has to do with ladder specific placeholders. This is similar to the mines placeholders but for ladders specifically. These player ladder placeholders are just the same a the player rank, but only for one ladder. The player rank placeholders will return all ranks on all ladders for that placeholder. + +This is an example of specifying the rank tag for both the prestige and default ladder. This ensures the expected order of these two tags, but it will also exclude other tags from other ladders, such as donor ladders or mod ladders. + + format: '<{prison_rank_tag_prestiges}{prison_rt_default}:{DISPLAYNAME}>{MESSAGE}' + + +Use the placeholder tools under `/prison placeholders` for more information and to see what is available for use. + + + +For example, to preview all of the placeholders with the placeholder search command. + + +``` +/prison placeholder search rank_tag + +/prison placeholder search RoyalCoffeeBeans rank_tag +/prison placeholder search RoyalCoffeeBeans 2 rank_tag +``` + + +Reviewing all placeholder tags + + + + +
+ + + + +# Enabling HolographicDisplays Placeholders + +Follow directions on how to install and configure the HolographicDisplays plugin. + + +An important detail to realize, is that HolographicDisplays can only use placeholders that related to the server. It cannot access any of the prison placeholders on its own. It needs the help of other plugins to extend it's functionality. + +* [HolographicDisplays Download](https://dev.bukkit.org/projects/holographic-displays) +* [HolographicDisplays' Documentation](https://filoghost.me/docs/holographic-displays) + +* [HolographicExtension](https://www.spigotmc.org/resources/holographicextension.18461/) +* [PlaceholderAPI Setup Details](prison_docs_0xx_setting_up_PlaceholderAPI.md) +* [ProtocolLib](https://www.spigotmc.org/resources/protocollib.1997/) + +The simple directions on how to get everything to work is to download these plugins, and place them all in to your server's plugin directory. There is no need to modify any config files to get them to work with prison. Prison will register all of the internal placeholders with PlaceholderAPI so it knows they are valid and where to find them (where to send them to be resolved). + +The simplest way to create a HolographicDisplay would be to stand where you want one. Then enter the following command: + +``` +/hd create test +``` + +Then on the server file system, open the file: + +``` +plugins\HolographicDisplays\database.yml +``` + +Then edit the file. Keep in mind it is a yml file and must be valid yml. + +This is an example of a holographic sign: + +``` +temp5: + location: world, -99.832, 74.500, 191.215 + lines: + - 'Welcome to Prison Mine: temp5' + - 'Reset Interval: {slowest}%prison_mines_interval_temp5% - {slowest}%prison_mines_interval_formatted_temp5%' + - 'Reset Time Left: {medium}%prison_mines_timeleft_temp5% - {fast}%prison_mtlf_temp5%' + - 'Reset Time Left: {slowest}%prison_mines_timeleft_bar_temp5%' + - 'Reset Count: {medium}%prison_mines_reset_count_temp5%' + - 'Mine Size: {slowest}%prison_mines_size_temp5%' + - 'Blocks Remaining: {slowest}%prison_mr_temp5% {slowest}%prison_mp_temp5%%' + - 'Players in Mine: {slowest}%prison_mines_player_count_temp5%' +``` + +Notice that the prison placeholders are wrapped in the % % escape characters. The prefixed placeholders such as {slowest} and {fast} are for the plugin HolographicExtensions and they control how frequently the placeholders are refreshed. + +This is an example of the above settings, including the bar graph. Notice that the bar graph's properties can be adjusted for both the characters that are used, and the total number of characters (width). See the configuration within the file `/plugins/Prison/config.yml`. +Prison Holographic Displays + + +Once you update and save the database.yml file, you can have HolographicDisaplys reload from the files: + +``` +/hd reload +``` + +The above example will produce a holograph that is too tall and the bottom part will be underground. You can raise it up by manually increasing the **Y** value stored in *location:*. As you raise it up, and save the file, then you use **/hd reload** to refresh. It's also easier to make changes directly to the database.yml file. Repeat until it looks right. + + +One word of warning about editing the yml file, is that it must be valid yml, if not, then it could fail to load, or it may reset to a default file. If you're unsure about the file being proper yml, make sure you save a backup before trying to reload the HolographicDisplays settings. You can also run it through an online yml validator to fix any issues. To find an online yml validator, search for: "online yaml lint" or "online yaml validator". + + + + + +
+ + From 1faa4532a6c5b0d73a74819a2cd24f2eb7d1ab01 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 15 Feb 2025 05:38:56 -0500 Subject: [PATCH 243/323] 2025-02-08: v3.3.0-alpha.19f --- docs/changelog_v3.3.x.md | 13 +++++++++++++ gradle.properties | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 82008b568..e254aca30 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,19 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.19e 2025-02-08 +# 3.3.0-alpha.19f 2025-02-08 + +* Support for spigot/paper v1.21.4 +* Bug fix: NBT-lib. If NBT-lib fails, prison no longer allows the stacktrace to fill the console/logs. This library needs to be updated with each release of paper/spigot and when it is out of date it can throw a lot of errors. +* New prison command placeholder: `{range: }`. Can be used in rank commands, mine commands, ladder commands, and even Block event commands. This can help insert a random number in your commands, such as a random number of items that you may give a player. +* Bug fix: Players when reloading players, or on server startup, player's ranks could have been reset. This fixes that issue. +* Bug fix: Rankups. Changes to how internal references to players caused some problems on some commands by not returning the correct player objects. See next item. +* Bug fix and enhancement: There was an issue with how prison would get player objects from bukkit. It generally wasn't a problem, unless you had over a few thousand players. The problem was that prison would get OfflinePLayers from bukkit, and that would cause bukkit to lag the server badly since it would consume a lot of resources and time trying to find player files within the bukkit world folders. Prison no longer asks for OfflinePlayers. Prison was tested with 35,000 + players and the issue is now resolved. +* Sellall and Blocks: Updated some of the internals in sellall to be able to better support custom blocks that have been added to sellall, but are not within prison. Prison cannot spawn these blocks, but it can sell them now. +* + + + * **Placeholders: Updated the docs to include the new command placeholder: '{range: }'** diff --git a/gradle.properties b/gradle.properties index a70ffb933..f09a18642 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.19e +version=3.3.0-alpha.19f From ff02629d06501ca77cc387d7eb7702f8d0d5fc36 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 15 Feb 2025 05:45:11 -0500 Subject: [PATCH 244/323] Prison debug: Add a 'commandHandler' to the debugger activeTargets so that way you can selectively enable a commandHandler log message outside of if debug is enabled or not. This is to troubleshoot if bukkit is actually passing commands to prison correctly. --- docs/changelog_v3.3.x.md | 9 ++++- .../prison/commands/CommandHandler.java | 2 +- .../prison/commands/RegisteredCommand.java | 38 ++++++++++++++++++- .../tech/mcprison/prison/output/Output.java | 16 +++++++- .../mcprison/prison/spigot/SpigotPrison.java | 13 ++++++- 5 files changed, 71 insertions(+), 7 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index e254aca30..26027e96a 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,10 +14,15 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.19e 2025-02-08 +# 3.3.0-alpha.19f 2025-02-15 -# 3.3.0-alpha.19f 2025-02-08 +* **Prison debug: Add a 'commandHandler' to the debugger activeTargets so that way you can selectively enable a commandHandler log message outside of if debug is enabled or not.** +This is to troubleshoot if bukkit is actually passing commands to prison correctly. + + + +## 3.3.0-alpha.19f 2025-02-15 * Support for spigot/paper v1.21.4 * Bug fix: NBT-lib. If NBT-lib fails, prison no longer allows the stacktrace to fill the console/logs. This library needs to be updated with each release of paper/spigot and when it is out of date it can throw a lot of errors. diff --git a/prison-core/src/main/java/tech/mcprison/prison/commands/CommandHandler.java b/prison-core/src/main/java/tech/mcprison/prison/commands/CommandHandler.java index c30b7f975..00a1e5822 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/commands/CommandHandler.java +++ b/prison-core/src/main/java/tech/mcprison/prison/commands/CommandHandler.java @@ -983,7 +983,7 @@ else if ( !hasCommandAccess( sender, rootCommand, label, args ) ) { else { try { - rootCommand.execute(sender, args); + rootCommand.execute( sender, args ); } catch ( Exception e ) { String message = "Prison CommandHander: onCommand: " + e.getMessage() + diff --git a/prison-core/src/main/java/tech/mcprison/prison/commands/RegisteredCommand.java b/prison-core/src/main/java/tech/mcprison/prison/commands/RegisteredCommand.java index f8deaecf7..36866df7f 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/commands/RegisteredCommand.java +++ b/prison-core/src/main/java/tech/mcprison/prison/commands/RegisteredCommand.java @@ -32,6 +32,7 @@ import tech.mcprison.prison.output.ChatDisplay; import tech.mcprison.prison.output.LogLevel; import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.output.Output.DebugTarget; public class RegisteredCommand @@ -160,12 +161,47 @@ public String getCompleteLabel() { * @param args */ protected void execute(CommandSender sender, String[] args) { + execute( sender, args, true ); + } + protected void execute(CommandSender sender, String[] args, boolean allowDebug ) { + + // Only enable debug mode if the selective debug target is commandHanlder. + // To enable this use ... + boolean debug = Output.get().isActiveTarget( DebugTarget.commandHandler ); // First ensure the player is not locked out of this command: if ( !handler.hasCommandAccess(sender, this, getLabel(), args) ) { + + if ( debug ) { + String argz = ""; + for (String arg : args) { + argz += arg + " "; + } + + String msg = String.format( + "RegisteredCommand.execute: Player %s does not have access to a command: [%s]", + sender.getName(), + (getLabel() + " " + argz).trim() + ); + Output.get().logInfo( msg ); + } return; } + if ( debug ) { + String argz = ""; + for (String arg : args) { + argz += arg + " "; + } + + String msg = String.format( + "RegisteredCommand.execute: Player %s is attempting to run command: [%s]", + sender.getName(), + (getLabel() + " " + argz).trim() + ); + Output.get().logInfo( msg ); + } + if (!testPermission(sender)) { Prison.get().getLocaleManager().getLocalizable("noPermission") .sendTo(sender, LogLevel.ERROR); @@ -202,7 +238,7 @@ protected void execute(CommandSender sender, String[] args) { // Strip first arg, then recursively try again String[] nargs = new String[args.length - 1]; System.arraycopy(args, 1, nargs, 0, args.length - 1); - command.execute( sender, nargs ); + command.execute( sender, nargs, false ); } } else { 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 04887921f..845fad982 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 @@ -83,7 +83,9 @@ public enum DebugTarget { rankup, // support - blockConstraints + blockConstraints, + + commandHandler ; public static DebugTarget fromString( String target ) { @@ -617,6 +619,18 @@ public boolean isSelectiveTarget( DebugTarget debugTarget ) { return getSelectiveDebugTargets().contains( debugTarget ); } + /** + *

This will return a value of true if the debug target was + * enabled by the admin/console. + *

+ * + * @param debugTarget + * @return + */ + public boolean isActiveTarget( DebugTarget debugTarget ) { + return getActiveDebugTargets().contains( debugTarget ); + } + public boolean isDebug() { return debug; } 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 2093a1498..7428b8dac 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 @@ -938,15 +938,24 @@ private void initDataDir() { } } + /** + * This will initialize the two fields, commandMap and knownCommands, which are from the + * Bukkit server. These will give prison's command handler the ability to easily access + * these fields, which are not normally accessible. + */ private void initCommandMap() { try { commandMap = Bukkit.getServer().getClass().getDeclaredField("commandMap"); commandMap.setAccessible(true); + knownCommands = SimpleCommandMap.class.getDeclaredField("knownCommands"); knownCommands.setAccessible(true); - } catch (NoSuchFieldException e) { + } + catch (NoSuchFieldException e) { getLogger().severe( - "&c&lReflection error: &7Ensure that you're using the latest version of Spigot and Prison."); + "&c&lReflection error: &7Ensure that you're using the latest version of Spigot and Prison. " + + "Unable to access Bukkit.getServer().commandMap field. " + + "or the org.bukkit.command.SimpleCommandMap.knownCommands field."); e.printStackTrace(); } } From 8c390a3c0c6ccd03379f9ac6ba17ea2354e83324 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 15 Feb 2025 05:49:43 -0500 Subject: [PATCH 245/323] Rankupmax broadcast bug: Sending the console log message to all players and the player too. Now sends the broadcast message that is associated with the normal rankup command. --- docs/changelog_v3.3.x.md | 5 +++ .../ranks/commands/RankUpCommandMessages.java | 43 +++++++++++++++++-- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 26027e96a..f01bde962 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.19f 2025-02-15 +* **Rankupmax broadcast bug: Sending the console log message to all players and the player too.** +Now sends the broadcast message that is associated with the normal rankup command. + + + * **Prison debug: Add a 'commandHandler' to the debugger activeTargets so that way you can selectively enable a commandHandler log message outside of if debug is enabled or not.** This is to troubleshoot if bukkit is actually passing commands to prison correctly. diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RankUpCommandMessages.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RankUpCommandMessages.java index 2b12a2ca6..b3107a1fc 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RankUpCommandMessages.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RankUpCommandMessages.java @@ -405,16 +405,53 @@ protected void ranksRankupMaxSuccessMsg( CommandSender sender, StringBuilder ran // Print to console for record: Output.get().logInfo( localManagerLog.localize() ); + String messageId = "ranks_rankup__rankup_success" ; + +// String messagNoPlayerName = PrisonRanks.getInstance().getRanksMessages() +// .getLocalizable( "ranks_rankup__rankup_no_player_name" ).localize(); + + + + String messagNoPlayerNameBroadcast = PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( "ranks_rankup__rankup_no_player_name_broadcast" ).localize(); if ( Prison.get().getPlatform().getConfigBooleanFalse( "broadcast-rankups" ) ) { - localManagerLog.broadcast( rPlayer ); - + PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( messageId ) + .withReplacements( + + (rPlayer.getName() == null ? messagNoPlayerNameBroadcast : rPlayer.getName() ), + ranks.toString(), + "" // no message - do not have anything configured for rankupmax on this? + ) + .broadcast( rPlayer ); } else { - localManagerLog.sendTo( sender, rPlayer ); + Localizable localManager = PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( messageId ) + .withReplacements( + + (rPlayer.getName() == null ? messagNoPlayerNameBroadcast : rPlayer.getName() ), + ranks.toString(), + "" // no message - do not have anything configured for rankupmax on this? + + ); + + localManager.sendTo( sender, rPlayer ); } + + +// if ( Prison.get().getPlatform().getConfigBooleanFalse( "broadcast-rankups" ) ) { +// +// localManagerLog.broadcast( rPlayer ); +// +// } +// else { +// +// localManagerLog.sendTo( sender, rPlayer ); +// } } protected void ranksRankupCannotAffordMsg( CommandSender sender, From b4e3db6202567c6cea1cc24b832b23183c4d885b Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 15 Feb 2025 06:30:37 -0500 Subject: [PATCH 246/323] RankupMax: Fix a bug where after successfully ranking up a few ranks, it always shows an error message related to the last attempt because the player cannot afford the next rank. --- docs/changelog_v3.3.x.md | 3 +++ .../prison/ranks/commands/RankUpCommand.java | 26 ++++++++++++------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index f01bde962..b1257e4b1 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.19f 2025-02-15 +* **RankupMax: Fix a bug where after successfully ranking up a few ranks, it always shows an error message related to the last attempt because the player cannot afford the next rank.** + + * **Rankupmax broadcast bug: Sending the console log message to all players and the player too.** Now sends the broadcast message that is associated with the normal rankup command. 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 8c4896ed0..f831ca2c2 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 @@ -793,7 +793,7 @@ private boolean rankUpPrivate(CommandSender sender, // sender.getName(), cmdTasks ); - processResults( sender, rankPlayer.getName(), results, null, ladder, currency, sbRanks ); + processResults( sender, rankPlayer.getName(), results, null, ladder, currency, sbRanks, mode ); // If the last rankup attempt was successful and they are trying to rankup as many times as possible: // Note they used to restrict rankupmax from working on prestige ladder... @@ -1029,7 +1029,7 @@ public void promotePlayer(CommandSender sender, // submit cmdTasks... submitCmdTasks( rPlayer, cmdTasks ); - processResults( sender, rPlayer.getName(), results, null, ladder, currency, null ); + processResults( sender, rPlayer.getName(), results, null, ladder, currency, null, RankupModes.ONE_RANK ); } else { @@ -1112,7 +1112,7 @@ public void demotePlayer(CommandSender sender, // submit cmdTasks submitCmdTasks( rPlayer, cmdTasks ); - processResults( sender, rPlayer.getName(), results, null, ladder, currency, null ); + processResults( sender, rPlayer.getName(), results, null, ladder, currency, null, RankupModes.ONE_RANK ); } else { @@ -1205,7 +1205,7 @@ public void setPlayerRank( RankPlayer rankPlayer, Rank pRank ) { processResults( rankPlayer, rankPlayer.getName(), results, pRank.getName(), pRank.getLadder().getName(), - pRank.getCurrency(), null ); + pRank.getCurrency(), null, RankupModes.ONE_RANK ); } } @@ -1234,7 +1234,7 @@ public void setPlayerRankFirstJoin( RankPlayer rankPlayer, Rank pRank ) { processResults( rankPlayer, rankPlayer.getName(), results, pRank.getName(), pRank.getLadder().getName(), - pRank.getCurrency(), null ); + pRank.getCurrency(), null, RankupModes.ONE_RANK ); } } @@ -1253,7 +1253,7 @@ private void setPlayerRank( RankPlayer rankPlayer, RankLadder ladder, Rank pRank processResults( sender, rankPlayer.getName(), results, pRank.getName(), ladder.getName(), - currency, sbRanks ); + currency, sbRanks, RankupModes.ONE_RANK ); } @@ -1283,7 +1283,7 @@ private void setPlayerRank( RankPlayer rankPlayer, String rank, String ladderNam // submit cmdTasks submitCmdTasks( rankPlayer, cmdTasks ); - processResults( sender, rankPlayer.getName(), results, rank, ladderName, currency, null ); + processResults( sender, rankPlayer.getName(), results, rank, ladderName, currency, null, RankupModes.ONE_RANK ); } } @@ -1333,7 +1333,8 @@ public RankPlayer getRankPlayer( CommandSender sender, UUID playerUuid, String p public void processResults( CommandSender sender, String playerName, RankupResults results, String rank, String ladder, String currency, - StringBuilder sbRanks ) { + StringBuilder sbRanks, + RankupModes mode ) { switch (results.getStatus()) { case RANKUP_SUCCESS: @@ -1347,7 +1348,14 @@ public void processResults( CommandSender sender, String playerName, break; case RANKUP_CANT_AFFORD: - ranksRankupCannotAffordMsg( sender, results ); + + // If mode is MAX_RANKS and was already successful, then do not display + // cannot afford message when it hits the end of the max rankups... + if ( mode != RankupModes.MAX_RANKS || + mode == RankupModes.MAX_RANKS && sbRanks.length() == 0 ) { + + ranksRankupCannotAffordMsg( sender, results ); + } break; case RANKUP_LOWEST: From 7aa099e25190a64274768858393b26432215d59c Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 25 Feb 2025 05:31:37 -0500 Subject: [PATCH 247/323] Ranks: Setup the PrisonRanks so getInstance() will not return a null and to ensure that isEnabled() returns false if Ranks is not enabled through module configs. --- docs/changelog_v3.3.x.md | 5 ++- .../tech/mcprison/prison/modules/Module.java | 8 +++- .../prison/modules/ModuleManager.java | 39 ++++++++++++++++--- .../mcprison/prison/ranks/PrisonRanks.java | 18 +++++++++ .../tech/mcprison/prison/ranks/RankUtil.java | 3 +- .../prison/ranks/managers/PlayerManager.java | 29 +++++++++++--- .../prison/ranks/managers/RankManager.java | 31 ++++++++++++--- .../prison/spigot/SpigotPlatform.java | 24 ++++++++++-- .../prison/spigot/configs/GuiConfig.java | 3 +- .../spigot/game/SpigotOfflinePlayer.java | 3 +- .../prison/spigot/game/SpigotPlayer.java | 2 +- .../spigot/gui/ListenersPrisonManager.java | 15 ++++++- .../gui/guiutility/SpigotGUIComponents.java | 2 +- 13 files changed, 155 insertions(+), 27 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index b1257e4b1..4baafe0ba 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.19f 2025-02-15 +# 3.3.0-alpha.19f 2025-02-25 + + +* **Ranks: Setup the PrisonRanks so getInstance() will not return a null and to ensure that isEnabled() returns false if Ranks is not enabled through module configs.** * **RankupMax: Fix a bug where after successfully ranking up a few ranks, it always shows an error message related to the last attempt because the player cannot afford the next rank.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/modules/Module.java b/prison-core/src/main/java/tech/mcprison/prison/modules/Module.java index f83ffe829..18cb42098 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/modules/Module.java +++ b/prison-core/src/main/java/tech/mcprison/prison/modules/Module.java @@ -164,7 +164,13 @@ public String getPackageName() { } public boolean isEnabled() { - return status.getStatus() == ModuleStatus.Status.ENABLED; + boolean results = false; + + if ( status != null && status.getStatus() != null ) { + results = status.getStatus() == ModuleStatus.Status.ENABLED; + } + + return results; } public void setEnabled(boolean enabled) { 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 532424f75..0cc4ce7e7 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 @@ -72,12 +72,21 @@ public static File getModuleRootDefault() { * Register a new module. */ public void registerModule(Module module) { - if ( getModule(module.getName()) == null ) { - // Module does not exist, so add it: - modules.add(module); - enableModule(module); + + if ( module != null ) { + + // If module already exists, remove it so it can be added: + if ( getModule(module.getName()) != null ) { + removeModule( module.getName() ); + } + + if ( getModule(module.getName()) == null ) { + // Module does not exist, so add it: + modules.add(module); + enableModule(module); // return; // Already added - } + } + } } private void validateVersion(Module module) { @@ -173,6 +182,26 @@ public Module getModule(String name) { // return modules.stream().filter(module -> module.getName().equalsIgnoreCase(name)) // .findFirst(); } + + /** + * Removes a module, if its already been added, by name. + * + * @param name + * @return + */ + public boolean removeModule( String name ) { + Module results = null; + + for (Module module : getModules() ) { + + if ( module.getName().equalsIgnoreCase(name) ) { + results = module; + break; + } + } + + return results == null ? false : getModules().remove( results ); + } /** * Returns the {@link Module} with the specified package name. 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 7341fbccb..4b5281292 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 @@ -94,12 +94,22 @@ public String getBaseCommands() { */ public static PrisonRanks getInstance() { + if ( instance == null ) { + synchronized (PrisonRanks.class) { + if ( instance == null ) { + instance = new PrisonRanks( "disabled" ); + instance.setEnabled( false ); + } + } + } return instance; } @Override public void enable() { instance = this; + + setEnabled( true ); this.localeManager = new LocaleManager(this, "lang/ranks"); @@ -461,6 +471,7 @@ public void deferredStartup() { */ @Override public void disable() { + setEnabled( false ); } @@ -550,6 +561,9 @@ public void setPrisonStartupDetails( List prisonStartupDetails ){ public RankManager getRankManager() { + if ( rankManager == null && !isEnabled() ) { + rankManager = new RankManager(); + } return rankManager; } @@ -558,6 +572,10 @@ public LadderManager getLadderManager() { } public PlayerManager getPlayerManager() { + + if ( playerManager == null && !isEnabled() ) { + playerManager = new PlayerManager( null ); + } return playerManager; } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/RankUtil.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/RankUtil.java index e52dc159c..bca8680d6 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/RankUtil.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/RankUtil.java @@ -352,7 +352,8 @@ private void rankupPlayerInternal(RankupResults results, Output.get().logDebug( DebugTarget.rankup, "Rankup: rankupPlayerInternal: "); - RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder(ladderName); + RankLadder ladder = !PrisonRanks.getInstance().isEnabled() ? null : + PrisonRanks.getInstance().getLadderManager().getLadder(ladderName); if( ladder == null ) { results.addTransaction( RankupStatus.RANKUP_FAILURE_COULD_NOT_LOAD_LADDER, RankupTransactions.failed_ladder ); return; diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java index 7ea743df3..831334e16 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java @@ -78,20 +78,33 @@ public class PlayerManager private List translatedPlaceHolderKeys; private transient Set playerErrors; + + private transient boolean enabled = false; public PlayerManager(Collection collection) { super("PlayerManager"); - this.collection = collection; this.players = new ArrayList<>(); this.playersByName = new TreeMap<>(); this.playerErrors = new HashSet<>(); + + if ( collection == null ) { + this.enabled = false; + + this.collection = null; + } + else { + + this.collection = collection; + + Prison.get().getEventBus().register(this); + } - - Prison.get().getEventBus().register(this); } + + /* * Methods @@ -122,7 +135,13 @@ public PlayerManager(Collection collection) { // } // } - /** + public boolean isEnabled() { + return enabled; + } + + + + /** * Loads every player in the specified playerFolder. * * @throws IOException If one of the files could not be read, or if the playerFolder does not exist. @@ -242,7 +261,7 @@ public boolean savePlayer(RankPlayer player) { */ public void checkPlayerDefaultRank( RankPlayer rPlayer ) { - if ( rPlayer.getPlayerRankDefault() == null ) { + if ( isEnabled() && rPlayer.getPlayerRankDefault() == null ) { // Try to perform the first join processing to give them the default rank: RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); 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 689975cc0..8d492f11b 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 @@ -85,6 +85,8 @@ public class RankManager private List translatedPlaceHolderKeys; + private transient boolean enabled; + public enum RanksByLadderOptions { playersOnly("players"), allRanks("all"), @@ -124,19 +126,36 @@ public String getAltName() { * Constructor */ + + public RankManager() { + this.collection = null; + + this.loadedRanks = new ArrayList<>(); + this.ranksByName = new TreeMap<>(); + this.ranksById = new TreeMap<>(); + + this.enabled = false; + } + /** * Instantiate this {@link RankManager}. */ public RankManager(Collection collection) { + this(); + + this.enabled = true; + this.collection = collection; - this.loadedRanks = new ArrayList<>(); - this.ranksByName = new TreeMap<>(); - this.ranksById = new TreeMap<>(); } - private void addRank( Rank rank ) { + public boolean isEnabled() { + return enabled; + } + + + private void addRank( Rank rank ) { if ( rank != null ) { getLoadedRanks().add( rank ); String rankName = rank.getName(); @@ -359,7 +378,9 @@ public Optional getRankOptional(String name) { * @return */ public Rank getRank(String name) { - return name == null ? null : getRanksByName().get( name.toLowerCase() ); + return name == null || !isEnabled() ? + null : + getRanksByName().get( name.toLowerCase() ); } 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 88ea237db..1518ad9d9 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 @@ -1369,7 +1369,9 @@ public boolean linkModuleElements( ModuleElement sourceElement, } else if ( sourceElement.getModuleElementType() == ModuleElementType.RANK && - sourceElement instanceof Rank ) { + sourceElement instanceof Rank && + PrisonRanks.getInstance().isEnabled() + ) { // If we have an instance of a mine, then we know that module has been // enabled. @@ -1378,6 +1380,7 @@ else if ( sourceElement.getModuleElementType() == ModuleElementType.RANK && // name. If found, then link. if ( targetElementType != null && targetElementType == ModuleElementType.MINE && PrisonMines.getInstance() != null && PrisonMines.getInstance().isEnabled() ) { + MineManager mm = PrisonMines.getInstance().getMineManager(); if ( mm != null ) { Mine mine = mm.getMine( name ); @@ -1427,7 +1430,8 @@ private boolean unlinkModuleElement( ModuleElement elementA, ModuleElement eleme // We need to confirm targetElementType is ranks, then we need to check to // ensure the rank module is active, then search for a rank with the given // name. If found, then link. - if ( elementB != null && elementB.getModuleElementType() == ModuleElementType.RANK ) { + if ( elementB != null && elementB.getModuleElementType() == ModuleElementType.RANK && + PrisonRanks.getInstance().isEnabled() ) { RankManager rm = PrisonRanks.getInstance().getRankManager(); if ( rm != null ) { @@ -3539,8 +3543,14 @@ public void checkPlayerDefaultRank( RankPlayer rPlayer ) { @Override public void listAllMines(tech.mcprison.prison.internal.CommandSender sender, Player player) { - RankPlayer rPlayer = PrisonRanks.getInstance().getPlayerManager().getPlayer(player); List mines = new ArrayList<>(); + + RankPlayer rPlayer = null; + + if ( PrisonRanks.getInstance().isEnabled() ) { + rPlayer = + PrisonRanks.getInstance().getPlayerManager().getPlayer(player); + } if ( rPlayer != null ) { @@ -3653,7 +3663,13 @@ public void sellall( RankPlayer rankPlayer ) { @Override public RankLadder getRankLadder(String ladderName) { - RankLadder results = PrisonRanks.getInstance().getLadderManager().getLadder( ladderName ); + RankLadder results = null; + + if ( PrisonRanks.getInstance().isEnabled() ) { + results = + PrisonRanks.getInstance().getLadderManager().getLadder( ladderName ); + } + return results; } 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 bba355b22..59c01673f 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 @@ -239,7 +239,7 @@ else if ( conf.get( "Options.Mines.MaterialType.NoMineAccess" ) == null ) { if ( conf.get( "Options.Ranks.MaterialType" ) == null ) { - if ( PrisonRanks.getInstance() != null ) { + if ( PrisonRanks.getInstance() != null && PrisonRanks.getInstance().isEnabled() ) { LinkedHashMap map = new LinkedHashMap<>(); @@ -339,6 +339,7 @@ else if ( conf.get( "Options.Ranks.MaterialType.NoRankAccess" ) == null ) { if ( conf.get( "Options.Ranks.GuiItemNames" ) == null ) { if ( PrisonRanks.getInstance() != null && + PrisonRanks.getInstance().isEnabled() && PrisonRanks.getInstance().getRankManager() != null && PrisonRanks.getInstance().getRankManager().getRanks() != null && PrisonRanks.getInstance().getRankManager().getRanks().size() > 0 ) { diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java index 560e11097..ed9d80b93 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java @@ -437,7 +437,8 @@ public void setActionBar( String actionBar ) { } public RankPlayer getRankPlayer() { - if ( rankPlayer == null ) { + if ( rankPlayer == null && PrisonRanks.getInstance() != null && + PrisonRanks.getInstance().isEnabled() ) { rankPlayer = PrisonRanks.getInstance().getPlayerManager().getPlayer( this ); } return rankPlayer; 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 09885c94f..71a4bb403 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 @@ -785,7 +785,7 @@ public void setActionBar( String actionBar ) { @Override public RankPlayer getRankPlayer() { - if ( rankPlayer == null && + if ( rankPlayer == null && PrisonRanks.getInstance() != null && PrisonRanks.getInstance().isEnabled() ) { rankPlayer = PrisonRanks.getInstance().getPlayerManager().getPlayer( this ); 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 5497f41af..2d6586434 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 @@ -1706,7 +1706,7 @@ private void prisonManagerGUI(InventoryClickEvent e, Player p, String buttonName private void laddersGUI(InventoryClickEvent e, Player p, String buttonNameMain, Module module ) { // Check if the Ranks module's loaded. - if(!(module instanceof PrisonRanks)){ + if(!(module instanceof PrisonRanks) || !PrisonRanks.getInstance().isEnabled() ){ Output.get().sendWarn(new SpigotPlayer(p), "The GUI can't open because the &3Rank module &cisn't loaded"); p.closeInventory(); e.setCancelled(true); @@ -1773,6 +1773,13 @@ private void ranksGUI(InventoryClickEvent e, Player p, String buttonNameMain, St // gui.open(); // return; // } + + if ( !PrisonRanks.getInstance().isEnabled() ) { + + Output.get().sendWarn(new SpigotPlayer(p), "&cPrison ranks are not enabled."); + return; + } + // Get the rank. Rank rank = PrisonRanks.getInstance().getRankManager().getRank(buttonNameMain); @@ -1883,6 +1890,12 @@ private void rankManagerGUI(InventoryClickEvent e, Player p, String[] parts) { String buttonName = ( parts.length >= 1 ? parts[0] : ""); String rankName = (parts.length >= 2 ? parts[1] : "-rankHasNoName-"); + if ( !PrisonRanks.getInstance().isEnabled() ) { + + Output.get().sendWarn(new SpigotPlayer(p), "&cPrison ranks are not enabled."); + return; + } + // Get the rank. Rank rank = PrisonRanks.getInstance().getRankManager().getRank(rankName); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/guiutility/SpigotGUIComponents.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/guiutility/SpigotGUIComponents.java index 40bc9b969..9d7dccdda 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/guiutility/SpigotGUIComponents.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/guiutility/SpigotGUIComponents.java @@ -156,7 +156,7 @@ protected List createLore( String... lores ) { * */ protected boolean checkRanks(Player p){ Module module = Prison.get().getModuleManager().getModule( PrisonRanks.MODULE_NAME ); - if(!(module instanceof PrisonRanks)){ + if( !PrisonRanks.getInstance().isEnabled() || !(module instanceof PrisonRanks)){ Output.get().sendWarn(new SpigotPlayer(p), "&c[ERROR] The GUI can't open because the &3Ranks module &cisn't loaded"); p.closeInventory(); } From 843d099aeb278f491aff7c26e9492633a1b192ce Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 25 Feb 2025 05:47:45 -0500 Subject: [PATCH 248/323] PrisonRanks: A couple of other changes to help ensure there are no issues if Ranks are disabled. --- docs/changelog_v3.3.x.md | 3 +++ .../mcprison/prison/ranks/managers/PlayerManager.java | 5 ++++- .../mcprison/prison/spigot/api/PrisonSpigotAPI.java | 10 +++++++++- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 4baafe0ba..7121166a7 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.19f 2025-02-25 +* **PrisonRanks: A couple of other changes to help ensure there are no issues if Ranks are disabled.** + + * **Ranks: Setup the PrisonRanks so getInstance() will not return a null and to ensure that isEnabled() returns false if Ranks is not enabled through module configs.** diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java index 831334e16..c75ddce14 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java @@ -532,7 +532,10 @@ public void onPlayerJoin(PlayerJoinEvent event) { // add them a second time. RankPlayer rPlayer = player.getRankPlayer(); - rPlayer.doNothing(); + if ( rPlayer != null ) { + + rPlayer.doNothing(); + } } } 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 d9200bbff..a1ef0a171 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 @@ -795,6 +795,8 @@ public void payPlayer( Player player, double amount, String currency, boolean completelySilent = notifyPlayerEarned || notifyPlayerDelay || notifyPlayerEarningDelay || playSoundOnSellAll; SpigotPlayer sPlayer = new SpigotPlayer( player ); + + RankPlayer rankPlayer = sPlayer.getRankPlayer(); // RankPlayer rankPlayer = PrisonRanks.getInstance().getPlayerManager().getPlayer(sPlayer.getUUID(), sPlayer.getName()); @@ -803,7 +805,13 @@ public void payPlayer( Player player, double amount, String currency, // if (!sellInputArrayListOnly) { // removeSellableItems(p); // } - rankPlayer.addBalance(currency, amount); + if ( rankPlayer != null ) { + + rankPlayer.addBalance(currency, amount); + } + else { + sPlayer.addBalance(currency, amount); + } if ( getPrisonSellAll().isSellAllDelayEnabled ){ getPrisonSellAll().addToDelay(player); From 34110447c088a821166cfd9829764f09116afb77 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 25 Feb 2025 05:48:18 -0500 Subject: [PATCH 249/323] AutoFeatures: fix typo in a comment. trival. --- .../mcprison/prison/autofeatures/AutoFeaturesFileConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 3536e470c..b0f2cd94a 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 @@ -138,7 +138,7 @@ public enum AutoFeatures { blockBreakEvents__ReadMe(blockBreakEvents, "Use the following event priorities with the blockBreakEvents: " + "DISABLED, LOWEST, LOW, NORMAL, HIGH, HIGHEST, BLOCKEVENTS, MONITOR, " + - "ACESS, ACCESSBLOCKEVENTS, ACCESSMONITOR"), + "ACCESS, ACCESSBLOCKEVENTS, ACCESSMONITOR"), blockBreakEvents__ReadMe2(blockBreakEvents, "MONITOR: Processed even if event is canceled. Includes block counts, " From 5887f17d3ef70867396739d9270c76ce7545a8a2 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 25 Feb 2025 06:24:19 -0500 Subject: [PATCH 250/323] Mines block preventDrops: Improve the help documentation so it's clearer on what it actually does and how to use the command. --- docs/changelog_v3.3.x.md | 3 +++ .../tech/mcprison/prison/mines/commands/MinesCommands.java | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 7121166a7..845eb3ca0 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.19f 2025-02-25 +* **Mines block preventDrops: Improve the help documentation so it's clearer on what it actually does and how to use the command.** + + * **PrisonRanks: A couple of other changes to help ensure there are no issues if Ranks are disabled.** 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 ddea8d9ee..e92f60e8f 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 @@ -277,7 +277,8 @@ public void constraintsBlockCommand(CommandSender sender, public void preventDropsBlockCommand(CommandSender sender, @Arg(name = "mineName", description = "The name of the mine to view.") String mineName, @Arg(name = "blockName", description = "The block's name") String blockName, - @Arg(name = "preventDrops", description = "Prevent the block from dropping anything " + + @Arg(name = "preventDrops", description = "Prevent the block from dropping anything " + + "and prevent payment for the breakage. A value of 'true' will prevent the drops. " + "[true false]", def = "false") String preventDrops ) { From 874e64cdcefe68737412c561c1e773d8fc8bc493 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 25 Feb 2025 06:30:06 -0500 Subject: [PATCH 251/323] InventoryFullEvent: Start to setup a prison based event that will fire when prison detects that the inventory object is full. This is useful for when other plugins, or customization to prison needs to perform an action when the inventory is full, such as handling a custom sell all action. --- docs/changelog_v3.3.x.md | 5 + .../prison/spigot/api/InventoryFullEvent.java | 254 ++++++++++++++++++ .../events/AutoManagerBlockBreakEvents.java | 6 + .../events/AutoManagerCrazyEnchants.java | 6 + .../AutoManagerEntityExplodeEvents.java | 6 +- .../events/AutoManagerPrisonEnchants.java | 6 +- ...nagerPrisonsExplosiveBlockBreakEvents.java | 6 +- .../AutoManagerRevEnchantsExplosiveEvent.java | 6 +- ...AutoManagerRevEnchantsJackHammerEvent.java | 6 +- .../events/AutoManagerTokenEnchant.java | 4 + ...toManagerXPrisonExplosionTriggerEvent.java | 6 +- .../AutoManagerXPrisonLayerTriggerEvent.java | 6 +- .../AutoManagerXPrisonNukeTriggerEvent.java | 6 +- .../events/AutoManagerZenchantments.java | 6 +- 14 files changed, 320 insertions(+), 9 deletions(-) create mode 100644 prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/InventoryFullEvent.java diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 845eb3ca0..a8fa3dc28 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.19f 2025-02-25 +* **InventoryFullEvent: Start to setup a prison based event that will fire when prison detects that the inventory object is full.** +This is useful for when other plugins, or customization to prison needs to perform an action when the inventory is full, such as handling a custom sell all action. +This new event offers cancel, but there is nothing to cancel within prison since canceling the event will not alter the inventory. It can be used to signal to other plugins that the event was handled by another plugin. + + * **Mines block preventDrops: Improve the help documentation so it's clearer on what it actually does and how to use the command.** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/InventoryFullEvent.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/InventoryFullEvent.java new file mode 100644 index 000000000..7f2da00f9 --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/InventoryFullEvent.java @@ -0,0 +1,254 @@ +/** + * + */ +package tech.mcprison.prison.spigot.api; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +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.Inventory; +import org.bukkit.inventory.PlayerInventory; +import org.bukkit.plugin.EventExecutor; +import org.bukkit.plugin.PluginManager; + +import tech.mcprison.prison.spigot.SpigotPrison; + +/** + * This event is used by plugins that want to get access to notifications when + * prison detects a full inventory. + * + * In general, this only currently supports a player's inventory, but if + * a backpack is also registered with backpack events, then this could be + * fired when a backpack is also full. + */ +public class InventoryFullEvent + extends Event + implements Cancellable { + + private final Player player; + private boolean cancel; + + private final Inventory inventory; + + /** + *

Warning: BlastUseEvent does not identify the block the player actually hit, so the dummyBlock + * is just a random first block from the explodedBlocks list and may not be the block + * that initiated the explosion event. Such events are identified by + * BlockEventType.CEXplosion. Make sure you do not process the first block twice, + * which is also passed as the org.bukkit.block.Block and the SpigotBlock to prevent have to + * pass nulls. They are the exact same objects. + *

+ * + * Due to this behavior, since BlockBreakEvent's handlers is static, it + * will "share" the handlers (listeners). To prevent this unwanted behavior, + * since prison's BlockBreakEvent listeners will be called, this class + * defines and overrides the the handlers with it's own instance. + * + */ + private static final HandlerList handlers = new HandlerList(); + + public InventoryFullEvent() { + super(); + + this.player = null; + this.cancel = false; + this.inventory = null; + } + + public InventoryFullEvent( Player player ) { + super(); + + this.player = player; + this.cancel = false; + + this.inventory = player.getInventory(); + } + + public PlayerInventory getPlayerInventory() { + PlayerInventory inv = null; + + if ( getInventory() != null && getInventory() instanceof PlayerInventory ) { + inv = (PlayerInventory) getInventory(); + } + + return inv; + } + + + /** + * This is an example of how to fire this event for a player's inventory. + * + * Generally this would not be used in your plugin, but this is how prison + * would fire the event internally. Your plugin could use it too, if it + * would cause the player's inventory to be full. + * + * Each time an event is fired, a new instance of the event is created + * so bukkit can pass that instance to all registered listeners. + * + * @param org.bukkit.entity.Player player + * @return boolean if the event was cancelled + */ + public static boolean fireInventoryFullEvent( Player player ) { + boolean isCancelled = false; + + InventoryFullEvent ifEvent = new InventoryFullEvent( player ); + + Bukkit.getServer().getPluginManager().callEvent( ifEvent ); + + if ( !ifEvent.isCancelled() ) { + // You would handle your plugin's actions here if this was called + // in line within your code. + } + + return isCancelled; + } + + + + /** + * This is an example of how you would setup a listener in your + * plugin, and how you would use it. It should generally be a class + * with a function of any name. The important key element is that it + * contains a parameter of class InventoryFullEvent. Specifying an + * @EventHandler annotation is optional, but it's included here to + * show you how you can use it to sent the event's priority. + * + * Dynamically setting the event priority based upon configs is + * beyond the purpose of this example. + * + * Make sure within your function, you put your code that will react + * to when this event is fired. You can refer to other classes + * within your plugin and do whatever you need to do. + * + * Your listener class must implement Listener. + * + */ + public class SampleInventoryFullListener + implements Listener { + + public SampleInventoryFullListener() { + super(); + + } + + @EventHandler(priority=EventPriority.NORMAL) + public void onInventoryFullEvent( InventoryFullEvent ifEvent ) { + + // If the event has been canceled, then do not process this event + // since another plugin already processed it, or has denyed that it + // should be processed. + if ( !ifEvent.isCancelled() ) { + + // Do something with this event here. + // You will have access to all of the functions in the event. + if ( ifEvent.getPlayerInventory() != null ) { + + // A playerInventory was registered with this event: + @SuppressWarnings("unused") + PlayerInventory pi = ifEvent.getPlayerInventory(); + + boolean success = true; + + if ( success ) { + + // If what we're doing in this example is successful and we need to + // cancel the event: + ifEvent.setCancelled( true ); + } + // etc... + } + } + } + + + /** + * Somewhere in your plugin, you need to register your event listener with + * the Bukkit PluginManager. This is an example of how to do that. + * + * This will register your listener with the EventPriority of NORMAL if you + * have not used the @EventHandler annotation. + * + * When prison fires the InventoryEvent, Bukkit will go through all registered + * event listeners and will call the registered function (the one with the parameter + * that includes InventoryFullEvent) so it can run all of your code that you + * have placed in that function. + * + * Please note that this function is placed in the inner class of + * SampleInventoryFullListener only for demonstration purposes. You do not + * have to put this function, or the registration of your listener in + * your listener class. Generally, you may find it better suited to register + * all of your listeners in your primary plugin class. + * + * As a bonus, I have included a secondary registration at a custom priority + * that is not set by an annotation, but could be set within a config file. + * + */ + public void sampleUsageRegisterListenerEvent() { + + SpigotPrison prison = SpigotPrison.getInstance(); + PluginManager pm = Bukkit.getServer().getPluginManager(); + + SampleInventoryFullListener sifListener = new SampleInventoryFullListener(); + + pm.registerEvents( sifListener, prison ); + + // Hint: to dynamically control the listener's EventPriority you would use + // the other pm.registerEvents() functions that allows you to set them + // upon registration. + + // WARNING: Do not register both events at the same time, or they will be + // be called twice and could duplicate everything. The following is + // included ONLY to show you how it can be done and is strictly + // for demonstration purposes. It's not needed if you can use + // the pm.registerEvents() function+. + + // The following shows how you can dynamically register your listener with + // a dynamically set EventPriority as defined in a config file. Assume + // that ePriority is based upon such a config that is requesting a LOW priority. + EventPriority ePriority = EventPriority.LOW; + + pm.registerEvent(InventoryFullEvent.class, sifListener, ePriority, + new EventExecutor() { + public void execute(Listener l, Event e) { + + InventoryFullEvent iffEvent = (InventoryFullEvent) e; + + ((SampleInventoryFullListener)l) + .onInventoryFullEvent( iffEvent ); + } + }, + prison); + } + } + + public Player getPlayer() { + return player; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public Inventory getInventory() { + return inventory; + } + + public boolean isCancelled() { + return cancel; + } + + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } + +} 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 b3032b796..0837fac66 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.mines.features.MineBlockEvent.BlockEventType; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.spigot.SpigotPrison; +import tech.mcprison.prison.spigot.api.InventoryFullEvent; import tech.mcprison.prison.spigot.api.PrisonMinesBlockBreakEvent; import tech.mcprison.prison.spigot.autofeatures.AutoManagerFeatures; import tech.mcprison.prison.spigot.block.BlockBreakPriority; @@ -520,6 +521,11 @@ else if ( cancelBy == EventListenerCancelBy.drops ) { // isPlayerAutosellEnabled, pmEvent.getDebugInfo() ); + if ( pmEvent.getSpigotPlayer().isInventoryFull() ) { + + InventoryFullEvent.fireInventoryFullEvent( pmEvent.getPlayer() ); + } + if ( isBoolean( AutoFeatures.isForceSellAllOnInventoryWhenBukkitBlockBreakEventFires ) && 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 0c6e58232..419097ad4 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 @@ -18,6 +18,7 @@ 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.InventoryFullEvent; import tech.mcprison.prison.spigot.api.PrisonMinesBlockBreakEvent; import tech.mcprison.prison.spigot.autofeatures.AutoManagerFeatures; import tech.mcprison.prison.spigot.block.BlockBreakPriority; @@ -418,6 +419,11 @@ else if ( pmEvent.getBbPriority().isMonitor() ) { } + if ( pmEvent.getSpigotPlayer().isInventoryFull() ) { + + InventoryFullEvent.fireInventoryFullEvent( pmEvent.getPlayer() ); + } + } printDebugInfo( pmEvent, start ); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerEntityExplodeEvents.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerEntityExplodeEvents.java index 376d431a5..c7fb2d895 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerEntityExplodeEvents.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerEntityExplodeEvents.java @@ -19,6 +19,7 @@ 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.InventoryFullEvent; import tech.mcprison.prison.spigot.api.PrisonMinesBlockBreakEvent; import tech.mcprison.prison.spigot.autofeatures.AutoManagerFeatures; import tech.mcprison.prison.spigot.block.BlockBreakPriority; @@ -436,7 +437,10 @@ else if ( pmEvent.getBbPriority().isMonitor() ) { // } } - + if ( pmEvent.getSpigotPlayer().isInventoryFull() ) { + + InventoryFullEvent.fireInventoryFullEvent( pmEvent.getPlayer() ); + } } printDebugInfo( pmEvent, start ); 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 582a7412a..990b4ccf2 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 @@ -22,6 +22,7 @@ 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.InventoryFullEvent; import tech.mcprison.prison.spigot.api.PrisonMinesBlockBreakEvent; import tech.mcprison.prison.spigot.autofeatures.AutoManagerFeatures; import tech.mcprison.prison.spigot.block.BlockBreakPriority; @@ -677,7 +678,10 @@ else if ( pmEvent.getBbPriority().isMonitor() ) { // } } - + if ( pmEvent.getSpigotPlayer().isInventoryFull() ) { + + InventoryFullEvent.fireInventoryFullEvent( pmEvent.getPlayer() ); + } } 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 8c76fd9ae..f7f22c93d 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 @@ -20,6 +20,7 @@ import tech.mcprison.prison.output.Output; import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.api.ExplosiveBlockBreakEvent; +import tech.mcprison.prison.spigot.api.InventoryFullEvent; import tech.mcprison.prison.spigot.api.PrisonMinesBlockBreakEvent; import tech.mcprison.prison.spigot.autofeatures.AutoManagerFeatures; import tech.mcprison.prison.spigot.block.BlockBreakPriority; @@ -415,7 +416,10 @@ else if ( cancelBy == EventListenerCancelBy.drops ) { } } - + if ( pmEvent.getSpigotPlayer().isInventoryFull() ) { + + InventoryFullEvent.fireInventoryFullEvent( pmEvent.getPlayer() ); + } } printDebugInfo( pmEvent, start ); 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 a6f51cc82..232bf3aeb 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 @@ -18,6 +18,7 @@ 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.InventoryFullEvent; import tech.mcprison.prison.spigot.api.PrisonMinesBlockBreakEvent; import tech.mcprison.prison.spigot.autofeatures.AutoManagerFeatures; import tech.mcprison.prison.spigot.block.BlockBreakPriority; @@ -420,7 +421,10 @@ else if ( pmEvent.getBbPriority().isMonitor() ) { // } } - + if ( pmEvent.getSpigotPlayer().isInventoryFull() ) { + + InventoryFullEvent.fireInventoryFullEvent( pmEvent.getPlayer() ); + } } printDebugInfo( pmEvent, start ); 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 f3691b344..f59fc0045 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 @@ -22,6 +22,7 @@ import tech.mcprison.prison.output.Output; import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.SpigotUtil; +import tech.mcprison.prison.spigot.api.InventoryFullEvent; import tech.mcprison.prison.spigot.api.PrisonMinesBlockBreakEvent; import tech.mcprison.prison.spigot.autofeatures.AutoManagerFeatures; import tech.mcprison.prison.spigot.block.BlockBreakPriority; @@ -446,7 +447,10 @@ else if ( pmEvent.getBbPriority().isMonitor() ) { // } } - + if ( pmEvent.getSpigotPlayer().isInventoryFull() ) { + + InventoryFullEvent.fireInventoryFullEvent( pmEvent.getPlayer() ); + } } printDebugInfo( pmEvent, start ); 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 7d04ea09f..42d1d9a05 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 @@ -19,6 +19,7 @@ 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.InventoryFullEvent; import tech.mcprison.prison.spigot.api.PrisonMinesBlockBreakEvent; import tech.mcprison.prison.spigot.autofeatures.AutoManagerFeatures; import tech.mcprison.prison.spigot.block.BlockBreakPriority; @@ -473,7 +474,10 @@ else if ( pmEvent.getBbPriority().isMonitor() ) { // } } + if ( pmEvent.getSpigotPlayer().isInventoryFull() ) { + InventoryFullEvent.fireInventoryFullEvent( pmEvent.getPlayer() ); + } } printDebugInfo( pmEvent, start ); 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 f0a329f34..38ffe1e50 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 @@ -18,6 +18,7 @@ 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.InventoryFullEvent; import tech.mcprison.prison.spigot.api.PrisonMinesBlockBreakEvent; import tech.mcprison.prison.spigot.autofeatures.AutoManagerFeatures; import tech.mcprison.prison.spigot.block.BlockBreakPriority; @@ -427,7 +428,10 @@ else if ( pmEvent.getBbPriority().isMonitor() ) { // } } - + if ( pmEvent.getSpigotPlayer().isInventoryFull() ) { + + InventoryFullEvent.fireInventoryFullEvent( pmEvent.getPlayer() ); + } } printDebugInfo( pmEvent, start ); 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 79fc8844a..e4029a8d4 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 @@ -18,6 +18,7 @@ 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.InventoryFullEvent; import tech.mcprison.prison.spigot.api.PrisonMinesBlockBreakEvent; import tech.mcprison.prison.spigot.autofeatures.AutoManagerFeatures; import tech.mcprison.prison.spigot.block.BlockBreakPriority; @@ -428,7 +429,10 @@ else if ( pmEvent.getBbPriority().isMonitor() ) { // } } - + if ( pmEvent.getSpigotPlayer().isInventoryFull() ) { + + InventoryFullEvent.fireInventoryFullEvent( pmEvent.getPlayer() ); + } } printDebugInfo( pmEvent, start ); 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 c6237d13f..fdea2dbba 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 @@ -18,6 +18,7 @@ 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.InventoryFullEvent; import tech.mcprison.prison.spigot.api.PrisonMinesBlockBreakEvent; import tech.mcprison.prison.spigot.autofeatures.AutoManagerFeatures; import tech.mcprison.prison.spigot.block.BlockBreakPriority; @@ -428,7 +429,10 @@ else if ( pmEvent.getBbPriority().isMonitor() ) { // } } - + if ( pmEvent.getSpigotPlayer().isInventoryFull() ) { + + InventoryFullEvent.fireInventoryFullEvent( pmEvent.getPlayer() ); + } } printDebugInfo( pmEvent, start ); 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 d2f6c028e..74a262889 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 @@ -18,6 +18,7 @@ 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.InventoryFullEvent; import tech.mcprison.prison.spigot.api.PrisonMinesBlockBreakEvent; import tech.mcprison.prison.spigot.autofeatures.AutoManagerFeatures; import tech.mcprison.prison.spigot.block.BlockBreakPriority; @@ -400,7 +401,10 @@ else if ( cancelBy == EventListenerCancelBy.drops ) { } } - + if ( pmEvent.getSpigotPlayer().isInventoryFull() ) { + + InventoryFullEvent.fireInventoryFullEvent( pmEvent.getPlayer() ); + } } printDebugInfo( pmEvent, start ); From 9d4288670e529a1104baab851249e44ea234febd Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 28 Feb 2025 13:21:51 -0500 Subject: [PATCH 252/323] AutoManager: PEExplosionEvent - remove a debug statement that was showing up in the console when not in debug mode. --- docs/changelog_v3.3.x.md | 5 ++++- .../autofeatures/events/AutoManagerPrisonEnchants.java | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index a8fa3dc28..8ca3d9359 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.19f 2025-02-25 +# 3.3.0-alpha.19f 2025-02-28 + + +* **AutoManager: PEExplosionEvent - remove a debug statement that was showing up in the console when not in debug mode.** * **InventoryFullEvent: Start to setup a prison based event that will fire when prison detects that the inventory object is full.** 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 990b4ccf2..3fc4751c1 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 @@ -507,8 +507,8 @@ public void handlePEExplosionEvent( PEExplosionEvent e, BlockBreakPriority bbPri List vBlocks = removeAllInvalidBlocks( e.getPlayer(), e.getBlocks(), bbPriority, true ); int blocksAfter = vBlocks.size(); - Output.get().logInfo( "&6 #### PEExplosionEvent: &7removeAllInvalidBlocks:&3 before: %d after: %d", - blocksBefore, blocksAfter ); +// Output.get().logInfo( "&6 #### PEExplosionEvent: &7removeAllInvalidBlocks:&3 before: %d after: %d", +// blocksBefore, blocksAfter ); if ( vBlocks.size() == 0 ) { From c9a91561588d6dc8b840c8cc9b01f58a266c674d Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 28 Feb 2025 13:25:49 -0500 Subject: [PATCH 253/323] CommandHandler: Expand the tracking of command stats to track the usage of aliases. The command '/prison support cmdStats' has been updated to include alias usage counts. Usage of aliases would not be tracked at all, even the primary command. --- docs/changelog_v3.3.x.md | 6 ++++++ .../tech/mcprison/prison/PrisonCommand.java | 10 +++++++--- .../prison/commands/CommandHandler.java | 18 ++++++++++++++++++ .../prison/commands/RegisteredCommand.java | 18 ++++++++++++++++++ 4 files changed, 49 insertions(+), 3 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 8ca3d9359..4705caf10 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.19f 2025-02-28 +* **CommandHandler: Expand the tracking of command stats to track the usage of aliases.** +The command '/prison support cmdStats' has been updated to include alias usage counts. +Usage of aliases would not be tracked at all, even the primary command. + + + * **AutoManager: PEExplosionEvent - remove a debug statement that was showing up in the console when not in debug mode.** 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 440f2dc46..a8f2f15e9 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java +++ b/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java @@ -1347,11 +1347,12 @@ private List getCommandStats() { 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 ") ); + Output.stringFormat( " &a&n%-40s&r &a&n%7s&r &a&n%7s&r &a&n%-11s&r", + " Commands ", " Usage "," Alias ", " Avg ms ") ); int count = 0; int totals = 0; + int totalsAlias = 0; double totalDuration = 0d; for (RegisteredCommand cmd : allCmds) { @@ -1359,13 +1360,15 @@ private List getCommandStats() { double duration = cmd.getUsageRunTimeNanos() / (double) cmd.getUsageCount() / 1000000.0d; - results.add( Output.stringFormat( " &2%-40s &2%7s &2%11s", + results.add( Output.stringFormat( " &2%-40s &2%7s &2%7s &2%11s", cmd.getCompleteLabel(), iFmt.format( cmd.getUsageCount() ), + iFmt.format( cmd.getUsageCountAlias() ), dFmt.format( duration ) ) ); count++; totals += cmd.getUsageCount(); + totalsAlias += cmd.getUsageCountAlias(); totalDuration += cmd.getUsageRunTimeNanos(); } } @@ -1373,6 +1376,7 @@ private List getCommandStats() { 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 )) ); + results.add( Output.stringFormat(" &3Total Prison Command Alias Usage: &7%9s", iFmt.format( totalsAlias )) ); double avgDuration = totalDuration / (double) count / 1000000.0d; results.add( Output.stringFormat(" &3Average Command Duration ms: &7%9s", dFmt.format( avgDuration )) ); diff --git a/prison-core/src/main/java/tech/mcprison/prison/commands/CommandHandler.java b/prison-core/src/main/java/tech/mcprison/prison/commands/CommandHandler.java index 00a1e5822..511349648 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/commands/CommandHandler.java +++ b/prison-core/src/main/java/tech/mcprison/prison/commands/CommandHandler.java @@ -48,6 +48,7 @@ import tech.mcprison.prison.output.LogLevel; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.output.RowComponent; +import tech.mcprison.prison.output.Output.DebugTarget; import tech.mcprison.prison.util.ChatColor; public class CommandHandler { @@ -971,6 +972,23 @@ public boolean onCommand(CommandSender sender, PluginCommand command, String lab if (rootCommand.isOnlyPlayers() && !(sender instanceof Player)) { Prison.get().getLocaleManager().getLocalizable("cantAsConsole") .sendTo(sender, LogLevel.ERROR); + + boolean debug = Output.get().isActiveTarget( DebugTarget.commandHandler ); + if ( debug ) { + String argz = ""; + for (String arg : args) { + argz += arg + " "; + } + + String msg = String.format( + "CommandHandler.onCommand: Sender %s. Command is marked with 'onlyPlayers'. " + + "Cannot run. : [%s]", + sender.getName(), + (label + " " + argz).trim() + ); + Output.get().logInfo( msg ); + } + return true; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/commands/RegisteredCommand.java b/prison-core/src/main/java/tech/mcprison/prison/commands/RegisteredCommand.java index 36866df7f..7dfa712a7 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/commands/RegisteredCommand.java +++ b/prison-core/src/main/java/tech/mcprison/prison/commands/RegisteredCommand.java @@ -44,6 +44,7 @@ public class RegisteredCommand private boolean alias = false; private int usageCount; + private int usageCountAlias; private long usageRunTimeNanos; private String junitTest = null; @@ -84,6 +85,7 @@ public RegisteredCommand(String label, CommandHandler handler, RegisteredCommand this.registeredAliases = new ArrayList<>(); this.usageCount = 0; + this.usageCountAlias = 0; this.usageRunTimeNanos = 0; } @@ -287,6 +289,12 @@ private void executeMethod(CommandSender sender, String[] args ) { // Record that the command has been "ran", which does not mean it was successful: incrementUsageCount(); + + if ( isAlias() && getParentOfAlias() != null ) { +// getParentOfAlias().incrementUsageCount(); + getParentOfAlias().incrementUsageCountAlias(); + + } nanosStart = System.nanoTime(); method.invoke(getMethodInstance(), resultArgs.toArray()); @@ -656,6 +664,16 @@ public int getUsageCount() { public void setUsageCount(int usageCount) { this.usageCount = usageCount; } + + public void incrementUsageCountAlias() { + usageCountAlias++; + } + public int getUsageCountAlias() { + return usageCountAlias; + } + public void setUsageCountAlilas(int usageCountAlias) { + this.usageCountAlias = usageCountAlias; + } public long getUsageRunTimeNanos() { return usageRunTimeNanos; From 470932edb0793f8fb7addd06234c51f111884120 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 28 Feb 2025 13:31:46 -0500 Subject: [PATCH 254/323] Players: CommandSender: Added a new transient field miscText that can now be used to return a message to the caller. For the command '/mines tp' if a player tries to tp to their current rank's mines, and if that rank does not have any mines connected to it, it will now step back through all prior ranks until it finds a mine to TP the player to. This returns a message that can be used, indicating the current rank, but indicates the next highest rank that had a mine. This message is not yet externalized. Including a TP message indicating where they player has been TP'd to. --- docs/changelog_v3.3.x.md | 7 ++++++ .../prison/internal/CommandSender.java | 10 ++++++++ .../prison/ranks/data/RankPlayer.java | 18 ++++++++++++++- .../java/tech/mcprison/prison/TestPlayer.java | 16 +++++++++++++ .../prison/spigot/SpigotPlatform.java | 23 +++++++++++++++++-- .../spigot/game/SpigotCommandSender.java | 19 +++++++++++++++ .../spigot/game/SpigotOfflinePlayer.java | 18 ++++++++++++++- .../prison/spigot/game/SpigotPlayer.java | 19 +++++++++++++-- 8 files changed, 124 insertions(+), 6 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 4705caf10..5945a0d22 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.19f 2025-02-28 +* **Players: CommandSender: Added a new transient field miscText that can now be used to return a message to the caller.** +For the command '/mines tp' if a player tries to tp to their current rank's mines, and if that rank does not have any mines connected to it, it will now step back through all prior ranks until it finds a mine to TP the player to. +This returns a message that can be used, indicating the current rank, but indicates the next highest rank that had a mine. +This message is not yet externalized. Including a TP message indicating where they player has been TP'd to. + + + * **CommandHandler: Expand the tracking of command stats to track the usage of aliases.** The command '/prison support cmdStats' has been updated to include alias usage counts. Usage of aliases would not be tracked at all, even the primary command. diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/CommandSender.java b/prison-core/src/main/java/tech/mcprison/prison/internal/CommandSender.java index 50b5a53c7..512401118 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/CommandSender.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/CommandSender.java @@ -120,5 +120,15 @@ public interface CommandSender public RankPlayer getRankPlayer(); + + /** + * This miscText is not used for any specific purpose other than to hold a String + * value. It can be used to return a message from a function, but it should always + * be cleared when done using it. + * + * @return + */ + public String getMiscText(); + public void setMiscText( String text ); } 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 161b56858..382540239 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 @@ -146,6 +146,8 @@ public class RankPlayer private List sellallMultipliers; + private transient String miscText; + public RankPlayer() { super(); @@ -2358,7 +2360,21 @@ public void setSellallMultipliers(List sellallMultipliers) { } - + /** + * This miscText is not used for any specific purpose other than to hold a String + * value. It can be used to return a message from a function, but it should always + * be cleared when done using it. + * + * @return + */ + @Override + public String getMiscText() { + return miscText; + } + @Override + public void setMiscText( String text ) { + miscText = text; + } // public long getRankScoreCooldown() { // return rankScoreCooldown; diff --git a/prison-core/src/test/java/tech/mcprison/prison/TestPlayer.java b/prison-core/src/test/java/tech/mcprison/prison/TestPlayer.java index aff060886..e66257ad1 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/TestPlayer.java +++ b/prison-core/src/test/java/tech/mcprison/prison/TestPlayer.java @@ -288,4 +288,20 @@ public RankPlayer getRankPlayer() { return null; } + + + /** + * This miscText is not used for any specific purpose other than to hold a String + * value. It can be used to return a message from a function, but it should always + * be cleared when done using it. + * + * @return + */ + @Override + public String getMiscText() { + return null; + } + @Override + public void setMiscText( String text ) { + } } 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 1518ad9d9..cd129e808 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 @@ -1611,9 +1611,12 @@ public ModuleElement getPlayerDefaultMine( tech.mcprison.prison.internal.Command if ( rankPlayer != null && rankPlayerFactory.getRank( rankPlayer, "default" ) != null ) { PlayerRank pRank = rankPlayerFactory.getRank( rankPlayer, "default" ); + // Reset the miscText field: + sender.setMiscText( null ); + Rank rank = pRank.getRank(); - if ( rank != null ) { + while ( rank != null && results == null ) { // First check to see if there are any mines linked to a rank: if ( rank.getMines() != null && rank.getMines().size() > 0 ) { @@ -1639,8 +1642,24 @@ public ModuleElement getPlayerDefaultMine( tech.mcprison.prison.internal.Command results = mm.getMine( rank.getName() ); } + if ( results == null ) { + // The current rank did not have any mines tied to the rank, nor was there + // a mine with the name of the current rank. + // Therefore, try the prior rank: + rank = rank.getRankPrior(); + } + + } + + if ( rank != null && rank.compareTo( pRank.getRank() ) != 0 ) { + String msg = String.format( + "&3No mines are connected to current rank %s&3. Mine %s&3 is the next " + + "highest rank that has a mine.", + pRank.getRank().getTag(), + rank.getTag() + ); + sender.setMiscText( msg ); } - } } 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 275baa560..8593d3e7b 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 @@ -45,6 +45,8 @@ */ public class SpigotCommandSender implements CommandSender { + + private transient String miscText; private org.bukkit.command.CommandSender bukkitSender; @@ -328,5 +330,22 @@ public RankPlayer getRankPlayer() { } return rankPlayer; } + + + /** + * This miscText is not used for any specific purpose other than to hold a String + * value. It can be used to return a message from a function, but it should always + * be cleared when done using it. + * + * @return + */ + @Override + public String getMiscText() { + return miscText; + } + @Override + public void setMiscText( String text ) { + miscText = text; + } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java index ed9d80b93..f03ec30ef 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java @@ -38,7 +38,7 @@ public class SpigotOfflinePlayer private transient File filePlayer; private transient File fileCache; - + private transient String miscText; public SpigotOfflinePlayer(OfflinePlayer offlinePlayer) { this.offlinePlayer = offlinePlayer; @@ -496,4 +496,20 @@ public tech.mcprison.prison.internal.Player getPlatformPlayer() { return player; } + + /** + * This miscText is not used for any specific purpose other than to hold a String + * value. It can be used to return a message from a function, but it should always + * be cleared when done using it. + * + * @return + */ + @Override + public String getMiscText() { + return miscText; + } + @Override + public void setMiscText( String text ) { + miscText = text; + } } 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 71a4bb403..0cbc3026e 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 @@ -77,7 +77,7 @@ public class SpigotPlayer private transient File filePlayer; private transient File fileCache; - + private transient String miscText; public SpigotPlayer(org.bukkit.entity.Player bukkitPlayer) { super(bukkitPlayer); @@ -1186,6 +1186,21 @@ public boolean checkAutoSellTogglePerms( StringBuilder debugInfo ) { return results; } - + + /** + * This miscText is not used for any specific purpose other than to hold a String + * value. It can be used to return a message from a function, but it should always + * be cleared when done using it. + * + * @return + */ + @Override + public String getMiscText() { + return miscText; + } + @Override + public void setMiscText( String text ) { + miscText = text; + } } From 455e7970d4d75aba8efd787fd397427e4559b190 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 28 Feb 2025 13:37:13 -0500 Subject: [PATCH 255/323] Bug fix: CommandSender: Was causing a type cast exception when trying to TP a player from the console. The CommandSender was assuming the sender was always a player object, when it shouldn't have been doing that. --- docs/changelog_v3.3.x.md | 9 +++++++++ .../prison/spigot/game/SpigotCommandSender.java | 13 +++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 5945a0d22..38bd10017 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.19f 2025-02-28 +* **Bug fix: CommandSender: Was causing a type cast exception when trying to TP a player from the console.** +The CommandSender was assuming the sender was always a player object, when it shouldn't have been doing that. + + +* **Bug fix: CommandSender: Was causing a type cast exception when trying to TP a player from the console.** +The CommandSender was assuming the sender was always a player object, when it shouldn't have been doing that. + + + * **Players: CommandSender: Added a new transient field miscText that can now be used to return a message to the caller.** For the command '/mines tp' if a player tries to tp to their current rank's mines, and if that rank does not have any mines connected to it, it will now step back through all prior ranks until it finds a mine to TP the player to. This returns a message that can be used, indicating the current rank, but indicates the next highest rank that had a 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 8593d3e7b..d417b81da 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 @@ -325,8 +325,17 @@ public RankPlayer getRankPlayer() { if ( PrisonRanks.getInstance().isEnabled() ) { - rankPlayer = PrisonRanks.getInstance().getPlayerManager() - .getPlayer( (Player) this ); + if ( isPlayer() ) { + + rankPlayer = PrisonRanks.getInstance().getPlayerManager() + .getPlayer( (Player) this ); + } + else { + rankPlayer = PrisonRanks.getInstance().getPlayerManager() + .getPlayer( null, this.getName() ); + + } + } return rankPlayer; } From 5774646fad7d24deeebee10c2a41dd1894a5cc1b Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 28 Feb 2025 13:39:18 -0500 Subject: [PATCH 256/323] MineBombs: Improvements to the command '/prison utils bomb list' command to better format the information and include some missing details. --- docs/changelog_v3.3.x.md | 3 + .../spigot/utils/PrisonUtilsMineBombs.java | 130 +++++++++++++----- 2 files changed, 99 insertions(+), 34 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 38bd10017..083fd1a4b 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.19f 2025-02-28 +* **MineBombs: Improvements to the command '/prison utils bomb list' command to better format the information and include some missing details.** + + * **Bug fix: CommandSender: Was causing a type cast exception when trying to TP a player from the console.** The CommandSender was assuming the sender was always a player object, when it shouldn't have been doing that. 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 99bc0a8ef..77f5ba5df 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 @@ -522,7 +522,7 @@ public void utilsMineBombsList( CommandSender sender, if ( options != null && options.toLowerCase().contains( "animations" ) ) { // exit after showing the list of mine bomb animations: - messages.add( "&7Animations Patterns:" ); + messages.add( "&7Mine Bomb Animation Patterns:" ); List animations = AnimationPattern.asList(); messages.addAll( Text.formatColumnsFromList( animations, 4 ) ); @@ -535,7 +535,7 @@ public void utilsMineBombsList( CommandSender sender, if ( options != null && options.toLowerCase().contains( "shapes" ) ) { // exit after showing shapes: - messages.add( "&7Shapes:" ); + messages.add( "&7Mine Bomb Shapes:" ); List shapes = ExplosionShape.asList(); messages.addAll( Text.formatColumnsFromList( shapes, 4 ) ); @@ -630,35 +630,79 @@ public void utilsMineBombsList( CommandSender sender, } + // support bomb name fragments? + DecimalFormat dFmt = new DecimalFormat( "#,##0.000" ); + DecimalFormat iFmt = new DecimalFormat( "#,##0" ); + + + String h1 = "&3Prison Mine Bomb Listing:"; + messages.add( h1 ); + + // Footers: + String f1 = " &b(&cThrSp&b=Throw Speed, &cCDwn&b=Cool Down Ticks, &cFuse&b=Fuse Delay Ticks)"; + String f2 = " &b(&cAutoSell&b=Forced AutoSell, &cBlkCnt&b=Add to player block counts)"; + String f3 = " &b(&cAPat&b=Animation Pattern, &cASp&b=Animation Speed, &cARad&b=Animation Radius)"; + String f4 = " &b(&cARadDel&b=Animation Radius Delta)"; + Set keys = mBombs.getConfigData().getBombs().keySet(); for ( String key : keys ) { + MineBombData bomb = mBombs.getConfigData().getBombs().get( key ); - String message = String.format( - "&7%-12s &3AnimationPattern & Speed: &7%s %s &3Throw Speed: &7(%s - %s)", - bomb.getName(), - bomb.getAnimationPattern().name(), - dFmt.format( bomb.getAnimationSpeed() ), - dFmt.format( bomb.getThrowVelocityLow() ), - dFmt.format( bomb.getThrowVelocityHigh() ) + + if ( bomb.getName().trim().length() > 0 && + !bomb.getName().toLowerCase().contains(options.trim().toLowerCase())) { + continue; + } + + + String msg1 = String.format( + "&7%s", + bomb.getName() ); + messages.add( msg1 ); - messages.add( message ); String msg2 = String.format( - " &3FuseDelayTicks: &7%d &3CooldownTicks: &7%d", - bomb.getFuseDelayTicks(), - bomb.getCooldownTicks() + " &3ThrSp: &7(%s - %s) &3CDwn: &7%s &3Fuse: &7%s &3AutoSell: &7%s " + + "&3BlkCnt: &7%s &3Small: &7%s", + dFmt.format( bomb.getThrowVelocityLow() ), + dFmt.format( bomb.getThrowVelocityHigh() ), + iFmt.format( bomb.getCooldownTicks() ), + iFmt.format( bomb.getFuseDelayTicks() ), + (bomb.isAutosell() ? "&aOn" : "&cOff"), + (bomb.isApplyToPlayersBlockCount() ? "&aOn" : "&cOff"), + (bomb.isSmall() ? "&aOn" : "&cOff") ); messages.add( msg2 ); + + + String msg3 = String.format( + " &3APat: &7%s &3ASp: &7%s &3ARad: &7%s &3ARadDel: &7%s " + + "&3ASpn: &7%s", + bomb.getAnimationPattern().name(), + dFmt.format( bomb.getAnimationSpeed() ), + dFmt.format( bomb.getAnimationRadius() ), + dFmt.format( bomb.getAnimationRadiusDelta() ), + dFmt.format( bomb.getAnimationSpinSpeed() ) + ); + +// bomb.getAnimationOffset(); + + + + messages.add( msg3 ); + + + ExplosionShape shape = ExplosionShape.fromString( bomb.getExplosionShape() ); String messageShape = null; @@ -668,7 +712,7 @@ public void utilsMineBombsList( CommandSender sender, { int lenght = 1 + (bomb.getRadius() * 2); messageShape = String.format( - " &3Shape: &7%s &3Size: &7%d &3x &7%d &3x &7%d &3Based on Radius: &7%d.5", + " &3Shape: &7%s &3Size: &7%d &3x &7%d &3x &7%d &3Based on Radius: &7%d.5", bomb.getExplosionShape(), lenght, lenght, lenght, bomb.getRadius() ); @@ -681,7 +725,7 @@ public void utilsMineBombsList( CommandSender sender, case ring_z: { messageShape = String.format( - " &3Shape: &7%s &3Radius: &7%d.5 &3RadiusInner: &7%d.5", + " &3Shape: &7%s &3Radius: &7%d.5 &3RadiusInner: &7%d.5", bomb.getExplosionShape(), bomb.getRadius(), bomb.getRadiusInner() ); break; } @@ -692,13 +736,13 @@ public void utilsMineBombsList( CommandSender sender, case disk_z: { messageShape = String.format( - " &3Shape: &7%s &3Radius: &7%d.5", + " &3Shape: &7%s &3Radius: &7%d.5", bomb.getExplosionShape(), bomb.getRadius() ); break; } default: { - messageShape = " &4(no shape defined)"; + messageShape = " &4(no shape defined)"; } } if ( messageShape != null && !messageShape.isEmpty() ) { @@ -730,6 +774,36 @@ public void utilsMineBombsList( CommandSender sender, messages.add( " " + bomb.getDescription() ); + if ( bomb.getAllowedMines().size() > 0 ) { + StringBuilder sb = new StringBuilder(); + for (String mineName : bomb.getAllowedMines() ) { + if ( sb.length() > 0 ) { + sb.append( ", " ); + } + sb.append( mineName ); + } + + String msgMines = String.format( + " &3Allowed on in mines: &7%s", + sb.toString() ); + messages.add( msgMines ); + } + if ( bomb.getPreventedMines().size() > 0 ) { + StringBuilder sb = new StringBuilder(); + for (String mineName : bomb.getPreventedMines() ) { + if ( sb.length() > 0 ) { + sb.append( ", " ); + } + sb.append( mineName ); + } + + String msgMines = String.format( + " &3Excluded from mines: &7%s", + sb.toString() ); + messages.add( msgMines ); + } + + if ( optAll ) { @@ -763,6 +837,11 @@ public void utilsMineBombsList( CommandSender sender, // Output.get().log( message, LogLevel.PLAIN ); } + messages.add( f1 ); + messages.add( f2 ); + messages.add( f3 ); + messages.add( f4 ); + sender.sendMessage( messages.toArray( new String[0] ) ); } } @@ -941,23 +1020,6 @@ public void utilsMineBombsGive( CommandSender sender, sender.sendMessage( String.format( message, bombName ) ); } -// if ( "list".equalsIgnoreCase( bombName ) ) { -// -// Set keys = mBombs.getConfigData().getBombs().keySet(); -// for ( String key : keys ) { -// -// MineBombData bomb = mBombs.getConfigData().getBombs().get( key ); -// -// String message = String.format( -// "%-12s %-7s Radius= %s (%s)\n %s", -// bomb.getName(), bomb.getExplosionShape(), Integer.toString(bomb.getRadius()), -// bomb.getItemType(), bomb.getDescription() ); -// -// sender.sendMessage( message ); -// } -// } - - } } } From 1ae0343db6f2ea3fff87d09554e5e190cbd35fda Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 28 Feb 2025 13:40:34 -0500 Subject: [PATCH 257/323] Players: CommandSender: Added a new transient field miscText that can now be used to return a message to the caller. For the command '/mines tp' if a player tries to tp to their current rank's mines, and if that rank does not have any mines connected to it, it will now step back through all prior ranks until it finds a mine to TP the player to. This returns a message that can be used, indicating the current rank, but indicates the next highest rank that had a mine. This message is not yet externalized. Including a TP message indicating where they player has been TP'd to. --- .../prison/mines/commands/MinesCommands.java | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) 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 e92f60e8f..efa78d989 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 @@ -3331,12 +3331,13 @@ else if ( "enable".equalsIgnoreCase( mineSweeper ) && !m.isMineSweeperEnabled() - @Command(identifier = "mines tp", description = "TP to the mine. Will default to the mine's " + + @Command(identifier = "mines tp", onlyPlayers = false, + description = "TP to the mine. Will default to the mine's " + "spawn location if set, but can specify the target [spawn, mine]. Instead of a mine " + "name, 'list' will show all mines you have access to. OPs and console can " + "TP other online players to a specified mine. Access for non-OPs can be setup through " + "'/mines set tpAccessByRank help` is preferred over permissions.", - aliases = "mtp", + aliases = "mtp", altPermissions = {"access-by-rank", "mines.tp", "mines.tp.[mineName]"}) public void mineTp(CommandSender sender, @Arg(name = "mineName", def="", @@ -3404,8 +3405,10 @@ public void mineTp(CommandSender sender, PrisonMines pMines = PrisonMines.getInstance(); Mine m = null; + // Reset the sender's miscText field: + sender.setMiscText( null ); - if ( mineName == null || mineName.trim().isEmpty() ) { + if ( mineName == null || mineName.trim().isEmpty() ) { // Need to find a "correct" mine to TP to. m = (Mine) Prison.get().getPlatform().getPlayerDefaultMine( sender ); @@ -3437,6 +3440,8 @@ public void mineTp(CommandSender sender, Player player = sender.getPlatformPlayer(); + + // This is not working... it should return an online player... Player playerAlt = getOnlinePlayer( playerName ); @@ -3521,6 +3526,14 @@ else if ( playerAlt != null && !player.getName().equalsIgnoreCase( playerAlt.get if ( sender.isPlayer() ) { teleportPlayer( (Player) sender, m, target ); + + String msg = String.format( + "&3Teleported to mine %s. %s", + m.getTag(), + ( sender.getMiscText() == null ? "" : sender.getMiscText() ) + ); + sender.sendMessage( msg ); + // m.teleportPlayerOut( (Player) sender, target ); } else { teleportFailedMsg( sender ); @@ -5888,6 +5901,8 @@ else if ( "*global*".equalsIgnoreCase(mineName) ) { } + @Command(identifier = "mines dump", permissions = "mines.block", onlyPlayers = false, + description = "Temp command for testing: Dumps a mine as a json object.") public void minesDumpCommand(CommandSender sender, @Arg(name = "mineName", description = "The name of the mine to dump") String mineName ) { From b636123438e389616b775ab1c76e71be06dfc30f Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 4 Mar 2025 06:59:13 -0500 Subject: [PATCH 258/323] MineBombs: Added a cooldown exception so cooldowns can now be handled and reported correctly. Before the "bomb not found" message would be used, which was confusing. --- docs/changelog_v3.3.x.md | 5 ++- .../bombs/MineBombCooldownException.java | 37 +++++++++++++++ .../tech/mcprison/prison/bombs/MineBombs.java | 7 ++- .../spigot/utils/PrisonBombListener.java | 45 +++++++++++++++++-- .../spigot/utils/PrisonUtilsMineBombs.java | 30 +++++++++++-- 5 files changed, 116 insertions(+), 8 deletions(-) create mode 100644 prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombCooldownException.java diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 083fd1a4b..b83d0f65d 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.19f 2025-02-28 +# 3.3.0-alpha.19f 2025-03-04 + + +* **MineBombs: Added a cooldown exception so cooldowns can now be handled and reported correctly. Before the "bomb not found" message would be used, which was confusing.** * **MineBombs: Improvements to the command '/prison utils bomb list' command to better format the information and include some missing details.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombCooldownException.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombCooldownException.java new file mode 100644 index 000000000..446d8f699 --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombCooldownException.java @@ -0,0 +1,37 @@ +package tech.mcprison.prison.bombs; + +import tech.mcprison.prison.Prison; + +public class MineBombCooldownException + extends Exception { + + private static final long serialVersionUID = 1L; + + private int cooldownTicks; + + public MineBombCooldownException( int cooldownTicks ) { + super( "Bomb cooldown is in effect. Try again later. Seconds remaining: " + + Prison.getDecimalFormatStaticDouble().format( cooldownTicks / 20.0d ) + ); + + this.cooldownTicks = cooldownTicks; + } + + public String getCooldownSecondsFormatted() { + String results = ""; + + double seconds = getCooldownTicks() / 20.0d; + + results = Prison.getDecimalFormatStaticDouble().format( seconds ); + + return results; + } + + public int getCooldownTicks() { + return cooldownTicks; + } + public void setCooldownTicks(int cooldownTicks) { + this.cooldownTicks = cooldownTicks; + } + +} 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 8999f05d0..726e0e314 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 @@ -268,6 +268,7 @@ public static boolean addPlayerCooldown( Player player, int ticks ) { * @return */ public MineBombData findBombByName( Player player, String bombName ) + throws MineBombCooldownException { MineBombData results = null; @@ -321,7 +322,11 @@ public MineBombData findBombByName( Player player, String bombName ) dbug.append( "&3 CoolDownIsInEffect: " ) .append( cooldownTicks ).append( " ticks remaining" ).append(" &aRejected! &3 " ); - results = null; + + MineBombCooldownException cooldownException = new MineBombCooldownException( cooldownTicks ); + + throw cooldownException; + } } 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 65b367044..1c161b230 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 @@ -19,6 +19,7 @@ import org.bukkit.util.Vector; import tech.mcprison.prison.Prison; +import tech.mcprison.prison.bombs.MineBombCooldownException; import tech.mcprison.prison.bombs.MineBombData; import tech.mcprison.prison.bombs.MineBombs; import tech.mcprison.prison.mines.data.Mine; @@ -83,7 +84,20 @@ public void mineBombPlacementEvent( BlockPlaceEvent event ) { Player player = event.getPlayer(); SpigotPlayer sPlayer = new SpigotPlayer( player ); - MineBombData mineBomb = MineBombs.getInstance().findBombByName( sPlayer, bombName ); + MineBombData mineBomb = null; + + try { + mineBomb = MineBombs.getInstance().findBombByName( sPlayer, bombName); + } + catch (MineBombCooldownException e) { + String msg = e.getLocalizedMessage(); + + sPlayer.sendMessage(msg); + + return; + } + +// MineBombData mineBomb = MineBombs.getInstance().findBombByName( sPlayer, bombName ); PrisonNBTUtil.setNBTString(iStack, @@ -148,7 +162,21 @@ public void mineBombThrowEvent( PlayerInteractEvent event ) { SpigotPlayer sPlayer = new SpigotPlayer( player ); // If the player is on a mine bomb cooldown, then mineBomb will be null: - MineBombData mineBomb = MineBombs.getInstance().findBombByName( sPlayer, bombName ); + + final MineBombData mineBomb; + + try { + mineBomb = MineBombs.getInstance().findBombByName( sPlayer, bombName); + } + catch (MineBombCooldownException e) { + String msg = e.getLocalizedMessage(); + + sPlayer.sendMessage(msg); + + return; + } + +// MineBombData mineBomb = MineBombs.getInstance().findBombByName( sPlayer, bombName ); if ( mineBomb != null ) { @@ -338,7 +366,18 @@ public void bombPlacementEvent( PlayerInteractEvent event ) { SpigotPlayer sPlayer = new SpigotPlayer( player ); // If the player is on a mine bomb cooldown, then mineBomb will be null: - MineBombData mineBomb = MineBombs.getInstance().findBombByName( sPlayer, bombName); + MineBombData mineBomb = null; + + try { + mineBomb = MineBombs.getInstance().findBombByName( sPlayer, bombName); + } + catch (MineBombCooldownException e) { + String msg = e.getLocalizedMessage(); + + sPlayer.sendMessage(msg); + + return; + } if ( mineBomb != null ) { 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 77f5ba5df..3cf58fae0 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 @@ -22,6 +22,7 @@ import tech.mcprison.prison.Prison; import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; import tech.mcprison.prison.autofeatures.AutoFeaturesWrapper; +import tech.mcprison.prison.bombs.MineBombCooldownException; import tech.mcprison.prison.bombs.MineBombData; import tech.mcprison.prison.bombs.MineBombDetonateTask; import tech.mcprison.prison.bombs.MineBombEffectsData; @@ -907,9 +908,22 @@ public void utilsMineBombsGive( CommandSender sender, count = Integer.parseInt( quantity ); - MineBombs mBombs = MineBombs.getInstance(); +// MineBombs mBombs = MineBombs.getInstance(); - MineBombData bomb = mBombs.findBombByName( player, bombName); + MineBombData bomb = null; + + try { + bomb = MineBombs.getInstance().findBombByName( player, bombName); + } + catch (MineBombCooldownException e) { + String msg = e.getLocalizedMessage(); + + player.sendMessage(msg); + + return; + } + +// MineBombData bomb = mBombs.findBombByName( player, bombName); // // Remove color codes from bomb's name for matching: // bombName = Text.stripColor( bombName ); @@ -1141,7 +1155,17 @@ public MineBombData getBombItem( Player player ) { SpigotPlayer sPlayer = new SpigotPlayer( player ); - bomb = MineBombs.getInstance().findBombByName( sPlayer, bombName ); + try { + bomb = MineBombs.getInstance().findBombByName( sPlayer, bombName); + } + catch (MineBombCooldownException e) { + String msg = e.getLocalizedMessage(); + + sPlayer.sendMessage(msg); + + } + +// bomb = MineBombs.getInstance().findBombByName( sPlayer, bombName ); // bomb = getBombItem( bombName ); } From af8726e3a230ee290303f72efd1b411bc33a1184 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 6 Mar 2025 04:27:55 -0500 Subject: [PATCH 259/323] MineBombs: Eliminated cooldowns from the 'utils bomb give' command and from prison checking to see if an items is a mine bomb to determine if the event should be handled. This should get rid of the bug where using bomb give too frequently would result in error messages and lost bombs (if a player is paying for a bomb). --- docs/changelog_v3.3.x.md | 6 +++++- .../java/tech/mcprison/prison/bombs/MineBombs.java | 12 ++++++++++-- .../prison/spigot/utils/PrisonBombListener.java | 5 ++++- .../prison/spigot/utils/PrisonUtilsMineBombs.java | 14 +++++++++++--- 4 files changed, 30 insertions(+), 7 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index b83d0f65d..f4c94d4ba 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.19f 2025-03-04 +# 3.3.0-alpha.19f 2025-03-06 + + +* **MineBombs: Eliminated cooldowns from the 'utils bomb give' command and from prison checking to see if an items is a mine bomb to determine if the event should be handled.** +This should get rid of the bug where using bomb give too frequently would result in error messages and lost bombs (if a player is paying for a bomb). * **MineBombs: Added a cooldown exception so cooldowns can now be handled and reported correctly. Before the "bomb not found" message would be used, which was confusing.** 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 726e0e314..6ff2b14ea 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 @@ -252,6 +252,11 @@ public static boolean addPlayerCooldown( Player player, int ticks ) { // return bombOriginal.clone(); // } + public MineBombData findBombByName( Player player, String bombName ) + throws MineBombCooldownException + { + return findBombByName( player, bombName, true ); + } /** *

This finds a bomb based upon a bombName which may include formatting. @@ -264,10 +269,13 @@ public static boolean addPlayerCooldown( Player player, int ticks ) { * original source. *

* + * @param player * @param bombName + * @param enableCooldown If true, then will force a cooldown on finding minebombs * @return */ - public MineBombData findBombByName( Player player, String bombName ) + public MineBombData findBombByName( Player player, String bombName, + boolean enableCooldown ) throws MineBombCooldownException { MineBombData results = null; @@ -300,7 +308,7 @@ public MineBombData findBombByName( Player player, String bombName ) } } - if ( results != null ) { + if ( results != null && enableCooldown ) { int ticks = results.getCooldownTicks(); int cooldownTicks = MineBombCooldownTask.checkPlayerCooldown( player ); 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 1c161b230..f84e86a67 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 @@ -87,6 +87,7 @@ public void mineBombPlacementEvent( BlockPlaceEvent event ) { MineBombData mineBomb = null; try { + // Placing minebombs: Use cooldowns: mineBomb = MineBombs.getInstance().findBombByName( sPlayer, bombName); } catch (MineBombCooldownException e) { @@ -166,6 +167,7 @@ public void mineBombThrowEvent( PlayerInteractEvent event ) { final MineBombData mineBomb; try { + // Throw minebombs: Use cooldowns: mineBomb = MineBombs.getInstance().findBombByName( sPlayer, bombName); } catch (MineBombCooldownException e) { @@ -369,7 +371,8 @@ public void bombPlacementEvent( PlayerInteractEvent event ) { MineBombData mineBomb = null; try { - mineBomb = MineBombs.getInstance().findBombByName( sPlayer, bombName); + // Player place event. Enable cooldown to limit placing too many bombs: + mineBomb = MineBombs.getInstance().findBombByName( sPlayer, bombName ); } catch (MineBombCooldownException e) { String msg = e.getLocalizedMessage(); 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 3cf58fae0..af56a3b7e 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 @@ -886,8 +886,13 @@ public void utilsMineBombsGive( CommandSender sender, return; } + + // Get a SpigotPlayer object, which will be returned if the player has + // access to those perms too. If ranks are disabled, then allow it to check + // bukkit's offline players. + boolean useOfflinePlayers = true; SpigotPlayer player = checkPlayerPerms( sender, playerName, - "prison.utils.bomb", "prison.utils.bomb.others" ); + "prison.utils.bomb", "prison.utils.bomb.others", useOfflinePlayers ); if ( player != null ) { @@ -913,7 +918,8 @@ public void utilsMineBombsGive( CommandSender sender, MineBombData bomb = null; try { - bomb = MineBombs.getInstance().findBombByName( player, bombName); + // Give command. Do not enable cooldowns: + bomb = MineBombs.getInstance().findBombByName( player, bombName, false ); } catch (MineBombCooldownException e) { String msg = e.getLocalizedMessage(); @@ -1156,7 +1162,9 @@ public MineBombData getBombItem( Player player ) { SpigotPlayer sPlayer = new SpigotPlayer( player ); try { - bomb = MineBombs.getInstance().findBombByName( sPlayer, bombName); + // Checking to see if an item in the player's inventory is a + // minebomb or not. So disable cooldown for this: + bomb = MineBombs.getInstance().findBombByName( sPlayer, bombName, false); } catch (MineBombCooldownException e) { String msg = e.getLocalizedMessage(); From 81e9e98dd746f2f51e4d52d7e7f548ab6f3d5b3f Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 10 Mar 2025 04:14:50 -0400 Subject: [PATCH 260/323] 2025-03-06: MineBombs: Players: Ranks disabled: Made some changes to how players are being loaded in the 'bomb give' command to allow it to work when ranks have been disabled. --- docs/changelog_v3.3.x.md | 3 +++ .../tech/mcprison/prison/spigot/utils/PrisonUtils.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 f4c94d4ba..d22f64d1c 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.19f 2025-03-06 +* **MineBombs: Players: Ranks disabled: Made some changes to how players are being loaded in the 'bomb give' command to allow it to work when ranks have been disabled.** + + * **MineBombs: Eliminated cooldowns from the 'utils bomb give' command and from prison checking to see if an items is a mine bomb to determine if the event should be handled.** This should get rid of the bug where using bomb give too frequently would result in error messages and lost bombs (if a player is paying for a bomb). diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtils.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtils.java index ff0f8300d..b48dd8506 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtils.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtils.java @@ -71,6 +71,10 @@ public boolean isEnabled() { */ abstract protected Boolean initialize(); + protected SpigotPlayer checkPlayerPerms( CommandSender sender, String playerName, + String permsSelf, String permsOthers ) { + return checkPlayerPerms(sender, playerName, permsSelf, permsOthers, false ); + } /** *

This function checks the perms of the player. If the CommandSender has no @@ -91,11 +95,12 @@ public boolean isEnabled() { * @return */ protected SpigotPlayer checkPlayerPerms( CommandSender sender, String playerName, - String permsSelf, String permsOthers ) { + String permsSelf, String permsOthers, + boolean useOfflinePlayers ) { boolean isConsole = !(sender instanceof org.bukkit.entity.Player); - SpigotPlayer player = getSpigotPlayer( playerName, false ); + SpigotPlayer player = getSpigotPlayer( playerName, useOfflinePlayers ); // Player's name was not found then it's either being ran from console, or on self. if ( player == null ) { From 829f0e134e289c112f0ba42866b2afc5bbdfe714 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 10 Mar 2025 05:46:26 -0400 Subject: [PATCH 261/323] BackpackEvent: New api using a backpack event to allow other plugins to hook in to the prison backpack processing which will behave as a new Backpack Integration. This will allow anyone to easily hook in to Prison's generic backpack behavior for auto pickup and autosell. This new event is tied to the new IntegrationBackpackAPI. Basically, to perform a backpack operation on an unknown backpack source, the BackpackEvent collects a list of Inventory objects from the backpack, which allows prison to operate on the generic Inventory, and then it offers the use of a CallBack that will allow the backpack plugin to process the results of the actions against the inventories. --- docs/changelog_v3.3.x.md | 8 +- .../mcprison/prison/spigot/SpigotPrison.java | 30 ++ .../mcprison/prison/spigot/SpigotUtil.java | 15 +- .../prison/spigot/api/BackpackEvent.java | 391 +++++++++++++++++ .../prison/spigot/api/InventoryFullEvent.java | 3 +- .../integrations/IntegrationBackpackAPI.java | 401 ++++++++++++++++++ .../prison/spigot/sellall/SellAllUtil.java | 7 + 7 files changed, 852 insertions(+), 3 deletions(-) create mode 100644 prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/BackpackEvent.java create mode 100644 prison-spigot/src/main/java/tech/mcprison/prison/spigot/integrations/IntegrationBackpackAPI.java diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index d22f64d1c..722e08ea2 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.19f 2025-03-06 +# 3.3.0-alpha.19f 2025-03-10 + + +* **BackpackEvent: New api using a backpack event to allow other plugins to hook in to the prison backpack processing which will behave as a new Backpack Integration.** +This will allow anyone to easily hook in to Prison's generic backpack behavior for auto pickup and autosell. +This new event is tied to the new IntegrationBackpackAPI. Basically, to perform a backpack operation on an unknown backpack source, the BackpackEvent collects a list of Inventory objects from the backpack, which allows prison to operate on the generic Inventory, and then it offers the use of a CallBack that will allow the backpack plugin to process the results of the actions against the inventories. + * **MineBombs: Players: Ranks disabled: Made some changes to how players are being loaded in the 'bomb give' command to allow it to work when ranks have been disabled.** 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 7428b8dac..3cd965045 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 @@ -89,6 +89,7 @@ import tech.mcprison.prison.spigot.economies.TheNewEconomy; import tech.mcprison.prison.spigot.economies.VaultEconomy; import tech.mcprison.prison.spigot.gui.ListenersPrisonManager; +import tech.mcprison.prison.spigot.integrations.IntegrationBackpackAPI; import tech.mcprison.prison.spigot.integrations.IntegrationMinepacksPlugin; import tech.mcprison.prison.spigot.permissions.LuckPermissions; import tech.mcprison.prison.spigot.permissions.LuckPerms5; @@ -992,6 +993,10 @@ private void initIntegrations() { registerIntegration( IntegrationMinepacksPlugin.getInstance() ); registerIntegration( BackpacksUtil.get() ); + // Force the registration since IntegrationPackpackAPI is not based + // upon any other plugin: + registerIntegrationForce( IntegrationBackpackAPI.getInstance() ); + // registerIntegration(new WorldGuard6Integration()); // registerIntegration(new WorldGuard7Integration()); @@ -1033,6 +1038,13 @@ public void reloadIntegrationsPlaceholders() { ph2.deferredInitialization(); } + /** + * This is the normal way to register integrations that are based upon + * other loaded plugins. They must be active, or they will not be + * registered. + * + * @param integration + */ public void registerIntegration(Integration integration) { boolean isRegistered = isIntegrationRegistered( integration ); @@ -1042,6 +1054,24 @@ public void registerIntegration(Integration integration) { PrisonAPI.getIntegrationManager().register(integration, isRegistered, version ); } + + /** + * This should only be used by Integrations that are not based upon another + * plugin, such as the IntegrationBackpackAPI, which any code in any plugin, + * can register dynamically as a backpackAPI listener. + * + * This will always treat it as a successful registration, although that + * does not mean it will be active. + * + * @param integration + */ + public void registerIntegrationForce(Integration integration) { + + boolean isRegistered = true; + String version = "api"; + + PrisonAPI.getIntegrationManager().register(integration, isRegistered, version ); + } private void enableModulesAndCommands() { 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 668295a2d..11b84d96b 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 @@ -52,6 +52,7 @@ import tech.mcprison.prison.spigot.compat.BlockTestStats; import tech.mcprison.prison.spigot.compat.SpigotCompatibility; import tech.mcprison.prison.spigot.game.SpigotWorld; +import tech.mcprison.prison.spigot.integrations.IntegrationBackpackAPI; import tech.mcprison.prison.spigot.integrations.IntegrationMinepacksPlugin; import tech.mcprison.prison.util.Location; import tech.mcprison.prison.util.Text; @@ -298,6 +299,12 @@ public static HashMap addItemToPlayerInventory( } + // Insert overflow in to the backpack API: + if ( overflow.size() > 0 && IntegrationBackpackAPI.getInstance().isEnabled() ) { + overflow = IntegrationBackpackAPI.getInstance().addItemsBukkit( player, overflow ); + } + + // Cannot stick it anywhere else, so return the extras: for ( Integer key : overflow.keySet() ) { ItemStack iStack = overflow.get(key); @@ -419,7 +426,13 @@ public static int itemStackRemoveAll(Player player, XMaterial xMat ) { if ( IntegrationMinepacksPlugin.getInstance().isEnabled() ) { removed += IntegrationMinepacksPlugin.getInstance().itemStackRemoveAll(player, xMat); } - + + + // Then remove from the backpack API: + if ( IntegrationBackpackAPI.getInstance().isEnabled() ) { + removed += IntegrationBackpackAPI.getInstance().itemStackRemoveAll(player, xMat); + } + return removed; } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/BackpackEvent.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/BackpackEvent.java new file mode 100644 index 000000000..37a01f805 --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/BackpackEvent.java @@ -0,0 +1,391 @@ +package tech.mcprison.prison.spigot.api; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +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.Inventory; +import org.bukkit.plugin.EventExecutor; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginManager; + +import tech.mcprison.prison.spigot.SpigotPrison; + +public class BackpackEvent + extends Event + implements Cancellable { + + private Player player; + + private BackpackCallback callback; + + private boolean cancel; + + private final List inventory; + + private BackpackAction action; + + private BackpackResults results; + + /** + *

These backpack actions just represents the Integration's backpack + * function that was called. You may have special processing you would + * like to do before or after handling these events. It's optional. + *

+ * + *
    + * + *
+ */ + public enum BackpackAction { + undefined, + addItems, + smeltItems, + removeAll, + sellItems + } + + /** + *

These are the backpack transaction results which would only be + * valid after the events are fired and the results are being processed + * in the BackpackCallback function. + *

+ * + *
    + *
  • undefined : The status before the backpack inventories are processed.
  • + *
  • noChange : The inventory has not been changed.
  • + *
  • contentsChanged : The inventory contents has been changed.
  • + *
+ */ + public enum BackpackResults { + undefined, // The status before the backpack inventories are processed + noChange, + contentsChanged + } + + public interface BackpackCallback { + public void run(); + } + + /** + *

Warning: BlastUseEvent does not identify the block the player actually hit, so the dummyBlock + * is just a random first block from the explodedBlocks list and may not be the block + * that initiated the explosion event. Such events are identified by + * BlockEventType.CEXplosion. Make sure you do not process the first block twice, + * which is also passed as the org.bukkit.block.Block and the SpigotBlock to prevent have to + * pass nulls. They are the exact same objects. + *

+ * + * Due to this behavior, since BlockBreakEvent's handlers is static, it + * will "share" the handlers (listeners). To prevent this unwanted behavior, + * since prison's BlockBreakEvent listeners will be called, this class + * defines and overrides the the handlers with it's own instance. + * + */ + private static final HandlerList handlers = new HandlerList(); + + public BackpackEvent() { + super(); + + this.player = null; + this.cancel = false; + + this.callback = null; + + this.inventory = new ArrayList<>(); + + this.action = BackpackAction.undefined; + + this.results = BackpackResults.undefined; + } + + public BackpackEvent( Player player ) { + this(); + + this.player = player; + } + + + + + /** + *

This is an example of how to fire this event for a player's backpack + * to take action. This function is flawed because you would need to use + * and access contents of the BackpackEvent, which this function will not + * return. So do not use this static function, but use the 4 lines of code + * as an example in your code. + *

+ * + *

Generally this would not be used in your plugin, but this is how prison + * would fire the event internally. Your plugin could use it too, if it + * would cause the player's inventory to be full. + *

+ * + *

Each time an event is fired, a new instance of the event is created + * so bukkit can pass that instance to all registered listeners. + *

+ * + * @param org.bukkit.entity.Player player + * @return boolean if the event was cancelled + */ + public static boolean fireBackpackEvent( Player player, BackpackAction action ) { + + BackpackEvent bpEvent = new BackpackEvent( player ); + bpEvent.setAction( action ); + + Bukkit.getServer().getPluginManager().callEvent( bpEvent ); + + if ( !bpEvent.fireBackpackEvent() ) { + // You would handle your plugin's actions here if this was called + // in line within your code. + } + + return bpEvent.isCancelled(); + } + + public boolean fireBackpackEvent() { + + Bukkit.getServer().getPluginManager().callEvent( this ); + + return isCancelled(); + } + + + /** + * This is an example of how you would setup a listener in your + * plugin, and how you would use it. It should generally be a class + * with a function of any name. The important key element is that it + * contains a parameter of class BackpackEvent. Specifying an + * @EventHandler annotation is optional, but it's included here to + * show you how you can use it to sent the event's priority. + * + * Dynamically setting the event priority based upon configs is + * beyond the purpose of this example. + * + * Make sure within your function, you put your code that will react + * to when this event is fired. You can refer to other classes + * within your plugin and do whatever you need to do. + * + * Your listener class must implement Listener. + * + */ + public class SampleBackpackListener + implements Listener { + + public SampleBackpackListener() { + super(); + + } + + /** + * This is for demonstration only. Do not use. + */ + public class DemoBackpack { + public DemoBackpack() { + super(); + } + public Inventory getPlayerBackpack( Player player ) { + return player.getInventory(); + } + public void setChanged() {} + public void save() {} + } + + + @EventHandler(priority=EventPriority.NORMAL) + public void onBackpackEvent( BackpackEvent bpEvent ) { + + // If the event has been canceled, then do not process this event + // since another plugin already processed it, or has denied that it + // should be processed. + if ( !bpEvent.isCancelled() ) { + + // Do something with this event here. + // You will have access to all of the functions in the event. + Player player = bpEvent.getPlayer(); + + // Pretend this represents a backpack object, whatever it may be. + // Just using an Object since we don't have your code for your backpacks, + // plus this is just an example. I've added dummy functions to this + // example backpack object so consider whatever you need to use + // with your own backpack. + + // Pretend we call our backpack function, passing the player to get + // the backpack for that player. In your code, the backpack object + // probably has been already created. For this demo, I'm just creating + // this dummy object here: + DemoBackpack backpack = new DemoBackpack(); + + + // Check to ensure the player has a valid backpack(s): + if ( backpack != null ) { + + // This example is just getting the player's inventory, which is wrong, + // for your code, return the inventory object from your backpack. + Inventory inventory = backpack.getPlayerBackpack( player ); + + // If you have more than one inventory object associated with your backpack, + // then add them all to bpEvent.getInventory(). + if ( inventory != null ) { + + // Add your backpack's inventory list. If you have more than one, then + // add them all. + bpEvent.getInventory().add( inventory ); + + + // Then setup your callback, which will run whatever code you need to use + // to process the backpack's action that was performed: + BackpackCallback callback = new BackpackCallback() { + public void run() { + + + switch ( bpEvent.getResults() ) { + case contentsChanged: + + // Process whatever you need to do after prison handles the + // inventory transactions: + backpack.setChanged(); + backpack.save(); + + break; + + default: + break; + } + + + } + }; + + bpEvent.setCallback( callback ); + + + boolean cancel = false; + + if ( cancel ) { + + // Canceling the event will prevent prison from process the backpack action: + bpEvent.setCancelled( true ); + } + // etc... + } + } + } + } + + + /** + * Somewhere in your plugin, you need to register your event listener with + * the Bukkit PluginManager. This is an example of how to do that. + * + * This will register your listener with the EventPriority of NORMAL if you + * have not used the @EventHandler annotation. + * + * When prison fires the InventoryEvent, Bukkit will go through all registered + * event listeners and will call the registered function (the one with the parameter + * that includes InventoryFullEvent) so it can run all of your code that you + * have placed in that function. + * + * Please note that this function is placed in the inner class of + * SampleInventoryFullListener only for demonstration purposes. You do not + * have to put this function, or the registration of your listener in + * your listener class. Generally, you may find it better suited to register + * all of your listeners in your primary plugin class. + * + * As a bonus, I have included a secondary registration at a custom priority + * that is not set by an annotation, but could be set within a config file. + * + */ + public void sampleUsageRegisterListenerEvent() { + + Plugin prison = SpigotPrison.getInstance(); // your plug. Don't use prison. + PluginManager pm = Bukkit.getServer().getPluginManager(); + + SampleBackpackListener sbpListener = new SampleBackpackListener(); + + pm.registerEvents( sbpListener, prison ); + + // Hint: to dynamically control the listener's EventPriority you would use + // the other pm.registerEvents() functions that allows you to set them + // upon registration. + + // WARNING: Do not register both events at the same time, or they will be + // be called twice and could duplicate everything. The following is + // included ONLY to show you how it can be done and is strictly + // for demonstration purposes. It's not needed if you can use + // the pm.registerEvents() function+. + + // The following shows how you can dynamically register your listener with + // a dynamically set EventPriority as defined in a config file. Assume + // that ePriority is based upon such a config that is requesting a LOW priority. + EventPriority ePriority = EventPriority.LOW; + + pm.registerEvent( BackpackEvent.class, sbpListener, ePriority, + new EventExecutor() { + public void execute( Listener l, Event e ) { + + BackpackEvent bpEvent = (BackpackEvent) e; + + ((SampleBackpackListener)l) + .onBackpackEvent( bpEvent ); + } + }, + prison ); + } + } + + + + @Override + public boolean isCancelled() { + return cancel; + } + @Override + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } + + public Player getPlayer() { + return player; + } + + public List getInventory() { + return inventory; + } + + public BackpackCallback getCallback() { + return callback; + } + public void setCallback(BackpackCallback callback) { + this.callback = callback; + } + + public static HandlerList getHandlerList() { + return handlers; + } + public HandlerList getHandlers() { + return handlers; + } + + public BackpackAction getAction() { + return action; + } + public void setAction(BackpackAction action) { + this.action = action; + } + + public BackpackResults getResults() { + return results; + } + public void setResults(BackpackResults results) { + this.results = results; + } + +} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/InventoryFullEvent.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/InventoryFullEvent.java index 7f2da00f9..b19b01af8 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/InventoryFullEvent.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/InventoryFullEvent.java @@ -14,6 +14,7 @@ import org.bukkit.inventory.Inventory; import org.bukkit.inventory.PlayerInventory; import org.bukkit.plugin.EventExecutor; +import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginManager; import tech.mcprison.prison.spigot.SpigotPrison; @@ -190,7 +191,7 @@ public void onInventoryFullEvent( InventoryFullEvent ifEvent ) { */ public void sampleUsageRegisterListenerEvent() { - SpigotPrison prison = SpigotPrison.getInstance(); + Plugin prison = SpigotPrison.getInstance(); // Your plugin. Don't use prison. PluginManager pm = Bukkit.getServer().getPluginManager(); SampleInventoryFullListener sifListener = new SampleInventoryFullListener(); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/integrations/IntegrationBackpackAPI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/integrations/IntegrationBackpackAPI.java new file mode 100644 index 000000000..deee9502a --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/integrations/IntegrationBackpackAPI.java @@ -0,0 +1,401 @@ +package tech.mcprison.prison.spigot.integrations; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Set; + +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +import com.cryptomorin.xseries.XMaterial; + +import tech.mcprison.prison.integration.IntegrationCore; +import tech.mcprison.prison.integration.IntegrationType; +import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.spigot.SpigotUtil; +import tech.mcprison.prison.spigot.api.BackpackEvent; +import tech.mcprison.prison.spigot.api.BackpackEvent.BackpackAction; +import tech.mcprison.prison.spigot.api.BackpackEvent.BackpackResults; +import tech.mcprison.prison.spigot.block.SpigotItemStack; +import tech.mcprison.prison.spigot.inventory.SpigotInventory; +import tech.mcprison.prison.spigot.sellall.SellAllData; +import tech.mcprison.prison.spigot.sellall.SellAllUtil; + +public class IntegrationBackpackAPI + extends IntegrationCore { + + private static IntegrationBackpackAPI instance = null; + + private int registeredListenersCount = 0; + +// private boolean enabled = false; + + private IntegrationBackpackAPI() { + super( "ApiBackpacks", "ApiBackpacks", IntegrationType.BACKPACK ); + +// this.enabled = false; + + } + + + public static IntegrationBackpackAPI getInstance() { + if ( instance == null ) { + synchronized( IntegrationBackpackAPI.class ) { + if ( instance == null ) { + instance = new IntegrationBackpackAPI(); + } + } + } + return instance; + } + + + public boolean isEnabled() { + + HandlerList listeners = BackpackEvent.getHandlerList(); + + int count = listeners.getRegisteredListeners().length; + + boolean enabled = count > 0; + + if ( getRegisteredListenersCount() != count ) { + + String msg = String.format( + "IntegrationBackpackAPI: The active number of Prison's BackpackEvent listeners has changed. " + + "It is now %s and was %s.", + Integer.toString(count), + Integer.toString(getRegisteredListenersCount()) + ); + Output.get().logInfo( msg ); + + setRegisteredListenersCount(count); + } + + return enabled; + } + + + /** + *

For this function, hasIntegrated(), it must always return a value of true, + * although the isEnabled() may return false. The isEnabled() is dynamic and + * may change a few times, depending if the plugin that is listening to that + * event is resetting multiple times. + *

+ * + *

This function is used to determine if it should be listed as an active + * integration or not. This is only set and checked at startup or reloading. + *

+ */ + @Override + public boolean hasIntegrated() { + return true; +// return isEnabled(); + } + + + /** + * Remove reference to Minepacks and then get a new instance, which will basically + * be similar to reloading the integration to Minepacks. + */ + @Override + public void disableIntegration() { + + // Do nothing. Since isEnabled() is based upon having at least one registered + // listener, and it's checked each time any of these functions are used, + // it will be self managing and handle dynamically added and removed listeners. + +// this.enabled = false; + } + + @Override + public String getDisplayName() + { + return super.getDisplayName(); + } + + @Override + public String getPluginSourceURL() { + return "(no ULR avilable since this is an API envent)"; + } + + + + + public int getRegisteredListenersCount() { + return registeredListenersCount; + } + public void setRegisteredListenersCount(int registeredListenersCount) { + this.registeredListenersCount = registeredListenersCount; + } + + + public HashMap addItems( Player player, HashMap items ) { + + HashMap extras = new HashMap<>(); + + if ( items != null && items.size() > 0 && isEnabled() ) { + + BackpackEvent bpEvent = new BackpackEvent( player ); + bpEvent.setAction( BackpackAction.addItems ); + + if ( bpEvent.fireBackpackEvent() ) { + + boolean changedBackpack = false; + + for ( Inventory inv : bpEvent.getInventory() ) { + + if ( inv != null ) { + + for ( SpigotItemStack spigotItemStack : items.values() ) { + + ItemStack iStack = SpigotUtil.prisonItemStackToBukkit( spigotItemStack ); +// ItemStack iStack = spigotItemStack.getBukkitStack(); + + if ( iStack != null ) { + +// extras.putAll( inv.addItem( iStack )); + + HashMap extra = inv.addItem( iStack ); + + Set keys = extra.keySet(); + for ( Integer key : keys ) { + ItemStack entry = extra.get(key); + + extras.put( key, new SpigotItemStack(entry) ); + + changedBackpack = true; + } + + + } + } + + } + + + // Since we are processing multiple occurrences of inventories, then + // we need to reset items to extras so they can be processed in the + // next inventory. + + items.clear(); + items.putAll( extras ); + extras.clear(); + } + + if ( changedBackpack ) { + bpEvent.setResults( BackpackResults.contentsChanged ); + + bpEvent.getCallback().run(); + } + + } + } + + + // All extras will be in items, so move them back to extras: + extras.putAll( items ); + + return extras; + } + + public HashMap addItemsBukkit( Player player, HashMap items ) { + + HashMap extras = new HashMap<>(); + + if ( items != null && items.size() > 0 && isEnabled() ) { + + BackpackEvent bpEvent = new BackpackEvent( player ); + bpEvent.setAction( BackpackAction.addItems ); + + if ( bpEvent.fireBackpackEvent() ) { + + boolean changedBackpack = false; + + for ( Inventory inv : bpEvent.getInventory() ) { + + if ( inv != null ) { + + for ( ItemStack itemStack : items.values() ) { + + if ( itemStack != null ) { + + extras.putAll( inv.addItem( itemStack )); + + changedBackpack = true; + } + } + + } + + // Since we are processing multiple occurrences of inventories, then + // we need to reset items to extras so they can be processed in the + // next inventory. + + items.clear(); + items.putAll( extras ); + extras.clear(); + } + + if ( changedBackpack ) { + bpEvent.setResults( BackpackResults.contentsChanged ); + + bpEvent.getCallback().run(); + } + } + } + + // All extras will be in items, so put them back in extras: + extras.putAll( items ); + + return extras; + } + + public HashMap smeltItems( Player player, XMaterial source, SpigotItemStack destStack ) { + + HashMap extras = new HashMap<>(); + + SpigotItemStack sourceStack = new SpigotItemStack( source.parseItem() ); + + if ( isEnabled() && sourceStack != null && destStack != null ) { + + BackpackEvent bpEvent = new BackpackEvent( player ); + bpEvent.setAction( BackpackAction.smeltItems ); + + if ( bpEvent.fireBackpackEvent() ) { + + boolean changedBackpack = false; + + for ( Inventory inv : bpEvent.getInventory() ) { + + if ( inv != null ) { + + if ( inv.containsAtLeast( sourceStack.getBukkitStack(), 1 ) ) { + + int count = SpigotUtil.itemStackCount( source, inv ); + if ( count > 0 ) { + sourceStack.setAmount( count ); + destStack.setAmount( count ); + + inv.remove( sourceStack.getBukkitStack() ); + + HashMap temp = new HashMap<>(); + temp.put( Integer.valueOf( 0 ), destStack ); + + extras.putAll( addItems( player, temp ) ); + + changedBackpack = true; + } + + } + } + + + // Since we are smeltings, extras will be the results of the smelt, + // and as such, for multiple inventories, they can be combined in to + // one extras object without having to reset it each time. + + } + + if ( changedBackpack ) { + bpEvent.setResults( BackpackResults.contentsChanged ); + + bpEvent.getCallback().run(); + } + + } + + } + + return extras; + } + + /** + *

Removes a given XMaterial from the Minepack's backpack if it exists. + * This function returns the number of items that were removed. + *

+ * + * @param player + * @param xMat + * @return + */ + public int itemStackRemoveAll(Player player, XMaterial xMat) { + int removed = 0; + + if ( xMat != null && isEnabled() ) { + + BackpackEvent bpEvent = new BackpackEvent( player ); + bpEvent.setAction( BackpackAction.removeAll ); + + if ( bpEvent.fireBackpackEvent() ) { + + boolean changedBackpack = false; + + for ( Inventory inv : bpEvent.getInventory() ) { + + if ( inv != null ) { + + removed += SpigotUtil.itemStackRemoveAll( xMat, inv ); + + if ( removed > 0 ) { + + changedBackpack = true; + } + } + + } + + if ( changedBackpack ) { + bpEvent.setResults( BackpackResults.contentsChanged ); + + bpEvent.getCallback().run(); + } + } + + } + return removed; + } + + + public List sellInventoryItems( Player player, double multiplier ) { + List soldItems = new ArrayList<>(); + + if ( isEnabled() ) { + + BackpackEvent bpEvent = new BackpackEvent( player ); + bpEvent.setAction( BackpackAction.removeAll ); + + if ( bpEvent.fireBackpackEvent() ) { + + boolean changedBackpack = false; + + for ( Inventory inv : bpEvent.getInventory() ) { + + if ( inv != null ) { + + SpigotInventory sInventory = new SpigotInventory( inv ); + + soldItems.addAll( SellAllUtil.get().sellInventoryItems( sInventory, multiplier ) ); + + if ( soldItems.size() > 0 ) { + + changedBackpack = true; + } + } + } + + if ( changedBackpack ) { + bpEvent.setResults( BackpackResults.contentsChanged ); + + bpEvent.getCallback().run(); + } + } + + } + + return soldItems; + } + +} 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 fe46356b4..16d30efa3 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 @@ -41,6 +41,7 @@ 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.IntegrationBackpackAPI; import tech.mcprison.prison.spigot.integrations.IntegrationMinepacksPlugin; import tech.mcprison.prison.spigot.inventory.SpigotPlayerInventory; import tech.mcprison.prison.util.Text; @@ -1098,10 +1099,16 @@ public List sellPlayerItems(Player p) { soldData.addAll( bpUtil.sellInventoryItems( p, multiplier ) ); } + // Enable sellall for the Minepacks plugin: if ( isSellAllMinesBackpacksPluginEnabled && IntegrationMinepacksPlugin.getInstance().isEnabled() ) { soldData.addAll( IntegrationMinepacksPlugin.getInstance().sellInventoryItems( p, multiplier ) ); } + // Enable sellall for the backpack API: + if ( isSellAllMinesBackpacksPluginEnabled && IntegrationBackpackAPI.getInstance().isEnabled() ) { + soldData.addAll( IntegrationBackpackAPI.getInstance().sellInventoryItems( p, multiplier ) ); + } + return soldData; } From 6494ee7acb23118bda4ea2d0d981f2af8956c15f Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 15 Mar 2025 17:34:01 -0400 Subject: [PATCH 262/323] Sellall: Ran in to a situation where an ItemStack that was being processed did not have a bukkit ItemStack internally, so it was causing an NPE. This fixes the issue by checking to ensure the bukkit ItemStack exists first. --- docs/changelog_v3.3.x.md | 7 ++++++- .../prison/spigot/block/SpigotItemStack.java | 13 ++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 722e08ea2..9cb43d35d 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.19f 2025-03-10 +# 3.3.0-alpha.19f 2025-03-12 + + +* **Sellall: Ran in to a situation where an ItemStack that was being processed did not have a bukkit ItemStack internally, so it was causing an NPE. ** +This fixes the issue by checking to ensure the bukkit ItemStack exists first. + * **BackpackEvent: New api using a backpack event to allow other plugins to hook in to the prison backpack processing which will behave as a new Backpack Integration.** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/SpigotItemStack.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/SpigotItemStack.java index 69b452177..d02649c7e 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/SpigotItemStack.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/SpigotItemStack.java @@ -401,11 +401,14 @@ public void addToAmount( int i ) { private ItemMeta getMeta() { - ItemMeta meta; - if (!bukkitStack.hasItemMeta()) { - meta = Bukkit.getItemFactory().getItemMeta(bukkitStack.getType()); - } else { - meta = bukkitStack.getItemMeta(); + ItemMeta meta = null; + + if ( getBukkitStack() != null ) { + if (!getBukkitStack().hasItemMeta()) { + meta = Bukkit.getItemFactory().getItemMeta(getBukkitStack().getType()); + } else { + meta = getBukkitStack().getItemMeta(); + } } return meta; From 0c69b78bb9c87356a5632ac9c2199593571c3a5e Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 15 Mar 2025 17:40:21 -0400 Subject: [PATCH 263/323] MineBombs: Added the new cooldown message that is in the MineBombCooldownException to the core messages. --- docs/changelog_v3.3.x.md | 5 +++- .../bombs/MineBombCooldownException.java | 6 +++-- .../prison/bombs/MineBombMessages.java | 20 +++++++++++++++ .../main/resources/lang/core/de_DE.properties | 6 ++++- .../main/resources/lang/core/en_GB.properties | 6 ++++- .../main/resources/lang/core/en_US.properties | 6 ++++- .../main/resources/lang/core/es_ES.properties | 25 +++++++++++++++++-- .../main/resources/lang/core/fi_FI.properties | 5 +++- .../main/resources/lang/core/fr_FR.properties | 5 +++- .../main/resources/lang/core/hu_HU.properties | 5 +++- .../main/resources/lang/core/it_IT.properties | 5 +++- .../main/resources/lang/core/nl_BE.properties | 5 +++- .../main/resources/lang/core/nl_NL.properties | 5 +++- .../main/resources/lang/core/pt_PT.properties | 5 +++- .../main/resources/lang/core/zh_CN.properties | 7 +++++- .../main/resources/lang/core/zh_TW.properties | 5 +++- 16 files changed, 104 insertions(+), 17 deletions(-) create mode 100644 prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombMessages.java diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 9cb43d35d..5f31de0c4 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.19f 2025-03-12 +# 3.3.0-alpha.19f 2025-03-15 + + +* **MineBombs: Added the new cooldown message that is in the MineBombCooldownException to the core messages.** * **Sellall: Ran in to a situation where an ItemStack that was being processed did not have a bukkit ItemStack internally, so it was causing an NPE. ** diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombCooldownException.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombCooldownException.java index 446d8f699..a753417b4 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombCooldownException.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombCooldownException.java @@ -10,9 +10,11 @@ public class MineBombCooldownException private int cooldownTicks; public MineBombCooldownException( int cooldownTicks ) { - super( "Bomb cooldown is in effect. Try again later. Seconds remaining: " + - Prison.getDecimalFormatStaticDouble().format( cooldownTicks / 20.0d ) + super( MineBombMessages.mineBombsCoolDownMsg( cooldownTicks ) ); +// super( "Bomb cooldown is in effect. Try again later. Seconds remaining: " + +// Prison.getDecimalFormatStaticDouble().format( cooldownTicks / 20.0d ) +// ); this.cooldownTicks = cooldownTicks; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombMessages.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombMessages.java new file mode 100644 index 000000000..58451dd75 --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombMessages.java @@ -0,0 +1,20 @@ +package tech.mcprison.prison.bombs; + +import java.text.DecimalFormat; + +import tech.mcprison.prison.Prison; + +public class MineBombMessages { + + static public String mineBombsCoolDownMsg( int cooldownTicks ) { + + double cooldownSeconds = cooldownTicks / 20.0f; + DecimalFormat dFmt = Prison.get().getDecimalFormat( "0.0" ); + + return Prison.get().getLocaleManager() + .getLocalizable( "core_minebombs__cooldown_delay" ) + .withReplacements( + dFmt.format(cooldownSeconds) ) + .localize(); + } +} 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 fa3866cf2..7f986035d 100644 --- a/prison-core/src/main/resources/lang/core/de_DE.properties +++ b/prison-core/src/main/resources/lang/core/de_DE.properties @@ -79,7 +79,7 @@ # like to share, please contact a staff member on our Discord server. #Thanks for your contributions! # -messages__version=10 +messages__version=11 messages__auto_refresh=true @@ -232,3 +232,7 @@ core_ranks_topn__player_line_2_detail_format= [-3] [-10] [7] [-18] [9] core_ranks_topn__player_line_2_detail_values={rankPosition}, {prestigeDefaultRankTagNoColor}, {rankScore}, {playerName}, {balanceKmbt} +## Please note there is another similar message in the spigot module: +## spigot_minebombs__cooldown_delay +core_minebombs__cooldown_delay=You cannot use another Prison Mine Bomb for %1 seconds. + 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 469ec9e69..630cb8cdb 100644 --- a/prison-core/src/main/resources/lang/core/en_GB.properties +++ b/prison-core/src/main/resources/lang/core/en_GB.properties @@ -76,7 +76,7 @@ # like to share, please contact a staff member on our Discord server. #Thanks for your contributions! # -messages__version=10 +messages__version=11 messages__auto_refresh=true @@ -232,3 +232,7 @@ core_ranks_topn__player_line_2_detail_format= [-3] [-10] [7] [-18] [9] core_ranks_topn__player_line_2_detail_values={rankPosition}, {prestigeDefaultRankTagNoColor}, {rankScore}, {playerName}, {balanceKmbt} +## Please note there is another similar message in the spigot module: +## spigot_minebombs__cooldown_delay +core_minebombs__cooldown_delay=You cannot use another Prison Mine Bomb for %1 seconds. + 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 19f7bb39a..58c4e21a3 100644 --- a/prison-core/src/main/resources/lang/core/en_US.properties +++ b/prison-core/src/main/resources/lang/core/en_US.properties @@ -76,7 +76,7 @@ # like to share, please contact a staff member on our Discord server. #Thanks for your contributions! # -messages__version=11 +messages__version=12 messages__auto_refresh=true @@ -232,4 +232,8 @@ core_ranks_topn__player_line_2_detail_format= [-3] [-10] [7] [-18] [9] core_ranks_topn__player_line_2_detail_values={rankPosition}, {prestigeDefaultRankTagNoColor}, {rankScore}, {playerName}, {balanceKmbt} +## Please note there is another similar message in the spigot module: +## spigot_minebombs__cooldown_delay +core_minebombs__cooldown_delay=You cannot use another Prison Mine Bomb for %1 seconds. + 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 f7ceb5748..41e3dfc3d 100644 --- a/prison-core/src/main/resources/lang/core/es_ES.properties +++ b/prison-core/src/main/resources/lang/core/es_ES.properties @@ -76,9 +76,10 @@ # like to share, please contact a staff member on our Discord server. #Thanks for your contributions! # -messages__version=11 +messages__version=12 messages__auto_refresh=true + core_output__prefix_template=| %1 | &7 core_output__prefix_template_prison=Prisión core_output__prefix_template_info=Información @@ -94,6 +95,7 @@ core_output__color_code_debug=&b core_output__error_startup_failure=Prisión: (Enviando a System.err debido a falla en el registro de salida): core_output__error_incorrect_number_of_parameters=Falla en el registro (%1): Número incorrecto de parámetros: [%2] Mensaje en bruto original: [%3] Argumentos: %4 + core_text__prefix=&3 core_text__just_now=justo ahora core_text__ago=hace @@ -104,6 +106,7 @@ core_text__time_units_singular=año,mes,semana,día,hora,minuto,segundo core_text__time_units_plural=años,meses,semanas,días,horas,minutos,segundos core_text__time_units_short=a,m,s,d,h,m,s + core_tokens__name_required=Tokens de la Prisión=Se requiere un nombre de jugador cuando se usa desde la consola. core_tokens__cannot_view_others_balances=Tokens de la Prisión: No tienes permiso para ver los saldos de otros jugadores. core_tokens__view_balance=&3%1 tiene %2 tokens. @@ -112,11 +115,14 @@ core_tokens__added_amount=&3%1 ahora tiene &7%2 &3tokens después de agregar &7% core_tokens__removed_amount=&3%1 ahora tiene &7%2 &3tokens después de eliminar &7%3&3. core_tokens__set_amount=&3%1 ahora tiene &7%2 &3tokens. + core_runCmd__name_required=Se requiere un nombre de jugador válido. core_runCmd__command_required=Se requiere un comando. + core_prison_utf8_test=Привет! Давай поÑмотрим, работает ли? Test 01 + # The following are the original messages and they will eventually be replaced. includeError=[%1] tiene un valor inválido. @@ -144,6 +150,7 @@ worldNotFound=El mundo %1 no se encontró. core_gui__click_to_decrease=&3Haz clic para disminuir. core_gui__click_to_increase=&3Haz clic para aumentar. + core_gui__click_to_cancel=&3Haz clic para cancelar. core_gui__click_to_close=&3Haz clic para cerrar. core_gui__click_to_confirm=&3Haz clic para confirmar. @@ -153,21 +160,25 @@ core_gui__click_to_edit=&3Haz clic para editar. core_gui__click_to_enable=&3Haz clic para habilitar. core_gui__click_to_open=&3Haz clic para abrir. + core_gui__left_click_to_confirm=&3Haz clic izquierdo para confirmar. core_gui__left_click_to_reset=&3Haz clic izquierdo para restablecer. core_gui__left_click_to_open=&3Haz clic izquierdo para abrir. core_gui__left_click_to_edit=&3Haz clic izquierdo para editar. + core_gui__right_click_to_cancel=&3Haz clic derecho para cancelar. core_gui__right_click_to_delete=&3Haz clic derecho para eliminar. core_gui__right_click_to_disable=&3Haz clic derecho para desactivar. core_gui__right_click_to_enable=&3Haz clic derecho para habilitar. core_gui__right_click_to_toggle=&3Haz clic derecho para alternar. + core_gui__right_click_and_shift_to_delete=&3Haz clic derecho y shift para eliminar. core_gui__right_click_and_shift_to_disable=&3Haz clic derecho y shift para desactivar. core_gui__right_click_and_shift_to_toggle=&3Haz clic derecho y shift para alternar. + core_gui__page_next=&3Página siguiente. core_gui__page_prior=&3Página anterior. @@ -183,6 +194,7 @@ core_gui__page_tools_current_page=&3Página actual: {current_page} de {last_page core_gui__page_tools_next_page=&3Página siguiente: {next_page} de {last_page} core_gui__page_tools_last_page=&3Última página: {last_page} de {last_page} + core_gui__money_earned=&3Ganaste &a$%1 core_gui__price=&3Precio: %1 core_gui__confirm=&3Confirmar: %1 %2 @@ -192,6 +204,10 @@ core_gui__value=&3Valor: %1 core_gui__permission=&3Permiso: &7%1 core_gui__prestige_name=&3Nombre de prestigio: %1 + + + + # For format, the edit codes need to be within []. A number defines the width # and negative numbers will left justify the values with padding. An empty [] # will not add any padding. All values are treated as strings. @@ -213,4 +229,9 @@ core_ranks_topn__player_line_2_header_values=Rango, Rangos, r-Score, Jugador, Ba core_ranks_topn__player_line_1_detail_format= [-4] [-18] [-12] [10] [7] [10] core_ranks_topn__player_line_1_detail_values={rankPosition}, {playerName}, {prestigeDefaultRankTagNoColor}, {balanceKmbt}, {rankScore}, {rankScorePenalty} core_ranks_topn__player_line_2_detail_format= [-3] [-10] [7] [-18] [9] -core_ranks_topn__player_line_2_detail_values={rankPosition}, {prestigeDefaultRankTagNoColor}, {rankScore}, {playerName}, {balanceKmbt} \ No newline at end of file +core_ranks_topn__player_line_2_detail_values={rankPosition}, {prestigeDefaultRankTagNoColor}, {rankScore}, {playerName}, {balanceKmbt} + + +## Please note there is another similar message in the spigot module: +## spigot_minebombs__cooldown_delay +core_minebombs__cooldown_delay=You cannot use another Prison Mine Bomb for %1 seconds. 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 10574cbf5..735000ce3 100644 --- a/prison-core/src/main/resources/lang/core/fi_FI.properties +++ b/prison-core/src/main/resources/lang/core/fi_FI.properties @@ -76,7 +76,7 @@ # like to share, please contact a staff member on our Discord server. #Thanks for your contributions! # -messages__version=11 +messages__version=12 messages__auto_refresh=true @@ -232,3 +232,6 @@ core_ranks_topn__player_line_2_detail_format= [-3] [-10] [7] [-18] [9] core_ranks_topn__player_line_2_detail_values={rankPosition}, {prestigeDefaultRankTagNoColor}, {rankScore}, {playerName}, {balanceKmbt} +## Please note there is another similar message in the spigot module: +## spigot_minebombs__cooldown_delay +core_minebombs__cooldown_delay=You cannot use another Prison Mine Bomb for %1 seconds. 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 a9d319fad..b45c2bd32 100644 --- a/prison-core/src/main/resources/lang/core/fr_FR.properties +++ b/prison-core/src/main/resources/lang/core/fr_FR.properties @@ -76,7 +76,7 @@ # like to share, please contact a staff member on our Discord server. #Thanks for your contributions! # -messages__version=11 +messages__version=12 messages__auto_refresh=true @@ -232,3 +232,6 @@ core_ranks_topn__player_line_2_detail_format= [-3] [-10] [7] [-18] [9] core_ranks_topn__player_line_2_detail_values={rankPosition}, {prestigeDefaultRankTagNoColor}, {rankScore}, {playerName}, {balanceKmbt} +## Please note there is another similar message in the spigot module: +## spigot_minebombs__cooldown_delay +core_minebombs__cooldown_delay=You cannot use another Prison Mine Bomb for %1 seconds. 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 7e4062aa0..85059ca8d 100644 --- a/prison-core/src/main/resources/lang/core/hu_HU.properties +++ b/prison-core/src/main/resources/lang/core/hu_HU.properties @@ -76,7 +76,7 @@ # like to share, please contact a staff member on our Discord server. #Thanks for your contributions! # -messages__version=10 +messages__version=11 messages__auto_refresh=true @@ -232,3 +232,6 @@ core_ranks_topn__player_line_2_detail_format= [-3] [-10] [7] [-18] [9] core_ranks_topn__player_line_2_detail_values={rankPosition}, {prestigeDefaultRankTagNoColor}, {rankScore}, {playerName}, {balanceKmbt} +## Please note there is another similar message in the spigot module: +## spigot_minebombs__cooldown_delay +core_minebombs__cooldown_delay=You cannot use another Prison Mine Bomb for %1 seconds. 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 1a2f28993..08f1fbe6e 100644 --- a/prison-core/src/main/resources/lang/core/it_IT.properties +++ b/prison-core/src/main/resources/lang/core/it_IT.properties @@ -76,7 +76,7 @@ # like to share, please contact a staff member on our Discord server. #Thanks for your contributions! # -messages__version=10 +messages__version=11 messages__auto_refresh=true @@ -232,3 +232,6 @@ core_ranks_topn__player_line_2_detail_format= [-3] [-10] [7] [-18] [9] core_ranks_topn__player_line_2_detail_values={rankPosition}, {prestigeDefaultRankTagNoColor}, {rankScore}, {playerName}, {balanceKmbt} +## Please note there is another similar message in the spigot module: +## spigot_minebombs__cooldown_delay +core_minebombs__cooldown_delay=You cannot use another Prison Mine Bomb for %1 seconds. 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 4ad3da75f..279e7f2d7 100644 --- a/prison-core/src/main/resources/lang/core/nl_BE.properties +++ b/prison-core/src/main/resources/lang/core/nl_BE.properties @@ -76,7 +76,7 @@ # like to share, please contact a staff member on our Discord server. #Thanks for your contributions! # -messages__version=10 +messages__version=11 messages__auto_refresh=true @@ -232,4 +232,7 @@ core_ranks_topn__player_line_2_detail_format= [-3] [-10] [7] [-18] [9] core_ranks_topn__player_line_2_detail_values={rankPosition}, {prestigeDefaultRankTagNoColor}, {rankScore}, {playerName}, {balanceKmbt} +## Please note there is another similar message in the spigot module: +## spigot_minebombs__cooldown_delay +core_minebombs__cooldown_delay=You cannot use another Prison Mine Bomb for %1 seconds. 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 88f1a3261..9421dca6a 100644 --- a/prison-core/src/main/resources/lang/core/nl_NL.properties +++ b/prison-core/src/main/resources/lang/core/nl_NL.properties @@ -76,7 +76,7 @@ # like to share, please contact a staff member on our Discord server. #Thanks for your contributions! # -messages__version=10 +messages__version=11 messages__auto_refresh=true @@ -232,3 +232,6 @@ core_ranks_topn__player_line_2_detail_format= [-3] [-10] [7] [-18] [9] core_ranks_topn__player_line_2_detail_values={rankPosition}, {prestigeDefaultRankTagNoColor}, {rankScore}, {playerName}, {balanceKmbt} +## Please note there is another similar message in the spigot module: +## spigot_minebombs__cooldown_delay +core_minebombs__cooldown_delay=You cannot use another Prison Mine Bomb for %1 seconds. 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 30f5072b9..3e2961b16 100644 --- a/prison-core/src/main/resources/lang/core/pt_PT.properties +++ b/prison-core/src/main/resources/lang/core/pt_PT.properties @@ -76,7 +76,7 @@ # like to share, please contact a staff member on our Discord server. #Thanks for your contributions! # -messages__version=6 +messages__version=7 messages__auto_refresh=true @@ -232,3 +232,6 @@ core_ranks_topn__player_line_2_detail_format= [-3] [-10] [7] [-18] [9] core_ranks_topn__player_line_2_detail_values={rankPosition}, {prestigeDefaultRankTagNoColor}, {rankScore}, {playerName}, {balanceKmbt} +## Please note there is another similar message in the spigot module: +## spigot_minebombs__cooldown_delay +core_minebombs__cooldown_delay=You cannot use another Prison Mine Bomb for %1 seconds. 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 3a55dba0a..3e6715b95 100644 --- a/prison-core/src/main/resources/lang/core/zh_CN.properties +++ b/prison-core/src/main/resources/lang/core/zh_CN.properties @@ -76,7 +76,7 @@ # like to share, please contact a staff member on our Discord server. #Thanks for your contributions! # -messages__version=11 +messages__version=12 messages__auto_refresh=true @@ -230,3 +230,8 @@ core_ranks_topn__player_line_1_detail_format= [-4] [-18] [-12] [10] [7] [10] core_ranks_topn__player_line_1_detail_values={rankPosition}, {playerName}, {prestigeDefaultRankTagNoColor}, {balanceKmbt}, {rankScore}, {rankScorePenalty} core_ranks_topn__player_line_2_detail_format= [-3] [-10] [7] [-18] [9] core_ranks_topn__player_line_2_detail_values={rankPosition}, {prestigeDefaultRankTagNoColor}, {rankScore}, {playerName}, {balanceKmbt} + + +## Please note there is another similar message in the spigot module: +## spigot_minebombs__cooldown_delay +core_minebombs__cooldown_delay=You cannot use another Prison Mine Bomb for %1 seconds. 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 d8daac534..5eaa9056a 100644 --- a/prison-core/src/main/resources/lang/core/zh_TW.properties +++ b/prison-core/src/main/resources/lang/core/zh_TW.properties @@ -76,7 +76,7 @@ # like to share, please contact a staff member on our Discord server. #Thanks for your contributions! # -messages__version=10 +messages__version=11 messages__auto_refresh=true @@ -232,4 +232,7 @@ core_ranks_topn__player_line_2_detail_format= [-3] [-10] [7] [-18] [9] core_ranks_topn__player_line_2_detail_values={rankPosition}, {prestigeDefaultRankTagNoColor}, {rankScore}, {playerName}, {balanceKmbt} +## Please note there is another similar message in the spigot module: +## spigot_minebombs__cooldown_delay +core_minebombs__cooldown_delay=You cannot use another Prison Mine Bomb for %1 seconds. From d45f70ba820bcbbfb450692e00d3b0258290c273 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 16 Mar 2025 06:20:49 -0400 Subject: [PATCH 264/323] Ranks: Fixed a few issues with '/ranks player' be issued by the player. Added last seen date to the player objects. --- docs/changelog_v3.3.x.md | 6 ++- .../prison/internal/OfflineMcPlayer.java | 11 +++--- .../tech/mcprison/prison/internal/Player.java | 8 ++++ .../prison/ranks/data/RankPlayer.java | 11 ++++++ .../java/tech/mcprison/prison/TestPlayer.java | 5 +++ .../prison/ranks/commands/RanksCommands.java | 38 ++++++++++++++++--- .../spigot/game/SpigotOfflinePlayer.java | 6 +++ .../prison/spigot/game/SpigotPlayer.java | 12 +++++- 8 files changed, 83 insertions(+), 14 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 5f31de0c4..46c5bf8b6 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.19f 2025-03-15 +# 3.3.0-alpha.19f 2025-03-16 + + +* **Ranks: Fixed a few issues with '/ranks player' be issued by the player.** +Added last seen date to the player objects. * **MineBombs: Added the new cooldown message that is in the MineBombCooldownException to the core messages.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/OfflineMcPlayer.java b/prison-core/src/main/java/tech/mcprison/prison/internal/OfflineMcPlayer.java index 6f99e3da0..ff6e92b0f 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/OfflineMcPlayer.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/OfflineMcPlayer.java @@ -7,23 +7,24 @@ public interface OfflineMcPlayer /** * Returns the unique identifier for this player. */ - UUID getUUID(); + public UUID getUUID(); /** * Returns the player's display name (nickname), which may include colors. */ - String getDisplayName(); + public String getDisplayName(); /** * Sets the player's display name (nickname). * * @param newDisplayName The new display name. May include colors, amp-prefixed. */ - void setDisplayName(String newDisplayName); + public void setDisplayName(String newDisplayName); /** * @return Returns true if the player is online, false otherwise. */ - boolean isOnline(); - + public boolean isOnline(); + + } diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/Player.java b/prison-core/src/main/java/tech/mcprison/prison/internal/Player.java index 5a390b45b..2a49849b6 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/Player.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/Player.java @@ -178,6 +178,14 @@ public default boolean doesSupportColors() { public void incrementMinecraftStatsDropCount( Player player, String blockName, int quantity); + /** + * Returns the bukkit's last seen date as a long. + * + * @return + */ + public long getLastSeenDate(); + + // public RankPlayer getRankPlayer(); } 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 382540239..f71c01cdf 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 @@ -348,6 +348,17 @@ public long getLastSeenDateTemp() { public void setLastSeenDateTemp(long lastSeenDate) { this.lastSeenDate = lastSeenDate; } + /** + * Returns the bukkit's last seen date as a long. + * + * Returns the save value as getLastSeenDateTemp(). + * @return + */ + public long getLastSeenDate() { + return lastSeenDate; + } + + public void updateTotalLastValues( PlayerCachePlayerData cacheData ) { updateTotalLastValues( cacheData, true ); diff --git a/prison-core/src/test/java/tech/mcprison/prison/TestPlayer.java b/prison-core/src/test/java/tech/mcprison/prison/TestPlayer.java index e66257ad1..52098f0db 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/TestPlayer.java +++ b/prison-core/src/test/java/tech/mcprison/prison/TestPlayer.java @@ -304,4 +304,9 @@ public String getMiscText() { @Override public void setMiscText( String text ) { } + + @Override + public long getLastSeenDate() { + return 0; + } } 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 210215e43..f344df94f 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 @@ -1641,7 +1641,11 @@ public void rankPlayer(CommandSender sender, DecimalFormat pFmt = Prison.get().getDecimalFormat("#,##0.0000"); SimpleDateFormat sdFmt = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ); + + // need to see if the player is offline or online: + Player offlinePlayer = Prison.get().getPlatform().getOfflinePlayer( rankPlayer.getUUID() ).orElse( null ); + //PlayerManager pm = PrisonRanks.getInstance().getPlayerManager(); // RankPlayer rankPlayer = player.getRankPlayer(); // RankPlayer rankPlayer = pm.getPlayer(player.getUUID(), player.getName()); @@ -1655,6 +1659,18 @@ public void rankPlayer(CommandSender sender, rankPlayer.getName() ); msgs.add( msg1 ); + + if ( offlinePlayer != null && cPlayer != null ) { + if ( cPlayer.getLastSeenDate() < offlinePlayer.getLastSeenDate() ) { + cPlayer.setLastSeenDate( offlinePlayer.getLastSeenDate() ); + cPlayer.setDirty( true ); + } + + if ( rankPlayer.getLastSeenDate() < offlinePlayer.getLastSeenDate() ) { + rankPlayer.setLastSeenDateTemp( offlinePlayer.getLastSeenDate() ); + rankPlayer.setDirty( true ); + } + } String lastSeen = cPlayer == null || cPlayer.getLastSeenDate() == 0 ? @@ -1769,12 +1785,12 @@ public void rankPlayer(CommandSender sender, } - boolean isOp = rankPlayer.isOp(); - boolean isPlayer = rankPlayer.isPlayer(); - boolean isOnline = rankPlayer.isOnline(); + boolean isOp = offlinePlayer != null ? offlinePlayer.isOp() : rankPlayer.isOp(); + boolean isPlayer = offlinePlayer != null ? offlinePlayer.isPlayer() : rankPlayer.isPlayer(); + boolean isOnline = offlinePlayer != null ? offlinePlayer.isOnline() : rankPlayer.isOnline(); boolean isPrisonPlayer = (rankPlayer instanceof Player); - boolean isPrisonOfflineMcPlayer = (rankPlayer instanceof OfflineMcPlayer); + boolean isPrisonOfflineMcPlayer = offlinePlayer != null ? true : (rankPlayer instanceof OfflineMcPlayer); if ( !isOnline ) { String msgOffline = ranksPlayerPermsOfflineMsg(); @@ -2649,11 +2665,14 @@ private boolean contains( String search, String... values ) { /** - * This gets the RankPlayer for the given UUID or playerName. The 'sender' generally is the + *

This gets the RankPlayer for the given UUID or playerName. The 'sender' generally is the * console, or an admin that is trying to run the command for a player. * So although the sender has a 'getRankPlayer()' function, it may be for the wrong player. + *

* - + *

If both the uuid and playerName are either null or empty, then if the sender + * is a player, then get the RankPlayer from the sender. + *

* * @param sender The one who should get an messages, but is not the one for RankPlayer. * @param playerUuid @@ -2662,6 +2681,13 @@ private boolean contains( String search, String... values ) { */ public RankPlayer getRankPlayer( CommandSender sender, UUID playerUuid, String playerName ) { + // If player name and uuid are both empty or null, and if sender is a player, + // then get the RankPlayer from the sender: + if ( (playerName == null || playerName.trim().length() == 0) && + playerUuid == null && sender.isPlayer() ) { + return sender.getRankPlayer(); + } + RankPlayer player = PrisonRanks.getInstance().getPlayerManager().getPlayer(playerUuid, playerName); // Well, this isn't supposed to happen... diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java index f03ec30ef..92f1a6576 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java @@ -141,6 +141,12 @@ public boolean isOnline() { // return false; } + + @Override + public long getLastSeenDate() { + return offlinePlayer.getLastPlayed(); + } + /** * NOTE: A SpigotOfflinePlayer does not represent an online player with inventory. * This class is not "connected" to the underlying bukkit player 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 0cbc3026e..6985af781 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 @@ -345,11 +345,13 @@ public org.bukkit.entity.Player getWrapper() { public Inventory getInventory() { return getSpigotPlayerInventory(); } + public SpigotPlayerInventory getSpigotPlayerInventory() { return new SpigotPlayerInventory(getWrapper().getInventory()); } - @Override public void updateInventory() { + @Override + public void updateInventory() { bukkitPlayer.updateInventory(); } @@ -362,6 +364,12 @@ public void recalculatePermissions() { public boolean isPlayer() { return true; } + + + @Override + public long getLastSeenDate() { + return bukkitPlayer.getLastPlayed(); + } // @Override // public boolean isOp() { @@ -441,7 +449,7 @@ public String toString() { return sb.toString(); } - + // /** // * This class is an adaptation of the NmsHelper class in the Rosetta library by Max Roncace. The From b7aa5025ba4f7aa3e3db495c64b9314ccc394ff8 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 16 Mar 2025 06:21:26 -0400 Subject: [PATCH 265/323] MineBombs: Added the new cooldown message that is in the MineBombCooldownException to the core messages. --- prison-core/src/main/resources/lang/core/ro_RO.properties | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) 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 aa7a2f680..ddf7ca06c 100644 --- a/prison-core/src/main/resources/lang/core/ro_RO.properties +++ b/prison-core/src/main/resources/lang/core/ro_RO.properties @@ -76,7 +76,7 @@ # -messages__version=5 +messages__version=6 messages__auto_refresh=true @@ -232,4 +232,7 @@ core_ranks_topn__player_line_2_detail_format= [-3] [-10] [7] [-18] [9] core_ranks_topn__player_line_2_detail_values={rankPosition}, {prestigeDefaultRankTagNoColor}, {rankScore}, {playerName}, {balanceKmbt} +## Please note there is another similar message in the spigot module: +## spigot_minebombs__cooldown_delay +core_minebombs__cooldown_delay=You cannot use another Prison Mine Bomb for %1 seconds. From c9b7ec1cf3a8e5b5d8f6fc9c3213bf2f21fc46da Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 16 Mar 2025 06:23:09 -0400 Subject: [PATCH 266/323] Placeholders: added a comment to better explain the hex colors. --- docs/changelog_v3.3.x.md | 3 +++ .../PlaceholderAttributeText.java | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 46c5bf8b6..3414e9e2a 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.19f 2025-03-16 +* **Placeholders: added a comment to better explain the hex colors.** + + * **Ranks: Fixed a few issues with '/ranks player' be issued by the player.** Added last seen date to the player objects. 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 06d75ed15..e16c4b93b 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 @@ -43,6 +43,25 @@ * * * + *

Please note that there are a couple of different ways you can enter hex codes + * in prison, and in turn, placeholder attributes. + *

+ * + *

If you use a hex code of `𞉀` then using 'hex', it will be translated as + * `&x&1&2&3&4&5&6`. hex2 would get translated as `§x§1§2§3§4§5§5`. This is actually + * somewhat odd, since even `&x&1&2&3&4&5&6` will ultimately be passed to the raw + * underlying bukkit handler as `§x§1§2§3§4§5§5`, but what makes it odd is that sometimes + * 'hex' works differently than 'hex2'. Disclaimer.. I may have misread the source + * code that I wrote a few years ago, and `hex2` may be something slightly different. + * Too see the actual content, enable `debug` in your attribute and see exactly how + * its passed. + *

+ * + *

There is another way to use hex codes too, and that is to use them as '#123456' + * without the leading '&'. Without using '&' color code, prison will allow the + * raw '#123456' hex code to be passed along, unchanged by prison. So the target + * plugin, or bukkit/spigot/paper will have to be able to handle that natively. + *

* */ public class PlaceholderAttributeText From 05c95b45e163fe699d16a733a7ca4615b092ee15 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 25 Mar 2025 04:10:03 -0400 Subject: [PATCH 267/323] Player: Change the way to get a platform player. Tie it to the Platform, and to use a new way to construct the SpigotPlayer and the SpigotOfflinePlayer by creating a static function that can take a RankPlayer object. This fixes some of the issues with getting the wrong bukkit player object, or none, even when the player is online. By putting the bukkit code directly in the SpigotPlayer and SpigotOfflinePlayer objects, it's able to bypass some of the abstraction that was found in the platform class. --- docs/changelog_v3.3.x.md | 8 +- .../mcprison/prison/cache/PlayerCache.java | 29 ++++--- .../prison/internal/platform/Platform.java | 13 ++- .../prison/ranks/data/RankPlayer.java | 49 +++++++++--- .../tech/mcprison/prison/TestPlatform.java | 5 ++ .../prison/spigot/SpigotPlatform.java | 22 +++++ .../spigot/game/SpigotOfflinePlayer.java | 39 +++++++-- .../prison/spigot/game/SpigotPlayer.java | 80 ++++++++++++++++++- .../spigot/game/SpigotPlayerException.java | 15 ++++ .../spigot/game/entity/SpigotEntity.java | 11 ++- 10 files changed, 233 insertions(+), 38 deletions(-) create mode 100644 prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotPlayerException.java diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 3414e9e2a..bcf6c80fa 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.19f 2025-03-16 +# 3.3.0-alpha.19f 2025-03-25 + + +* **Player: Change the way to get a platform player. Tie it to the Platform, and to use a new way to construct the SpigotPlayer and the SpigotOfflinePlayer** by creating a static function that can take a RankPlayer object. +This fixes some of the issues with getting the wrong bukkit player object, or none, even when the player is online. +By putting the bukkit code directly in the SpigotPlayer and SpigotOfflinePlayer objects, it's able to bypass some of the abstraction that was found in the platform class. + * **Placeholders: added a comment to better explain the hex colors.** 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 410a354bc..c5ff1f92a 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 @@ -126,7 +126,10 @@ private void onDisableInternal() { PrisonTaskSubmitter.cancelTask( saveAllTask.getTaskId() ); // Shutdown the timerTasks - PrisonTaskSubmitter.cancelTask( checkTimersTask.getTaskId() ); + if ( checkTimersTask != null ) { + + PrisonTaskSubmitter.cancelTask( checkTimersTask.getTaskId() ); + } // save all dirty cache items and purge cache: @@ -424,18 +427,20 @@ public PlayerCacheRunnable submitCacheRefresh() { 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, repeatTimeTicks ); - task.setTaskId( taskId ); + PlayerCacheRunnable task = PlayerCacheCheckTimersTask.submitPlayerStatsCacheUpdater(); +// 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, repeatTimeTicks ); +// task.setTaskId( taskId ); +// return task; } 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 d1735735b..123baa640 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 @@ -74,6 +74,18 @@ public interface Platform { public void getWorldLoadErrors( ChatDisplay display ); + /** + *

Providing a RankPlayer, generate and return a + * platform player object, that is connected to the + * platform, such as bukkit through the spigot platform. + *

+ * + * @param rankPlayer + * @return + */ + public Player getPlatformPlayer(RankPlayer rankPlayer); + + public RankPlayer getRankPlayer(UUID uuid, String name); @@ -515,5 +527,4 @@ public String autoCreateMineLinerAssignment(ModuleElement eMine, public MineBombEffectsData validateMineBombEffect(MineBombEffectsData mineBombEffectsData); - } 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 f71c01cdf..8c9aea9f8 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 @@ -69,6 +69,10 @@ public class RankPlayer private UUID uid; + private Player platformPlayer; + private long platformPlayerTimestamp = -1L; + + private transient File filePlayer; private transient File fileCache; @@ -1224,24 +1228,47 @@ public Inventory getInventory() { // } + /** + *

This function will use the platform to get the platform player, which is tied to the + * platform's player object. So on Spigot, the platformPlayer will be a SpigotPlayer object, + * with this instance of RankPlayer attached to it. + *

+ * + *

Every five minutes, this function will refresh the platformPlayer since the instances + * may actually change, such as if the player logged off and back on quickly. It's never + * good to have a stale player object because then the wrong inventory gets updated. But + * at least if that ever happens, then this will 'fix it', at worse, in 5 minutes. + * Getting the platform player is expensive, so we do need to cache it. + *

+ * + */ @Override public Player getPlatformPlayer() { - Player player = null; - Optional oPlayer = Prison.get().getPlatform().getPlayer( uid ); + long now = System.currentTimeMillis(); + long fiveMin = 1000 * 60* 5; - if ( oPlayer.isPresent() ) { - player = oPlayer.get(); - } - else { - oPlayer = Prison.get().getPlatform().getOfflinePlayer( uid ); + if ( platformPlayer == null || platformPlayerTimestamp + fiveMin < now ) { - if ( oPlayer.isPresent() ) { - player = oPlayer.get(); - } + platformPlayer = Prison.get().getPlatform().getPlatformPlayer( this ); + + platformPlayerTimestamp = now; } - return player; +// Optional oPlayer = Prison.get().getPlatform().getPlayer( uid ); +// +// if ( oPlayer.isPresent() ) { +// player = oPlayer.get(); +// } +// else { +// oPlayer = Prison.get().getPlatform().getOfflinePlayer( uid ); +// +// if ( oPlayer.isPresent() ) { +// player = oPlayer.get(); +// } +// } + + return platformPlayer; } 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 f54eb54e9..39c80272d 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/TestPlatform.java +++ b/prison-core/src/test/java/tech/mcprison/prison/TestPlatform.java @@ -80,6 +80,11 @@ public void getWorldLoadErrors( ChatDisplay display ) { } + @Override + public Player getPlatformPlayer(RankPlayer rankPlayer) { + return null; + } + @Override public RankPlayer getRankPlayer(UUID uuid, String name) { return null; 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 cd129e808..d601bb8e4 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 @@ -136,6 +136,7 @@ import tech.mcprison.prison.spigot.game.SpigotHandlerList; import tech.mcprison.prison.spigot.game.SpigotOfflinePlayer; import tech.mcprison.prison.spigot.game.SpigotPlayer; +import tech.mcprison.prison.spigot.game.SpigotPlayerException; import tech.mcprison.prison.spigot.game.SpigotPlayerUtil; import tech.mcprison.prison.spigot.game.SpigotWorld; import tech.mcprison.prison.spigot.placeholder.SpigotPlaceholders; @@ -274,6 +275,27 @@ public void getWorldLoadErrors( ChatDisplay display ) { } + @Override + public Player getPlatformPlayer( RankPlayer rankPlayer) { + Player sPlayer = SpigotPlayer.getSpigotPlayer( rankPlayer ); + +// try { +// } +// catch (SpigotPlayerException e) { + +// String msg = String.format( +// "SpigotPlatform.getPlatformPlayer: " +// + "Could not get a bukkit player object for '%s'. " +// + "Have they been removed or banned from spigot?", +// rankPlayer.getName() +// ); + +// Output.get().logInfo( e.getMessage() ); +// } + + return sPlayer; + } + @Override public RankPlayer getRankPlayer( UUID uuid, String name ) { RankPlayer rPlayer = null; diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java index 92f1a6576..dd4b2007b 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java @@ -7,6 +7,7 @@ import java.util.Set; import java.util.UUID; +import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; import org.bukkit.permissions.PermissionAttachmentInfo; @@ -44,6 +45,21 @@ public SpigotOfflinePlayer(OfflinePlayer offlinePlayer) { this.offlinePlayer = offlinePlayer; } + public static SpigotOfflinePlayer getOfflinePlayer( RankPlayer rankPlayer ) { + SpigotOfflinePlayer result = null; + + // Get an offline player: + OfflinePlayer olPlayer = Bukkit.getOfflinePlayer( rankPlayer.getUUID() ); + + if ( olPlayer != null ) { + result = new SpigotOfflinePlayer( olPlayer ); + + result.setRankPlayer( rankPlayer ); + } + + return result; + } + @Override public String getName() { return offlinePlayer.getName(); @@ -443,12 +459,18 @@ public void setActionBar( String actionBar ) { } public RankPlayer getRankPlayer() { + if ( rankPlayer == null && PrisonRanks.getInstance() != null && PrisonRanks.getInstance().isEnabled() ) { + rankPlayer = PrisonRanks.getInstance().getPlayerManager().getPlayer( this ); } return rankPlayer; } + private void setRankPlayer( RankPlayer rankPlayer ) { + this.rankPlayer = rankPlayer; + } + @Override public PlayerCache getPlayerCache() { @@ -491,15 +513,20 @@ public void sendMessage(List messages) { @Override public tech.mcprison.prison.internal.Player getPlatformPlayer() { - tech.mcprison.prison.internal.Player player = null; - Optional oPlayer = Prison.get().getPlatform().getPlayer( getName() ); + SpigotPlayer sPlayer = SpigotPlayer.getSpigotPlayer( getRankPlayer() ); - if ( oPlayer.isPresent() ) { - player = oPlayer.get(); - } + return sPlayer; - return player; +// tech.mcprison.prison.internal.Player player = null; +// +// Optional oPlayer = Prison.get().getPlatform().getPlayer( getName() ); +// +// if ( oPlayer.isPresent() ) { +// player = oPlayer.get(); +// } +// +// return player; } 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 6985af781..e29b72523 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 @@ -23,8 +23,10 @@ import java.util.List; import java.util.Optional; +import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.Material; +import org.bukkit.OfflinePlayer; import org.bukkit.Statistic; import org.bukkit.block.Block; import org.bukkit.entity.ExperienceOrb; @@ -62,7 +64,19 @@ import tech.mcprison.prison.util.Vector; /** - * @author Faizaan A. Datoo + *

This is a wrapper class that stores the bukkit player object and enables it + * to be used with the internal Prison SpigotPlayer object. It also can store the + * RankPlayer object too. + *

+ * + *

To generate a SpigotPlayer from a RankPlayer there is a new + * static function that will perform the construction of the SpigotPlayer. + *

+ * + *

This SpigotPlayer object is ONLY for players that are online. This class + * cannot exist for offline players, of which use the SpigotOfflinePlayer object. + *

+ * */ public class SpigotPlayer extends SpigotEntity @@ -81,9 +95,50 @@ public class SpigotPlayer public SpigotPlayer(org.bukkit.entity.Player bukkitPlayer) { super(bukkitPlayer); + this.bukkitPlayer = bukkitPlayer; } + + + /** + *

This function sets up a SpigotPlayer object using a RankPlayer object. + * It basically joins the bukkit player to the existing RankPlayer. + *

+ * + * + *

This will throw a SpigotPlayerException if the RankPlayer's UUID cannot be + * tied to a bukkit player. This should never happen since UUIDs come from bukkit + * with the exception of the player being removed from bukkit, but not yet from + * prison. + *

+ * + * @param rankPlayer + * @throws SpigotPlayerException + */ + public static SpigotPlayer getSpigotPlayer( RankPlayer rankPlayer ) { + + SpigotPlayer result = null; + + // We have a RankPlayer object, but we need to connect this SpigotPlayer object + // to the bukkit player object. + // NOTE: We're directly accessing bukkit here because it's more direct instead of + // trying to do that through a few different function within the + // SpigotPlatform. + + // First try to load a bukkit online player: + org.bukkit.entity.Player bPlayer = Bukkit.getPlayer( rankPlayer.getUUID() ); + + if ( bPlayer != null ) { + result = new SpigotPlayer( bPlayer ); + + result.setRankPlayer( rankPlayer ); + } + + return result; + } + + /** *

This constructs a player file named based upon the UUID followed * by the player's name. This format is used so it's easier to identify @@ -161,6 +216,16 @@ public String getDisplayName() { return bukkitPlayer.getDisplayName(); } + @Override + public String getName() { + + return bukkitPlayer != null ? + bukkitPlayer.getName() : + rankPlayer != null ? + rankPlayer.getName() : ""; + } + + @Override public void setDisplayName(String newDisplayName) { bukkitPlayer.setDisplayName(newDisplayName); @@ -185,7 +250,7 @@ public void give(ItemStack itemStack) { @Override public boolean isOnline() { - return bukkitPlayer.isOnline(); + return bukkitPlayer == null ? false : bukkitPlayer.isOnline(); } @Override @@ -445,7 +510,11 @@ public String toString() { sb.append( "SpigotPlayer: " ).append( getName() ) .append( " isOp=" ).append( isOp() ) .append( " isOnline=" ).append( isOnline() ) - .append( " isPlayer=" ).append( isPlayer() ); + .append( " isPlayer=" ).append( isPlayer() ) + + .append( " hasBukkitPlayer=" ).append( bukkitPlayer != null ) + .append( " hasRankPlayer=" ).append( rankPlayer != null ) + ; return sb.toString(); } @@ -801,6 +870,11 @@ public RankPlayer getRankPlayer() { return rankPlayer; } + private void setRankPlayer( RankPlayer rankPlayer ) { + this.rankPlayer = rankPlayer; + } + + @Override public PlayerCache getPlayerCache() { return PlayerCache.getInstance(); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotPlayerException.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotPlayerException.java new file mode 100644 index 000000000..79d646670 --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotPlayerException.java @@ -0,0 +1,15 @@ +package tech.mcprison.prison.spigot.game; + +public class SpigotPlayerException extends Exception { + + private static final long serialVersionUID = 1L; + + public SpigotPlayerException() { + super( "Cannot load the bukkit org.bukkit.entity.Player." ); + } + + public SpigotPlayerException( String msg ) { + super( msg ); + } + +} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotEntity.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotEntity.java index 9c381aa2f..95f9b052c 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotEntity.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotEntity.java @@ -281,10 +281,13 @@ public org.bukkit.entity.Entity getBukkitEntity() { } - @Override - public String getName() { - return bukkitEntity.getName(); - } +// @Override +// public String getName() { +// +// return bukkitEntity != null ? +// bukkitEntity.getName() : +// rankplayer; +// } @Override From 939e51d215092355486049655e33497c3379e639 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 25 Mar 2025 04:13:45 -0400 Subject: [PATCH 268/323] PlayerCache Timer Task: Redo the submission of the task to be self contained and will not initiate the task if the Ranks are disabled. --- docs/changelog_v3.3.x.md | 3 ++ .../cache/PlayerCacheCheckTimersTask.java | 47 ++++++++++++++++++- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index bcf6c80fa..7f0106153 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.19f 2025-03-25 +* **PlayerCache Timer Task: Redo the submission of the task to be self contained and will not initiate the task if the Ranks are disabled.** + + * **Player: Change the way to get a platform player. Tie it to the Platform, and to use a new way to construct the SpigotPlayer and the SpigotOfflinePlayer** by creating a static function that can take a RankPlayer object. This fixes some of the issues with getting the wrong bukkit player object, or none, even when the player is online. By putting the bukkit code directly in the SpigotPlayer and SpigotOfflinePlayer objects, it's able to bypass some of the abstraction that was found in the platform class. diff --git a/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheCheckTimersTask.java b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheCheckTimersTask.java index a052deca6..b4a412a8a 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheCheckTimersTask.java +++ b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheCheckTimersTask.java @@ -8,7 +8,10 @@ import tech.mcprison.prison.Prison; import tech.mcprison.prison.internal.Player; +import tech.mcprison.prison.modules.Module; +import tech.mcprison.prison.modules.ModuleElementType; import tech.mcprison.prison.ranks.data.RankPlayer; +import tech.mcprison.prison.tasks.PrisonTaskSubmitter; /** *

This periodically ran task will go through all cached players and update @@ -53,6 +56,40 @@ public PlayerCacheCheckTimersTask() { this.processedKeys = new HashSet<>(); } + /** + * This will submit this task to run at regular intervals only if the rank + * module is enabled. + * + * If ranks are not enabled, then this task will not be started since there will be + * no reason to use the player cache. + * + * @return + */ + public static PlayerCacheRunnable submitPlayerStatsCacheUpdater() { + + PlayerCacheCheckTimersTask task = null; + + Module ranksModule = Prison.get().getModuleManager().getModule( + ModuleElementType.RANK.name() ); + + if ( ranksModule != null && ranksModule.isEnabled() ) { + + task = new PlayerCacheCheckTimersTask(); + + int repeatTimeTicks = Prison.get().getPlatform() + .getConfigInt( PlayerCache.PLAYER_CACHE_UPDATE_PLAYER_STATS_CONFIG_NAME, + PlayerCache.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, repeatTimeTicks ); + task.setTaskId( taskId ); + } + + return task; + } + @Override public void run() { @@ -64,10 +101,18 @@ public void run() processCache(); } + + /** + * Only allow the cache to be processed if ranks is enabled. + */ private void processCache() { PlayerCache pCache = PlayerCache.getInstance(); - if ( pCache.getPlayers() != null && pCache.getPlayers().keySet().size() > 0 ) { + Module ranksModule = Prison.get().getModuleManager().getModule( + ModuleElementType.RANK.name() ); + + if ( ranksModule != null && ranksModule.isEnabled() && + pCache.getPlayers() != null && pCache.getPlayers().keySet().size() > 0 ) { try { From a4c261783face8bbe7c3c125e89d56c8a71bff00 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 25 Mar 2025 04:28:48 -0400 Subject: [PATCH 269/323] Prison Utils: Changed the way the platform players are used to resolve some issues when the players are offline. --- docs/changelog_v3.3.x.md | 3 + .../prison/spigot/utils/PrisonUtils.java | 90 ++++++++++++++----- 2 files changed, 71 insertions(+), 22 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 7f0106153..9805917ca 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.19f 2025-03-25 +* **Prison Utils: Changed the way the platform players are used to resolve some issues when the players are offline.** + + * **PlayerCache Timer Task: Redo the submission of the task to be self contained and will not initiate the task if the Ranks are disabled.** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtils.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtils.java index b48dd8506..7b08ac753 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtils.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtils.java @@ -5,9 +5,10 @@ import tech.mcprison.prison.Prison; import tech.mcprison.prison.internal.CommandSender; import tech.mcprison.prison.internal.Player; +import tech.mcprison.prison.output.Output; import tech.mcprison.prison.ranks.data.RankPlayer; -import tech.mcprison.prison.spigot.game.SpigotOfflinePlayer; import tech.mcprison.prison.spigot.game.SpigotPlayer; +import tech.mcprison.prison.spigot.game.SpigotPlayerException; public abstract class PrisonUtils implements PrisonUtilsInterface { @@ -71,10 +72,10 @@ public boolean isEnabled() { */ abstract protected Boolean initialize(); - protected SpigotPlayer checkPlayerPerms( CommandSender sender, String playerName, - String permsSelf, String permsOthers ) { - return checkPlayerPerms(sender, playerName, permsSelf, permsOthers, false ); - } +// protected SpigotPlayer checkPlayerPerms( CommandSender sender, String playerName, +// String permsSelf, String permsOthers ) { +// return checkPlayerPerms(sender, playerName, permsSelf, permsOthers, false ); +// } /** *

This function checks the perms of the player. If the CommandSender has no @@ -95,12 +96,11 @@ protected SpigotPlayer checkPlayerPerms( CommandSender sender, String playerName * @return */ protected SpigotPlayer checkPlayerPerms( CommandSender sender, String playerName, - String permsSelf, String permsOthers, - boolean useOfflinePlayers ) { + String permsSelf, String permsOthers ) { boolean isConsole = !(sender instanceof org.bukkit.entity.Player); - SpigotPlayer player = getSpigotPlayer( playerName, useOfflinePlayers ); + SpigotPlayer player = getSpigotPlayer( playerName ); // Player's name was not found then it's either being ran from console, or on self. if ( player == null ) { @@ -155,31 +155,77 @@ else if ( !sender.isOp() && !sender.hasPermission( permsSelf ) ) { * ensure a player is always returned, if its a valid player. *

* - * @param sender - * @param playerName is optional, if not supplied, then sender will be used + * @param playerName * @return Player if found, or null. */ - protected SpigotPlayer getSpigotPlayer( String playerName, boolean useOfflinePlayer ) { + protected SpigotPlayer getSpigotPlayer( String playerName ) { SpigotPlayer result = null; RankPlayer rPlayer = Prison.get().getPlatform().getRankPlayer( null, playerName ); - if ( rPlayer != null ) { - Player player = Prison.get().getPlatform().getPlayer( rPlayer.getUUID() ).orElse(null); +// // First try to get the bukkit online player: +// if ( rPlayer != null ) { +// org.bukkit.entity.Player playerBukkit = Bukkit.getPlayer( rPlayer.getUUID() ); +// } + + if ( rPlayer == null ) { + + // The requested player name is not within prison. Could be a typo or they + // don't have ranks enabled. First get a temp SpigotPlayer and then use + // the supplied name and UUID to create a new RankPlayer so we can + // create a valid SpigotPlayer that includes the RankPlayer even with the + // Ranks disabled. + Player player = Prison.get().getPlatform().getPlayer( playerName ).orElse( null ); if ( player != null ) { result = (SpigotPlayer) player; - } - else if ( useOfflinePlayer ) { - Player offLinePlayer = Prison.get().getPlatform().getOfflinePlayer( player.getUUID() ).orElse( null ); - if ( offLinePlayer != null ) { - - SpigotOfflinePlayer offlinePlayer = (SpigotOfflinePlayer) offLinePlayer; - - result = new SpigotPlayer( offlinePlayer.getWrapper().getPlayer() ); - } + // Create a 'false' RankPlayer object: + + RankPlayer rp = new RankPlayer( player.getUUID(), player.getDisplayName() ); + + rPlayer = rp; } + + + } + + + if ( rPlayer != null ) { + + result = SpigotPlayer.getSpigotPlayer( rPlayer ); +// try { +// } +// catch (SpigotPlayerException e) { +// +//// String msg = String.format( +//// "SpigotPlayer: Could not get a bukkit player object for '%s'. " +//// + "Is their name spelled correctly? " +//// + "Have they been removed or banned from spigot?", +//// playerName +//// ); +// +// Output.get().logInfo( e.getMessage() ); +// +// } + +// Player player = Prison.get().getPlatform().getPlayer( rPlayer.getUUID() ).orElse(null); +// +// if ( player != null ) { +// result = (SpigotPlayer) player; +// } +// else if ( useOfflinePlayer ) { +// +// +//// Player offLinePlayer = Prison.get().getPlatform().getOfflinePlayer( rPlayer.getUUID() ).orElse( null ); +//// +//// if ( offLinePlayer != null ) { +//// +//// SpigotOfflinePlayer offlinePlayer = (SpigotOfflinePlayer) offLinePlayer; +//// +//// result = new SpigotPlayer( offlinePlayer.getWrapper().getPlayer() ); +// } +// } } // if ( playerName != null ) { From 8184bc228e7158a1e4c8042aa56a2226185b081d Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 25 Mar 2025 04:31:34 -0400 Subject: [PATCH 270/323] Ranks: Change the way ranks player get the player objects, especially when the player is offline. This fixes a few issues. --- docs/changelog_v3.3.x.md | 4 ++ .../prison/ranks/commands/RanksCommands.java | 54 +++++++++++-------- 2 files changed, 35 insertions(+), 23 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 9805917ca..8cbf9876f 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.19f 2025-03-25 +* **Ranks: Change the way ranks player get the player objects, especially when the player is offline. +This fixes a few issues.** + + * **Prison Utils: Changed the way the platform players are used to resolve some issues when the players are offline.** 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 f344df94f..1bec29df3 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 @@ -17,7 +17,6 @@ import tech.mcprison.prison.PrisonAPI; import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; import tech.mcprison.prison.autofeatures.AutoFeaturesWrapper; -import tech.mcprison.prison.cache.PlayerCache; import tech.mcprison.prison.cache.PlayerCachePlayerData; import tech.mcprison.prison.chat.FancyMessage; import tech.mcprison.prison.commands.Arg; @@ -28,7 +27,6 @@ import tech.mcprison.prison.integration.IntegrationType; import tech.mcprison.prison.integration.PermissionIntegration; import tech.mcprison.prison.internal.CommandSender; -import tech.mcprison.prison.internal.OfflineMcPlayer; import tech.mcprison.prison.internal.Player; import tech.mcprison.prison.modules.ModuleElement; import tech.mcprison.prison.modules.ModuleElementType; @@ -1618,14 +1616,18 @@ public void rankPlayer(CommandSender sender, @Arg(name = "options", def = "", description = "Options [perms]") String options ){ - RankPlayer rankPlayer = getRankPlayer(sender, null, playerName); + RankPlayer rankPlayer = getRankPlayer(sender, null, playerName ); if ( rankPlayer == null ) { rankupInvalidPlayerNameMsg( sender, playerName ); return; } + + // This is a SpigotPlayer object, with the bukkit player attached: + Player sPlayer = rankPlayer.getPlatformPlayer(); + // Player player = getPlayer( sender, playerName ); // // if (player == null) { @@ -1643,7 +1645,7 @@ public void rankPlayer(CommandSender sender, // need to see if the player is offline or online: - Player offlinePlayer = Prison.get().getPlatform().getOfflinePlayer( rankPlayer.getUUID() ).orElse( null ); +// Player offlinePlayer = Prison.get().getPlatform().getOfflinePlayer( rankPlayer.getUUID() ).orElse( null ); //PlayerManager pm = PrisonRanks.getInstance().getPlayerManager(); @@ -1651,7 +1653,7 @@ public void rankPlayer(CommandSender sender, // RankPlayer rankPlayer = pm.getPlayer(player.getUUID(), player.getName()); // Get the cachedPlayer: - PlayerCachePlayerData cPlayer = PlayerCache.getInstance().getOnlinePlayer( rankPlayer ); + PlayerCachePlayerData cPlayer = rankPlayer.getPlayerCachePlayerData(); @@ -1660,17 +1662,28 @@ public void rankPlayer(CommandSender sender, msgs.add( msg1 ); - if ( offlinePlayer != null && cPlayer != null ) { - if ( cPlayer.getLastSeenDate() < offlinePlayer.getLastSeenDate() ) { - cPlayer.setLastSeenDate( offlinePlayer.getLastSeenDate() ); + if ( sPlayer != null && cPlayer != null ) { + if ( cPlayer.getLastSeenDate() < sPlayer.getLastSeenDate() ) { + cPlayer.setLastSeenDate( sPlayer.getLastSeenDate() ); cPlayer.setDirty( true ); } - if ( rankPlayer.getLastSeenDate() < offlinePlayer.getLastSeenDate() ) { - rankPlayer.setLastSeenDateTemp( offlinePlayer.getLastSeenDate() ); + if ( rankPlayer.getLastSeenDate() < sPlayer.getLastSeenDate() ) { + rankPlayer.setLastSeenDateTemp( sPlayer.getLastSeenDate() ); rankPlayer.setDirty( true ); } } +// if ( offlinePlayer != null && cPlayer != null ) { +// if ( cPlayer.getLastSeenDate() < offlinePlayer.getLastSeenDate() ) { +// cPlayer.setLastSeenDate( offlinePlayer.getLastSeenDate() ); +// cPlayer.setDirty( true ); +// } +// +// if ( rankPlayer.getLastSeenDate() < offlinePlayer.getLastSeenDate() ) { +// rankPlayer.setLastSeenDateTemp( offlinePlayer.getLastSeenDate() ); +// rankPlayer.setDirty( true ); +// } +// } String lastSeen = cPlayer == null || cPlayer.getLastSeenDate() == 0 ? @@ -1785,12 +1798,12 @@ public void rankPlayer(CommandSender sender, } - boolean isOp = offlinePlayer != null ? offlinePlayer.isOp() : rankPlayer.isOp(); - boolean isPlayer = offlinePlayer != null ? offlinePlayer.isPlayer() : rankPlayer.isPlayer(); - boolean isOnline = offlinePlayer != null ? offlinePlayer.isOnline() : rankPlayer.isOnline(); + boolean isOp = sPlayer != null ? sPlayer.isOp() : rankPlayer.isOp(); + boolean isPlayer = sPlayer != null ? sPlayer.isPlayer() : rankPlayer.isPlayer(); + boolean isOnline = sPlayer != null ? sPlayer.isOnline() : rankPlayer.isOnline(); - boolean isPrisonPlayer = (rankPlayer instanceof Player); - boolean isPrisonOfflineMcPlayer = offlinePlayer != null ? true : (rankPlayer instanceof OfflineMcPlayer); +// boolean isPrisonPlayer = (rankPlayer instanceof Player); +// boolean isPrisonOfflineMcPlayer = offlinePlayer != null ? true : (rankPlayer instanceof OfflineMcPlayer); if ( !isOnline ) { String msgOffline = ranksPlayerPermsOfflineMsg(); @@ -1956,9 +1969,9 @@ public void rankPlayer(CommandSender sender, msgPlayerPerms, (isOp ? " " + ranksPlayerOpMsg() : ""), (isPlayer ? " " + ranksPlayerPlayerMsg() : ""), - (isOnline ? " " + ranksPlayerOnlineMsg() : " " + ranksPlayerOfflineMsg()), - (isPrisonOfflineMcPlayer ? " " + ranksPlayerPrisonOfflinePlayerMsg() : - (isPrisonPlayer ? " " + ranksPlayerPrisonPlayerMsg() : "")) + (isOnline ? " " + ranksPlayerOnlineMsg() : " " + ranksPlayerOfflineMsg()) +// (isPrisonOfflineMcPlayer ? " " + ranksPlayerPrisonOfflinePlayerMsg() : +// (isPrisonPlayer ? " " + ranksPlayerPrisonPlayerMsg() : "")) ) ); if ( !isOnline ) { @@ -2690,11 +2703,6 @@ public RankPlayer getRankPlayer( CommandSender sender, UUID playerUuid, String p RankPlayer player = PrisonRanks.getInstance().getPlayerManager().getPlayer(playerUuid, playerName); - // Well, this isn't supposed to happen... - if ( player == null ) { - ranksRankupFailureToGetRankPlayerMsg( sender ); - } - return player; } } From 47f64afd3de80527cc12a49d464eebfb1f83bcaf Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 25 Mar 2025 04:34:24 -0400 Subject: [PATCH 271/323] MineBombs: Fix the way players are used to resolve a few issues with the player objects. --- docs/changelog_v3.3.x.md | 3 +++ .../spigot/utils/PrisonUtilsMineBombs.java | 16 ++++++++++------ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 8cbf9876f..473ee6b6f 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.19f 2025-03-25 +* **MineBombs: Fix the way players are used to resolve a few issues with the player objects.** + + * **Ranks: Change the way ranks player get the player objects, especially when the player is offline. This fixes a few issues.** 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 af56a3b7e..55435c530 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 @@ -654,16 +654,17 @@ public void utilsMineBombsList( CommandSender sender, MineBombData bomb = mBombs.getConfigData().getBombs().get( key ); + String bombName = bomb.getName().trim(); - if ( bomb.getName().trim().length() > 0 && - !bomb.getName().toLowerCase().contains(options.trim().toLowerCase())) { + if ( bombName.length() > 0 && options != null && + !bombName.toLowerCase().contains(options.toLowerCase().trim())) { continue; } String msg1 = String.format( "&7%s", - bomb.getName() + bombName ); messages.add( msg1 ); @@ -890,9 +891,9 @@ public void utilsMineBombsGive( CommandSender sender, // Get a SpigotPlayer object, which will be returned if the player has // access to those perms too. If ranks are disabled, then allow it to check // bukkit's offline players. - boolean useOfflinePlayers = true; + SpigotPlayer player = checkPlayerPerms( sender, playerName, - "prison.utils.bomb", "prison.utils.bomb.others", useOfflinePlayers ); + "prison.utils.bomb", "prison.utils.bomb.others" ); if ( player != null ) { @@ -950,8 +951,11 @@ public void utilsMineBombsGive( CommandSender sender, if ( bombs != null ) { + SpigotItemStack sBombs = new SpigotItemStack( bombs ); + bombs.setAmount( count ); - player.getWrapper().getInventory().addItem( bombs ); + player.getInventory().addItem( sBombs ); +// player.getWrapper().getInventory().addItem( bombs ); player.getWrapper().updateInventory(); // player.updateInventory(); From e23d120a2c3518c4bf548f2c5c5aa99d8e0729a7 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 1 Apr 2025 04:14:44 -0400 Subject: [PATCH 272/323] These was a problem with hex color codes being used in lore (or elsewhere probably) where they are not being translated unless there is another color, such as &7 anywhere else in the String. The problem was that the hex conversion was working perfectly well. But since the "dirty" variable was not getting modified, since the hex colors were applied before that point in processing, it would always revert back to the original unchanged String value because it thought there was nothing that changed. To fix the problem, I eliminated the dirty variable and am always converting the byte array back to a String value. So no need to check if dirty anymore, since it always converts. --- docs/changelog_v3.3.x.md | 6 ++++- .../java/tech/mcprison/prison/util/Text.java | 19 +++++++++------ .../tech/mcprison/prison/util/TextTest.java | 23 +++++++++++++++++++ 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 473ee6b6f..3d12f00e6 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.19f 2025-03-25 +# 3.3.0-alpha.19f 2025-03-31 + +* **These was a problem with hex color codes being used in lore (or elsewhere probably) where they are not being translated unless there is another color, such as &7 anywhere else in the String. +The problem was that the hex conversion was working perfectly well. But since the "dirty" variable was not getting modified, since the hex colors were applied before that point in processing, it would always revert back to the original unchanged String value because it thought there was nothing that changed. +To fix the problem, I eliminated the dirty variable and am always converting the byte array back to a String value. So no need to check if dirty anymore, since it always converts. * **MineBombs: Fix the way players are used to resolve a few issues with the player objects.** 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 d0fd98d18..06b783a0f 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 @@ -356,16 +356,20 @@ public static String translateColorCodes(String text, char prefix) { } - public static String translateColorCodes(String text, char prefix, + private static String translateColorCodes(String text, char prefix, char targetColorCode, char targetHexColorCode) { if (prefix == COLOR_CHAR) { return text; // No need to translate, it's already been translated } + // If the hex color codes are translated here, then it was not marking + // 'dirty' as being true, when it actually was. + // So to fix, eliminate 'dirty' and always convert the character array to + // a String. char[] b = translateHexColorCodes( text, targetHexColorCode ).toCharArray(); int len = b.length; - boolean dirty = false; +// boolean dirty = false; boolean quote = false; boolean quoted = false; @@ -385,11 +389,12 @@ else if ( quote ) { else if (b[i] == prefix && "0123456789AaBbCcDdEeFfKkLlMmNnOoRr#xX".indexOf(b[i + 1]) > -1) { b[i] = targetColorCode; // COLOR_CHAR; // 167; // Section symbol b[i + 1] = Character.toLowerCase(b[i + 1]); - dirty = true; +// dirty = true; } } - String results = dirty ? new String(b) : text; + String results = new String(b); +// String results = dirty ? new String(b) : text; if ( quoted ) { results = results.replace( "\\Q", "" ).replace( "\\E", "" ); } @@ -469,7 +474,7 @@ public static String stripColor(String text) { * @param targetColorCode * @return */ - public static String translateHexColorCodes( String text, char targetColorCode ) { + protected static String translateHexColorCodes( String text, char targetColorCode ) { StringBuilder sb = new StringBuilder(); if ( text != null && !text.trim().isEmpty() ) { @@ -515,7 +520,7 @@ public static String translateHexColorCodes( String text, char targetColorCode ) * @param targetColorCode the char value that is used to inject as a color code * @return */ - public static String translateHexColorCodesCore(String message, char targetColorCode) { + private static String translateHexColorCodesCore(String message, char targetColorCode) { String results = ""; if ( message != null ) { @@ -545,7 +550,7 @@ public static String translateHexColorCodesCore(String message, char targetColor } - public static String convertToAmpColorCodes( String textEncoded ) { + private static String convertToAmpColorCodes( String textEncoded ) { String results = textEncoded; diff --git a/prison-core/src/test/java/tech/mcprison/prison/util/TextTest.java b/prison-core/src/test/java/tech/mcprison/prison/util/TextTest.java index 9c038a37d..76c5dfe5e 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/util/TextTest.java +++ b/prison-core/src/test/java/tech/mcprison/prison/util/TextTest.java @@ -134,6 +134,29 @@ public void testHexColors() { // Test with two complete quote: assertEquals("This ^7is ^x^a^3^b^4^c^5 ^ra test #123456 test test2 #778899 test", replaceColorCodeWithx( translateColorCodes("This &7is #a3b4c5 &Ra test \\Q#123456 test\\E test2 \\Q#778899 test\\E", '&'), '^' )); + + } + + @Test + public void testHexColorBug() { + + // Note: These is a problem with hex color codes being used in lore (or elsewhere probably) + // where they are not being translated unless there is another color, such as &7 + // Proceeding it. So try to reproduce the situation... + + // The problem was that the hex conversion was working perfectly well. But + // since the "dirty" variable was not getting modified, since the hex colors were + // applied before that point in processing, it would always revert back to the original + // unchanged String value because it thought there was nothing that changed. + + // To fix the problem, I eliminated the dirty variable and am always converting the byte + // array back to a String value. So no need to check if dirty anymore, since it always converts. + assertEquals("This is ^x^a^3^b^4^c^5 a test", replaceColorCodeWithx( + translateAmpColorCodes("This is #a3b4c5 a test" ), '^' )); + + assertEquals("This is ^x^a^3^b^4^c^5a test", replaceColorCodeWithx( + translateAmpColorCodes("This is &#a3b4c5a test" ), '^' )); + } From fe77d74841eedb1feaa79f9b978abf66f4b1232a Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 7 Apr 2025 03:27:24 -0400 Subject: [PATCH 273/323] 2025-03-31 V3.3.0-alpha.19g --- docs/changelog_v3.3.x.md | 8 ++++++-- gradle.properties | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 3d12f00e6..3c43b5cae 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,9 +14,13 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.19f 2025-03-31 +# 3.3.0-alpha.19g 2025-03-31 -* **These was a problem with hex color codes being used in lore (or elsewhere probably) where they are not being translated unless there is another color, such as &7 anywhere else in the String. + + +* **3.3.0-alpha.19g 2025-03-31* + +* **These was a problem with hex color codes being used in lore (or elsewhere probably) where they are not being translated unless there is another color**, such as &7 anywhere else in the String. The problem was that the hex conversion was working perfectly well. But since the "dirty" variable was not getting modified, since the hex colors were applied before that point in processing, it would always revert back to the original unchanged String value because it thought there was nothing that changed. To fix the problem, I eliminated the dirty variable and am always converting the byte array back to a String value. So no need to check if dirty anymore, since it always converts. diff --git a/gradle.properties b/gradle.properties index f09a18642..75ba5656c 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.19f +version=3.3.0-alpha.19g From 0caa2b6b534af6fa98045d2823bcf90d5c33c3d9 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 7 Apr 2025 04:57:59 -0400 Subject: [PATCH 274/323] Increment build to v3.3.0-alpha.19h because 19g did not appear to compile correctly and was still reporting alpha.19f. --- docs/changelog_v3.3.x.md | 7 ++++++- gradle.properties | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 3c43b5cae..d06930b2d 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.19g 2025-03-31 +# 3.3.0-alpha.19h 2025-04-07 + + + +* **3.3.0-alpha.19h 2025-04-07** +The build for alpha.19g did not reflect the correct version. So incrementing the version so it is clear if someone is using the correct version or not. diff --git a/gradle.properties b/gradle.properties index 75ba5656c..1a7e90252 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.19g +version=3.3.0-alpha.19h From f1fab5ffd030e4f5b4054b3d06785d335cf2a87a Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 7 Apr 2025 05:00:00 -0400 Subject: [PATCH 275/323] Added zEssentials and zMenu to Prison's soft depends so prison will load after those plugins. There was an issue with prison trying to access vault's economy before zEssentials could properly hook in to it. This should allow zEss to fully enabled the economy now. --- docs/changelog_v3.3.x.md | 3 +++ prison-spigot/src/main/resources/plugin.yml | 2 ++ 2 files changed, 5 insertions(+) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index d06930b2d..747d6df4e 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.19h 2025-04-07 +* **Added zEssentials and zMenu to Prison's soft depends so prison will load after those plugins.** +There was an issue with prison trying to access vault's economy before zEssentials could properly hook in to it. This should allow zEss to fully enabled the economy now. + * **3.3.0-alpha.19h 2025-04-07** The build for alpha.19g did not reflect the correct version. So incrementing the version so it is clear if someone is using the correct version or not. diff --git a/prison-spigot/src/main/resources/plugin.yml b/prison-spigot/src/main/resources/plugin.yml index 6e6e5fefb..2f12423ee 100644 --- a/prison-spigot/src/main/resources/plugin.yml +++ b/prison-spigot/src/main/resources/plugin.yml @@ -57,4 +57,6 @@ softdepend: - SaneEconomy - EdPrison - ExcellentEnchants + - zEssentials + - zMenu From 158d0ad2095dba66523d36824435b12e8c825520 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 7 Apr 2025 05:01:31 -0400 Subject: [PATCH 276/323] Prison was hard coding the teleport message. Not sure why it was not hooked in to the language files, or if it was, why it was removed. Rehooked it up. --- docs/changelog_v3.3.x.md | 4 ++++ .../mines/commands/MinesCommandMessages.java | 12 ++++++++++++ .../prison/mines/commands/MinesCommands.java | 15 ++++++++++----- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 747d6df4e..43a48496e 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.19h 2025-04-07 +* **Prison was hard coding the teleport message.** Not sure why it was not hooked in to the language files, or if it was, why it was removed. +Rehooked it up. + + * **Added zEssentials and zMenu to Prison's soft depends so prison will load after those plugins.** There was an issue with prison trying to access vault's economy before zEssentials could properly hook in to it. This should allow zEss to fully enabled the economy now. diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesCommandMessages.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesCommandMessages.java index 6281b61fd..52cbcd957 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesCommandMessages.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesCommandMessages.java @@ -70,4 +70,16 @@ protected void teleportFailedMsg( CommandSender sender ) { .sendTo( sender ); } + + protected String teleportSuccessMsg( String mineName ) { + // &3Telport failed. Are you sure you're a Player? + String msg = PrisonMines.getInstance().getMinesMessages() + .getLocalizable( "teleport" ) + .withReplacements( + mineName ) + .localize(); + + return msg; + } + } 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 efa78d989..2080e0824 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 @@ -3527,11 +3527,16 @@ else if ( playerAlt != null && !player.getName().equalsIgnoreCase( playerAlt.get if ( sender.isPlayer() ) { teleportPlayer( (Player) sender, m, target ); - String msg = String.format( - "&3Teleported to mine %s. %s", - m.getTag(), - ( sender.getMiscText() == null ? "" : sender.getMiscText() ) - ); + String msg = teleportSuccessMsg( m.getTag() ); + + if ( sender.getMiscText() != null ) { + msg = msg + " " + sender.getMiscText(); + } +// String msg = String.format( +// "&3Teleported to mine %s. %s", +// m.getTag(), +// ( sender.getMiscText() == null ? "" : sender.getMiscText() ) +// ); sender.sendMessage( msg ); // m.teleportPlayerOut( (Player) sender, target ); From 23e9fb862fec302b6cb5fc482a5fb74d63ed899b Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 7 Apr 2025 05:22:01 -0400 Subject: [PATCH 277/323] Change logs: Restructured the change logs so the primary file is not quite as large. It was starting to run in to some lag issues when editing. --- docs/changelog_v3.3.x.md | 2247 +----------------------------------- docs/changelog_v3.3.xb.md | 2272 +++++++++++++++++++++++++++++++++++++ docs/prison_changelogs.md | 1 + 3 files changed, 2284 insertions(+), 2236 deletions(-) create mode 100644 docs/changelog_v3.3.xb.md diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 43a48496e..a86ed892c 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.19h 2025-04-07 +* **Change logs: Restructured the change logs so the primary file is not quite as large. It was starting to run in to some lag issues when editing.** + + + * **Prison was hard coding the teleport message.** Not sure why it was not hooked in to the language files, or if it was, why it was removed. Rehooked it up. @@ -1284,2256 +1288,27 @@ As a fallback, if the privatebin cannot be used, it is now using the older paste This will allow prison to use EdPrison's economy does not also use another established economy that is accessible through vault, or multi-currency. - -# 3.3.0-alpha.17 2024-04-20 - -**v3.3.0-alpha.17** 2024-04-20 - - - -* **Mines messages: Secondary placeholders. Added support for mines' messages to be able to support secondary placeholders within the language files. NOTE: Not usable at this time.** -But... this is basically useless. Within the mines language files, the vast majority of all messages are related to admin messages and are not viewable by the players. -Therefore the admin-only messages will not support the secondary placeholders since the players will never see them. -At this time, there are no messages that supports the use of these secondary placeholders, although the feature has been enabled for mines. -If a need is required, then please reach out and request such features should be enabled. At this time, effort and work will not be performed blindly upon items that will never be used, so if you see a need for this, I'd be happy to add them since you would have a need. - - - -* **Placeholder bug: The placeholder 'prison_rankup_cost_percent' uses the calculated value of a percentage, but when used with the placeholder attribute, it was found to use the price instead.** As such, the actual value returned for the placeholder was incorrect. - - -* **Player Manager: Secondary Placeholders: Setup the secondary placeholder support on the PlayerManager, but it has not been enabled yet** since secondary placeholders on placeholders do not make a lot of sense because each placeholder is only one value and they cannot contain alternative text. At least not yet. - - -* **Localizable: Secondary placeholders: Rewrote the whole support of secondary placeholders related to players.*** -Expanded the support by making them generic so other data sources can also have their own custom set of placeholders too. Such as mines. -This now supports a new interface that will provide the generic support. -Player's commands have been modified to pass a RankPlayer object, which supports the new interface. Non-player commands have not been converted since players will never see those messages (such as admin commands). - - -* **Added a comment in the ranks message files indicating that there is now some support for player based placeholders to farther customize messages.** -This also fixes an issue with the broadcast messages to use the intended player instead of the target player who is being sent the message. - - - -* **Localization: If admin adds extra parameters, or other parsing failures, happens on a message, the error will now be trapped and logged to the console without formatting.** - - - -* **Economy: For economies that prison supports that has a method to check if the player has an account, prison now tries to check if there is an account for the player before trying to use the economy.** -This could potentially prevent issues or run time failures. - - -* **Prison API: Added a few new functions to work with ItemStacks.** - - - -* **Players: Shift the function of getting a player object to the Player classes, such as CommandSender.** -This is to simplify the code and to put the functionality in one location. - - - -* **Sellall: New command: '/sellall items inspect'** -This new command will inspect what the player is holding, and dump the details so the admin can see exactly how an item/block is created, including lore and enchantments. -Eventually this information can be used to enhance the ability to sell and buy non-standard items by allowing the admins to filter on lore, enchantments, and/or NBTs. - - - -* **SpigotPlayer: Fixed a potential issue if trying to use getRankPlayer() if the ranks module is not enabled.** -Added a check to ensure it's active. -We have not seen any reports of issues related to this. - - - -* **Prison Player: Added a new sendMessage function using Lists of Strings. ** -Added a new function getPlatformPlayer() which gets a bukkit player object if the player is online. This will consolidate a lot of other duplicate code. - - -* **Mine Bombs: wrapped up the changes to enable the placement of a mine bomb when using the BlockPlaceEvent which is used when using a block for the bomb's item.** - - -* **Prison ItemStack: remove enchantments from the core ItemStack since prison cannot properly represent it in versions lower than 1.13.x**, plus it was wrong for all spigot versions greater than 1.12.x. -Added the proper enchantment functions to the SpigotItemStack object. - - -* **Initial setup of sellall lore filtering** -A little clean up. - - -**3.3.0-alpha.16c 2024-03-11** - - -* **PlaceholderAPI: Upgrade from v2.11.2 to v2.11.5** - - -* **XSeries: Upgrade from v9.8.0 to v9.9.0** - - -* **Mine bombs: add support for BlockPlacementEvent so if someone is using a Block they can use it as the mine bomb's item.** - - -* **Prison's NBT: Add support for using NBTs with bukkit's Block.** - - -* **Add support for getting the "hand" from the BlockPlaceEvent.** - - -* **Prison support listeners: added support for listening to and providing dumps for PlayerDropItemEvent, PlayerPickupItemEvent, and BlockPlaceEvent.** - - -* **Promote & Demote: Improved upon reporting issues with the command.** -There were few situations where the command would exit without reporting why, which was leading to difficulties with using the command effectively. - - -* **New feature: TopN customization now possible. The messages and placeholders that you can use are located in the core multi-language files.** -See the bottom of the files for instructions on usage. -TopN data is set to delay load so it does not lengthen the startup process. As such, it now reports that the data is being loaded so it is now clear why there are no entries in the list initially. - - -* **Mines: eliminate a field no longer used: includeInLayerCalculations.** -This was obsoleted with better use of logic. - - -* **Mine resets: Reworked how prison is selecting random blocks per layer, to properly include constraints.** -The addition of various new features in the past made a mess of the logic, so it's been cleaned up greatly so it now makes sense and should work properly now. -There is a slight risk, that as blocks are removed from a layer due to reaching it's max constraint value, that future random selections were missing blocks selections and was then inserting AIR. This fixed code now will insert a filler block which has been selected with no constraints, and the largest chance value. - - -* **mines block layerStats: rewrote to improve and get rid of the collection manipulations.** -Found potential problem with air being inserted in to mines. -Renamed a lot of uses of Location objects to include the name "location" in their variable names instead of "block". - - -* **Mines block layer: Added colors for same IDs so it's easier to read.** Added a check that sees what block actually exists. If counts of what should have spawned match whats in the mine for that layer, then it shows only one number. It shows two numbers if a block's intended spawn does not match what's in the mine. - - -* **Mine reset: added a force to the reset so it will ignore an existing mine reset and allow a new one to begin.*** -When a mine is being reset, there is no way to actually cancel it. So this allows a large mine to undergo multiple concurrent resets. Use at your own risk. - - - -* **Bug fix: the check for the time the reset has been going on was incorrect and was fixed.** -Also all the code for submitting the reset task was moved in to the mutext. Now, if the reset got hung up, this will properly terminate it and resubmit it. - - -* **File format: Eliminate the check for file types since there is only one.** -Currently there isn't a setting to specify what it should be. - - -* **Mines block layerStats: Added a new command that shows which blocks are in each layer in the mine.** -There are a lot of future enhancements that can be added to this command, such as checking the actual blocks to see if they are still there, or if there was a problem with the spawning of the blocks. - - -* **Block lists: Added the total chance percentage to be displayed with the blocks.** - - -* **File output technique: Changes to how the "replace" existing files works.** -If the file does not exist, then it opens it to create it, otherwise it truncates it. - - -* **Mine bombs: Ability to prevent a bomb's blocks from count towards the player's block totals.** - - -* **Sellall and autosell: Refinements were made to the handling of the sellall settings to better stabilize the use of the commands.** Setting status for the players were moved to the player objects and is now used in all of the related calculations so there is better stability and consistency. - - -* **Mines import: prevent the processing of an importing of a mine if there are problems with the mine's name, or locations.** - - -* **AutoSell: Bug fix: When autosell and sell on inventory is full was all turned off, it would still sell.** -This fixes some of the logic to simplify the code, and to fix those issues. - - -* **Mine skip reset messaging: Did not have it hooked up in the correct location, so the skip messages were not happening.** - - -* **Mine reset: Under heavy load when performing a mine import, there were seen occasionally errors with concurrent modification errors.** -Code was changed to minimize that possibility. - - -* **Sellall and GUI message failures: a number of messages that would indicate the player does not have access to that command were changed to remove the permission from the message.** -This was requested by a couple of admins because they did not want the players to see the internal workings that would otherwise control how the software would behave. - - - -* **Mine imports: Fix some minor issues to get this to work even better.** - - -* **Mine skip reset: If a mine is reset, send a message to players, but only if the message is defined and not empty: 'skip_reset_message='** - - - -* **Player sellall Multipliers: Fixed the ranks multiplier to include all ranks that are defined within the sellall multipliers.** -Added a new function that will gather and list all multipliers that go in to the calculation of the player's total multipliers, which includes the rank multipliers (the sellall multipliers) and also permission based multipliers. -This detailed list of the individual multipliers, is viewable for each player that is online with the command `/ranks player ` and reveals the actual details of how it's calculated. - - - -**3.3.0-alpha.16b 2024-02-24** - - -* **Import Mines: Added the ability to import mines from JetPrisonMines config files.** -`/mines import jetprisonmines help` - - -* **Prison Command Handler: using config.yml you can now change all of prison's root commands with 'prisonCommandHandler.command-roots'.** -Can now map 'prison', 'mines', 'ranks', 'gui', 'sellall' to all new command that you want. - - -* **File saving: alternative technique for saving files. Do not use!** -This is a more dangerous technique that could possibly result in lost configurations. This is being provided as a degraded service if the fail-safe technique is not working ideally on a degraded server. -This should never be used, unless directed by a prison support admin. - - - -* **Prison startup bug: There was an issue with the prison startup when there was an error and prison tried to log the error**, only to find that resources that were needed for logging were not yet loaded nor were their dependencies. This fixes some of the entanglements to allow the error messages to be properly logged. - - -* **Bug fix: GUI configuration: Found a problem that when configuring the gui initial settings, that there were problems when trying to access mines and ranks when they don't yet exist.** - - -* **Add prison debug option to filter on blockConstraints when regenerating the blocks within the mines.** - - -* **Bug fix: prison support submit: if the bukkit system cannot extract a file from the jar**, such as plugin.yml, this will prevent the failure of the command. This will allow the command to continue being processed, but may just skip the extraction. - - - -* **Placeholders: Top player rank was using the wrong ladder, which was incorrectly the prestiges rank and not the default rank.** -Correcting the rank fixed the problem. This only was an issue if the player did not have a prestige rank. - - - -* **Mines set resetTime: fix typo in the description where it shows '*all' instead of '*all*'.** - - -* **ranks ladder: applyRanksCostMultiplier command was changed to allow the value of 'true' to be used along with the value of 'apply'.** This helps to eliminate some confusion on how the command works. - - -* **Bug fix: Prison command handler. When players are de-op'd, and they do the commands such as `/ranks help` or `/mines help` it was incorrectly showing other sub commands they did not have access to.** -This now shows the correct sub commands that they have access to. - - -* **Placeholders: topn players - bug fix. If a player did not have a prestige rank, then it would cause a NPE when using the `prison_top_player_rank_prestiges_nnn_tp` placeholder.** -Just check to ensure its not null... if it is, then return an empty string. - - -* **Bug fix: Player manager startup: fixed a problem where all players were being updated** even though they did not have a name change. Only when name changes are detected are the files updated or when a new player is found. - - -* **Add debug statements to identify how each block was calculated during a mine reset.** - - -* **Bug fix: block constraints: fix an issue with the selection of lower limits.** - - -* **updated the help on the `/mines block constraint` to indicate that the layer count is originating from the top, not the bottom.** - - -* **alpha.16a - 2023-12-28** - NOTE: I just noticed that alpha.16a was never committed. So this is not the correct location of when it was set with the local builds. - - -* **Mines: Fixes an issue for when mines are disabled and they are being checked in other processes to see if they are active.** -If the instance of PrisonMines is null, then it will create a temp instance just to prevent an NPE. - - -* **Mines unit tests: Setup a new constructor for mines that is only to be used with unit tests which allows the mines to be created,** but it does not initialize them since such tasks and processes are not needed in the unit tests. -As a side effect, these two unit test run much faster since it's not trying to setup tasks. - - -* **Prison Block change: Add support for display name, which is optional.** -Setup sellall so it can use the display name now, so renamed items will not be mistaken for vanilla minecraft items. -More work needs to be done to hook up displayName to other features, such as sellall and add prison block to mines. - - -* **Bug fix: Fixed the command `/mines set accessPermission` where it was apply the given perm to all mines.** - Likewise, all mines parameter was failing to do anything. - - -* **NOTE: This alpha version "should" support spigot 20.0.4.** -After a few days, if no other issues surface pertaining to 20.0.4, or other related plugins, this will be released as a public release. - - -* **Fix issue with BlockEvent's SellAll when isAutoSellIfInventoryIsFullForBLOCKEVENTSPriority feature is enabled.** -This was not using the correct new functions that checks to see if a player can use autsell, or if they have it temporarily toggled off. This also checks to see if the player has the correct perms, if perms are enabled for the sellall event. - - -* **Breaking change in XSeries: GRASS has been changed to SHORT_GRASS for v20.0.4!** It's disappointing to say the least that after all of these damn years, XSeries screwed up and pushed a breaking change to their repo. They should have kept GRASS so they would have remained compatible will all past code and configs that had to refer to GRASS directly, but nope... they opted for causing problems. Very disappointing. -Setup a converter to automatically convert all GRASS to SHORT_GRASS as the mines are loaded. - - - -* **Upgrade XSeries from v9.7.0 to v9.8.0.** -* **Upgrade nbt-api from v2.12.0 to v2.12.2.** - - -* **config.yml - changed the default values for remapping aliases and restricting players from using commands.** -The default, which used `/mines tp` was actually causing conflict with normal usage. - - -* **AutoFeatures auto permissions: enable the ability to 'disable' the perms.** Any op'd player, if perms are enabled, will have these auto features enabled. There is no other way around this, since this is the correct behavior of OP'd players. - - -* **Mine resets: If a mine reset takes longer than 4 minutes, then that is probably a failure and the mine reset did not complete.** Therefore, reset the mine reset mutex and try again. This allows a "crashed" mine reset to auto fix itself if it can. The 4 minute wait time is LONG, but it will prevent a normal reset from being canceled and restarted in the middle of a restart. - - -* **Performance: Changed the defaults for the mine reset settings to help improve the performance on larger servers.** -The older settings would allow other commands to backup and it would appear as if there was lag happening, TPS would rarely drop below 20. This helps to keep performance a little more responsive. -The side effect is that there will need to be more "chunks" submitted which could possibly result in longer wall-time for mine resets. - - -* **Mine resets: If a suggested block is null, then set it to air. This was causing an NPE under some conditions.** - - -* **BlockEvents: Added the ability to update block events** -instead of deleting them and re-adding them. Follow directions when using '/mines blockevent update help', or whenever a block event listing is shown in game, you can now click on the commands to auto populate the block event update command... then just edit the needed changes and submit. - - -* **Upgrade XSeries to v9.7.0 from v9.4.0.** - - -* **Bug Fix: Mine resets and block constraints.** -This fixes a few issues with block constrains using min and max, along with exclude from top and bottom too. - - -* **Bug Fix: GUI ranks, mines, and prestiges were not using the default item name correctly.** It was using the template correctly, but was not translating the use of placeholders. Only name and tag are supported. -Mines: `{mineName}` and `{mineTag}` -Ranks and prestiges: `{rankName}` and `{rankTag}` - - -* **Mines: Added support for '*all*' for mine names for the following mine commands: resetDelay, resetThreshhold, notificationPerm, and accessPermission** - - -* **Localizable: Bug fix. Blanks were being removed by the use of trim() so the spaces were being ignored.** - - -**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.** - - - -* **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. +## Current Change Log - Part 2: -* **Sellall command: '/sellall set delay' - fixed the description which had a typo in the description.** +**[v3.3.0-alpha - Current - Part 2](changelog_v3.3.xb.md)** +- **v3.3.0-alpha.17** 2024-04-20 and older -* **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** - - - -See [Prison Change log v3.2.3-alpha.15](prison_changelog_v3.3.0-alpha.15.md) - - - -**Prison v3.3.0-alpha.14 2023-01-23** - - -See [Prison Change log v3.2.3-alpha.14](prison_changelog_v3.3.0-alpha.14.md) - - - ---------------------------- - - - -**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. - - -* Added a new tool: `mines tp list` which will show a player all of the mines they have access to. They can also click on a listed mine to generate the TP command. This command can also be ran from the console to inspect what players have access to. -* Fixed a recently introduced bug where if the server starts up, but someone has no ranks, it was not able to properly assign them their first default rank. It was leading to circular references. -* Fixed an issue with color codes not being translated correctly with placeholderAPI. -* Prison has a rank cost multiplier where ranks on different ladders can increase, or decrease, the cost of all ranks the player buys. So when they prestige, it makes ranks A-Z cost more each time. What's new is that now you can control which ladders these rank cost multipliers are applied to, such as not on prestiges, but only on default. -* Fixed calculations of the placeholder `prison_rank__player_cost_rankname`. It was not fully working with every possible rank on every possible ladder. Now it works correctly if trying to get the player's cost for even many prestige ranks out (it includes cals for all A-Z mines at multiple passes). -* Mine bombs: Changed to only allow mine bombs to be setoff withn mines the player has access to. Fixed an issue with color codes within the mine bomb's tags. -* Fixes issues with NBT, color codes with prison broadcast commands. -* Rewrote topN for better performance: `/topn`. Older players are archived within topN and can be queried: `/topn archive`. -* Update ladder details on a few commands. -* Update XSeries from v8.8.0 to v9.0.0 so prison now supports 1.19.x blocks. -* Bug fixes with first join events. Bug fix with a few guis. -* CMI update: If CMI is detected at startup, and delayed startup is not enabled, prison will go in a simple delayed startup mode to allow CMI a chance to enable it's economy through vault. This reduces the learning curve with CMI users. -* New feature: Prison will now make an auto backup of all files in it's directory when it detects a change in version. Can manually backup too. The backup stores temp files then removes them from the server, this helps keep the server clean. -* Update bstats: Gained control of the account and started to add useful custom reports to help zero in on what we need to help support. -* More work on block converts. Will be added in the next alpha releases. -* Bug fixes: mines gui fixes for virtual mines. Sellall bug fixes. Placeholders fixes. - - - - -* **Minor addition to bstats.** - - -* **Player Mine GUI had the wrong calculation for volume which also threw off blocks remaining and percent remaining.** -The calculation for volume was using the surface area and not the total number of blocks. - - -**v3.3.0-alpha.12L 2022-08-25** - - -* **Updates to the bstats....** - - -* **New placeholders: `prison_rank__linked_mine_tag_rankname` and alias `prison_r_lmt_rankname`.** -Similar to `prison_rank__linked_mine_rankname` but uses the mine's tag instead of the mine's name. - - -* **Mine TP list: use mine tags and clickable mines to teleport to them.** - - -* **Mines TP list. Added a new options to mines tp command to list all mines that the player actually has access to.** -Not finished with it... will add clickable links to them when in game. - - -* **There was an unused updated tool in prison. It's against my policy to auto update this plugin, which would need to be consented to anyway, but I feel that admins need to be in full control of updates and know what is included in the updates. There was identified a potential exploit called zip-slip-vulnerability that could hijack a server if malicious zip is extracted. Prison never used this tool, so it's been fully disabled with no intention of reenabling. It may be deleted in the near future.** - - -* **TopN bug fix: If a player was in an archived state, they were not being moved to active when they would login.** - - -* **If the player is holding the mine bomb in their off hand, then remove the inventory from their off hand.** - - -* **v3.3.0-alpha.12k** - - -* **Fixed an issue when starting the server an no ranks exist. Also fixes an issue when starting the server an a player has no rank.** -Was using a mix of really old code, and the latest code, which caused a conflict since neither was doing what it was really supposed to. - - -* **Added the custom bstats report for Prison Vault Plugins.** -This reports all plugins that have been integrated through Vault. This report does not impact any other plugins report. This is segmented by integration type. - - -* **Fixed bug when server starts up when no player ranks exist.** -It will now bypass the player validation until ranks have been configured. - - -* **v3.3.0-alpha.12j 2022-08-21** - - -* **Update bstats to remove old custom reports that are not wanted/needed anymore.** -Added 6 new placeholder reports that classifies placeholders ini various categories related to how they are used within prison. Any placeholder that appears in these lists, will not be included in the generic 4-category placeholder lists. -Added a few more simple pie charts to cover a lot of the details on ranks, ladders, and players. Simple is better so you can just glance at all of them, without having to drill down on each one. - -* **v3.3.0-alpha.12i 2022-09-19** - - -* **TopN players - fixed an issue where topN was being processed before the offline players were validated and fixed.** -There was an issue with processing an invalid player that did not have a default rank. - - -* **v3.3.0-alpha.12h 2022-08-19** - - -* **Rankup costs: Minor clean up of existing code. Using the calculateTargetPlayerRank function within the RankPlayer object.** - - -* **PAPI Placeholders: Force color code translations on all resulting placeholders.** -There were a few issues where placeholder color codes were not being properly translated. This was not consistent with everyone. Not sure why it was working for most. -These changes are more in line with how chat handlers and MVdW placeholders works. - - -* **Ladder: apply rank cost multiplier to a ladder or not.** -This new feature enables you to disable all rank cost multipliers for a specific ladder. Normally that rank cost multiplier applies to all ladders, but now you can suppress it. It's for the whole ladder, and not on a per rank basis. - - -* **Fixed an issue with calculating the player's rank cost when they already on the presetiges ladder and calculating the higher prestige ranks.** -Appears as if this becomes an issue when at the last rank on the default ladder. - - -* **v3.3.0-alpha12g 2022-08-14** - - -* **Fxing of the calculations of the placeholder prison_rank__player_cost_rankname and related placeholders.** -The original implementation did not take in to consideration the prestige ranks in relation to the default rank. -The improvements in this calculation now generates a list of all ranks between the current rank and the target rank. So if a few prestige ranks out from the player's current prestige rank will result in calculating every rank in between including multiple passes through all default ranks. So if there are 26 default ranks, and the player is at rank A with no prestiges, then to calculate rank P4 would include the following ranks: -b --> z + p1 + a --> z + p2 + a --> z + p3 + a --> z + p4. -This results in a total of 107 ranks that must be collected, then the player's cost for each rank will have to be calculated. Then all of these must be added together to get the player's cost on rank P4. -This calculation has to be performed for each rank in it's entirety -Warning: this calculation on high prestige ranks will be a performance issue. If this becomes a problem on any particular server, then the only recommendation that can be provided is not to use any of the prison_rank__player_cost placeholders. - - -* **TopN : a few more adjustments to fix a few issues with duplicates and also with using values from within the topN to include in the report to help minimize the need to recalculate everything especially with archived entries.** - - -* **Mine bombs: Fixed an issue with the mine bomb names not always working with color codes.** -Honestly the wrong function was being used so how it even worked I don't know. lol - - -* **New topN functionality: far better performance, with regular updates.** -TopN now is a singleton and is self contained. When the singleton is instantiated, it then loads and setup the prisonTopN.json file on the first run. 30 seconds after the initial load, it then hits all players to load their balances in an async thread. -The command /ranks topn, or just /topn has new parameter: "archived". Any player who has not been online for more than 90 days will be marked as archived. The archived option will show just the archived players. -Setup new parameters within config.yml to control the topn behavior with the async task. - - -* **v3.3.0-alpha.12f 2022-08-08 ** (forgot to commit when made this version) - - -* **Mine Bombs: Only allow bombs to be placed when within a mine that the player has access to.** -This will help prevent wasted bombs. - - -* **Fixed an issue with nbt items not having a value for toString().** - - -* **Encode color codes for the prison utils broadcast command.** - - -* **Added an "invalid player name" message to the rankup commands.** -Also added missing messages to the zh_TW.properties file. - - -* **BlockEvents were changed to auto display the existing rows so it's easier for the end user to know which row to select.** -All they need to do is to enter the mine's name, then press enter to submit the command, and then the existing rows details will be shown. Then the user can select the row and complete the command. -Updated docs on block events. - - -* **BlockEvents were changed to auto display the existing rows so it's easier for the end user to know which row to select.** -All they need to do is to enter the mine's name, then press enter to submit the command, and then the existing rows details will be shown. Then the user can select the row and complete the command. - - -* **minor updates for disabled mine reset times. No functional changes were made.** - - -* **Fixed a potential NPE with giving the players overflow blocks, but not sure what the exact cause was, but looked like there was an issue with mapping to a spigot item stack.** - - - **CMI delayed startup: Added new feature to try to auto enable Prison's delayed startup if CMI is detected as an active plugin, and if the delayed startup is disabled within the config.yml.** -This is to help get more CMI users up and running without more effort, but yet still provide the ability to customize how it is triggered. -If CMI is active, there is NO WAY to disable a delayed startup check.* - -* **Added the the option for playerName to the `/rankup` command so the command can be scripted and ran from the console.** - - -* **There was another issue with using `/gui` related to no ladders being loaded.** -This fixes that problem, and it appears like the issue was caused by plugman messing things up. This does not "solve" the problem with ladders not being loaded, but prevents the NPE from happening. - - -* **There was an issue with `/prison reload gui` causing a NPE.** - - -* **Fixed the `/ranks topn` command (`/topn`) to sort the list of players before printing the list.** -The list was being set a server startup time, and if someone would rankup or prestige, it was not reflecting their new position. The list is also now sorted after each rankup. Sorting should be a low cost operation since the list used never is regenerated so the changes made during sorting is minimal at best. - - -* **Added the ability to control the prefix spaces on the unit names.** -NOTE: may need to enable the use of the `core_text__time_units_short` since the long units are not being used. May need to create another placeholder for short/long. It used to be short, so may need to use long with the new placeholder and convert the calcs to the short as the default. -This was requested by PassBL. - - -* **v3.3.0-alpha.12e** - - -* **Fixed issue rank null issues when showing ladder details.** - - -* **Prison backups: Fixed an issue with folders not existing when running the backups the first time.** - - -* **v3.3.0-alpha.12d 2022-07-25** - - -* **Added more information on ladder listing to show name, number of ranks, and rank cost multiplier.** - - -* **bStats update: Added a new bstats custom chart for auto features.** - - -* **Update some docs. Added docs for Prison Backups** -[Prison Backup Document](prison_docs_050_Prison_backups.md) - - -* **Upgrade XSeries from v8.8.0 to v9.0.0** - - -* **Fixed issue with prison version check triggering a backup upon startup.** -It was always bypassing the previous version check, so it was always creating another backup. - - -* **Update bstats by moving to its own class in its own package.** -Added 4 new custom charts to split the plugins in to 4 parts. - - -* **Fixed a few issues with the ranks gui where they were using the wrong message key (placeholder).** - - -* **Prison v3.3.0-alpha.12c** - - - -* **Prison bstats: setup 4 new bstats charts for prison. May change a few charts or add new ones in the near future.** -Got control over the prison bstats so can now add custom stats. - - -* **Prison backups: Created a Prison/backups/versions.log file which gets logs when a new prison version is detected on startup, which also performs a backup.** -All backups are also logged in the versions.log file too. - - -* **v3.3.0-alpha.12b** -- Added the fix for the placeholders. See next note. - - -* **Fixed an issue with placeholders not be properly evaluated; there were 3 sections and they were combined in to one so it would not bypass any.** - - -* **Possible bug fix with first join: it appears like it was inconsistant with running the rank commands. Fixed by rewriting how the first join event is handled.** - - - -* **Prison backups: Added new features where it is generating a stats file in the root of the zip file which contains all of the "prison support submit" items.** -This is just about ready, but lacking support for auto backups when prison versions change, or job submission to run auto backups at regular intervals. - - -* **Setup a prison backup command that will backup all files within the prison plugin folder.** -When finished, it will delete all temp files since they have been included in the backup. -The new command is `/prison support backup help`. - - -* **v3.3.0-alpha.12a** - - -* **Added a new set of intelligent placeholders: these show the tags for the default ladder and prestige ladder, for the "next" rank but are linked together.** -They only apply to the default ladder and the prestige ladders. The tags are only shown if the player has that rank, or if that will become their next rank. -These ONLY show the tags that will be appropriate when the next rank up. So if the can still rankup on the default ladder, then only the default rank shows the next ranks tag. If they are at the end of the default rank, then it will show the next rank on the prestiges ladder; if they do not have a rank there currently, then it will show the next prestige rank with the default rank showing the first rank on that ladder. - - -* **When the command handler starts up, it now logs the pluigin's root command and the command prefix which is used if there are duplicate commands found during bukkit command registration.** - - -* **Bug fix: Placeholders search was missing the assignment of the placeholderKey, which is what would like the search results on the raw placeholders, with the actual data that is tied back to the player.** -In otherwords, without the PlaceholderKey it was not possible to extract the player's data to be displayed within the command: /prison placeholders search. - - -* **Added constants for the default and prestiges ladder name so it does not have to be duplicated all over the place, which can lead to bugs with typos.** - - -* **Sellall bug fix: There wasn't a common point of refernce to check if sellall is enabled. Many locations were directly checking config.yml, but the new setting has been moved to the modules.yml file. ** -If config.yml has sellall enabled in there, it will be used as a secondary setting if the sellall setting in modules.yml is not defined or set to false. Eventually the config.yml setting will be removed. - - -* **Found that bStats was erroring out with the servers hitting the rate limit so this makes a few adjustments to try to get prison to work with bstats.** -Basically plugins that load last will be unable to report their stats since every single plugin that is using bstats submits on it's own, and therefore it quickly reaches the limits. - - -* **BlockConverters: More changes to block converters.** -Added defaults for auto blocking, and for auto features with support for *all* blocks. - - -* **Bug fix: mines gui was not able to handle virtual mines with the internal placeholders. -This bug fix was included with the deployment of alpha.12 to spigotmc.org. - - - -* **Pull Request from release.branch.v3.3.0-alpha.12 to Master - 2022-06-25** - - -This represents about six months of a lot of work with many bug fixes, performance improvements, and new features that have been introduced. The last two alphas were not pulled back to main, but they were released, This PR will preserve the released alpha as it has been published. - -Also, this helps to ensure that this work will not be lost in the event the bleeding branch is lost/removed. Hopefully it won't be, but a lot of work has gone in to it and it will be impossible to recreate the current state of the alpha release. - -This version, v3.3.0-alpha.12, has 300 commits and 323 changed files. The list of actual changes since v3.2.11 is substantial and the change log should be referenced. - -Highlights of some of the changes include (a sparse list): - -* new block model - full support for CustomItems custom blocks - updated XSeries which mean prison supports Spigot 1.19. -* major improvements to auto features - streamlined and new code - higher performance - many bugs eliminated - now supports drop canceling to make prison more compatible with other plugins -* better multi-language support - supports UTF-8 -* Improved rankup - rankup commands are now ran in batch and will not lag the server if players spam it -* rewrite of the async mine resets - next to impossible for mine resets to cause lag - Uses a new intelligence design that will throttle placing blocks as the server load increases, which makes it next to impossible for it to cause lag. -* Enhanced debugging tools - if a server owner is having issues, prison has more useful tools and logging to better identify where the issues are - new areas are not able to log details when in debug mode - debug mode now has a "count down timer" where if debug mode is 8enabled like /prison debug 10 then it will only allow 10 debug messages to print, then it will turn off debug mode automatically. This is very useful on very heavy servers when a lot of players are active... it prevents massive flooding of the console. -* Major rewrite of the placeholder code that identifies which placeholder raw text is tied to, so it can then retrieve and process the data. - Pre-cache that provides mapping to raw text, so once it is mapped, it can prevent the expensive costs of finding the correct placeholder - Added the beginning of tracking stats (through the pre-cache0 and will be adding an actual placeholder cache in the near future. -* Mine Bombs - fixes and enhancements -* Starting to create a new sellall module that will support multiple shops and custom blocks (not just XMaterial names) -* Block Converters - Will allow full customization on all block specific things within auto features - will eliminate all hard coded block -* Started to add NBT support. - Used in mine bombs - Starting to use in GUI's to simplify the complexity of hooking actions up with the menu items. -* Added rank scores and top-n players - Rank score is a fair way to score players within a rank. It's currently the percentage of money they have to rank up (0 to 100 percent), but once they cross the 100% threshold, then 10% of the excess subtracts from their rank score. This prevents camping at levels. -* There is more stuff, some major, a bunch of minor, and many bug fixes along the way. - - - - - -* **v3.3.0-alpha.12 2022-06-25** - - - -* **v3.3.0-alpha.11k 2022-06-20** -Plus luckperms doc update. - - -* **Mine resets: Fixed an issue when dealing with zero-block resets on a very small mine, such as a one block mine in that the 5 second delay was preventing from rapid resets.** -Bypass both 5 second cooldown on resets and blockmatching when 25 blocks or less for the mine size. -With running resets in async mode, with rapid resets for a one-block mine, the handling of the block breaks can occur out of order, which will trigger the block mismatch. - - -* **Fix issue: On the creation of a new mine, it would reset the mine a number of times. This fixes the problem by only allowing one reset every 5 seconds at the soonest.** - - - -* **Placeholder fix: The PAPI placeholder integrations should not be prefixing raw text with "prison_"; that is the task for PlaceholderIdentifier.** - - -* **minor items changed with the GUIs... no functional changes.** - - -* **Update a number of docs...** - - -* **Fixed an issue where if you try to use a % on a number it's causing String format errors.** -This now strips off % and $ if they are used. - - -* **Update Docs: LuckPerms groups and tracks... added images and fixes a few minor things too.** - - -* **Update some of the docs on setting up luckperms and tracks.** - - -* **v3.3.0-alpha.11j** - - -* **Since the chat event is handled within the spigot module, and since ranks and mines would just duplicate the processing since they both will hit the SpigotPlaceholder class, it made sense to handle the chat event directly within the spigot module.** - - -* **Updates to the prison placeholder handler. This fixes a bug with chat messages return a null value.** -These changes also allows the pre-cache to track invalid placeholders now, so it can fast-fail them so it does not have to waste CPU time trying to look up which placeholder key they are tied to. - - -* **v3.3.0-alpha.11i** -Getting ready to release alpha.12. - - -* **Placeholder stats: A new feature that is tracking usage counts with placeholders.** -This is not a placeholder cache that caches the results, but it caches the placeholder that is associated with text placeholder. The stats currently only tracks the total number of hits, and the average run time to calculate the placeholder. -The pre-cache will reduce some overhead costs. This also provides the framework to hooking up a formal placeholder cache. - - -* **Placeholders: changed the two top_player line placeholders that are the headings** - since they originally had _nnn_ pattern that is getting messed up in some settings. So removal of the nnn helped to getting it working. - - -* **GUI MInes: Update support for custom lore support within the gui configs.** - - -* **Update XSeries from v8.7.1 to v8.8.0 to better support the newest blocks.** - - -* **Updated item-nbt-api-plugin from v2.9.2 to v2.10.0.** - - -* **v3.3.0-alpha.11h 2022-06-14** - - -* **Prison Placeholders: General clean up of obsolete code.** -Since the new placeholder system is working well with the new class PlaceholderIdentifier, obsolete code that was commented out has been removed. -The obsolete class that used to be the key component to identifying placeholders was PlaceholderResults and is no longer used anywhere. It's core components were moved to PlaceholderIdentifier and therefore all references to this obsolete class has been eliminated. -At this time, PlaceholderResults has not been deleted, but will be at some future time. - - -* **Prison Placeholders: Major rewrite the handling of placeholders.** -Prison's placeholder handling was completely rewritten to better handle the matching of a placeholder text with the actual placeholder objects. Over the last few years, many new features were added to prison's placeholders, but the way they were implemented were through patching existing code. This rewrite starts from scratch on how placeholder are decoded. Placeholders are now only decoded once instead of being decoded when attempting to match each internal placeholder. The results are significant performance improvements and eliminates a lot of redundant code. Some new features were add, such as supporting more than one placeholder attribute at a time. Also it streamlines how parameters and data is passed from the outer most layers of prison to where the placeholders are calculated. - -Another major benefit of this rewrite, beside reduction of code complexity and performance improvements, is that it opens the door to being able to implement an internal placeholder cache. Some plugins request placeholder data once per tick, or 20 times per second. Multiply that by 50 online players, and you got prison performing the same calculation 1000 times per second. Caching could help reduce that to only one calculation per second (assuming a cache time to live value of 1 second. Caching will not always be so simple, or possible, or every placeholder. Player-based placeholders can't be cached like static mine placeholders (mine names and mine tags as an example). - - -* **Add support for Portuguese.** - - -* **BlockConverters: fix issue when block converters are not active.** - - -**v3.3.0-alpha.11g - 2022-06-11** - - -* **Disable the gui for autofeatures configs. They are so out of date, they were causing problems.** -Autofeatures should be manually edited. - - -* **Fix a problem when BlockConverters are disabled, and doing a reload on auto features, it's not able to find that config file so its throwing an exception.** - - -* **The build was failing intermittently on the continual integration (CI)** -pertaining to the item-nbt-api-plugin, so an entry to added to "lock it in" to the correct path within the mavenrepository.com repo. -This should prevent the resource from being paired with the wrong repo. - - -* **There is a situation when checking for new updates to the language files, that it needs to write the new file, but the old one has not been archived.** -This now checks to make sure the old one has been renamed, and if it hasn't, then it will rename it. - - -* **Added an entry for the sellall module in the modules.yml file.** -Code has been setup to check, with a default fall-back on to the sellall settings within config.yml file. The entry in config.yml has been commented out. -Either will work, but the setting within modules.yml will take priority. - - -* **Update XSeries to v8.7.1 from v8.6.2.** -Note that this does not add any of the newer 1.19 blocks or items. - - -* **GUI: Fixed some issues with the gui and admin perms. Added some admin perms to a few gui commands to lock them down.** -Found a serious issue with non-admins being able to edit rank costs and sellall item costs. The GUIs were not locked down and if the players knew the commands, they could edit the costs. - - -* **v3.3.0-alpha.11f 2022-06-06** - - -* **BlockConverters: minor changes.** - - -* **Bug fix: Backpacks were not working properly with just ".save()" but had to add ".setChanged()" too, otherwise minepacks will not actually save the status of the backpacks.** - - -* **BlockConverters: rename targets to outputs.** - - -* **BlockConversions: hooked up the code to not only filter and return the blockConversions for the player and the block, but to also return the item stacks from the results.** -This is just about ready to be used in the code. - - -* **Romanian Locale language files were placed in the wrong location.** -Oreoezi provide two new language files for the Romanian Locale, but they were placed in the wrong location. -They were added to "prison-core/out/production/resources/lang/core/" and ".../mines/". For them to actually -work correctly, without being deleted, need to be placed within the following path: -"prison-core/src/main/resources/lang/core/" and "prison-core/src/main/resources/lang/mines". -These should now be usable. Also the LocaleManager now has alternatives setup to default to en_US; future -alternative languages can be added in the future. - - -* **BlockConverters: add some validators to the BlockConverters.** -Reports various issues, fixes non-lowercase source block names, and also disables invalid settings. - - -* **BlockConverters: Adjusting around how they are setup, and how they are generated.** -BlockConverters are now in their own config file: blockConvertersConfig.json. -They are no longer being stacked/placed in the autoFeaturesConfig.yml file, so all the conversion code is no longer required. With it being json, it now can reflect the java classes without any special considerations on the conversion process. - - -* **BlockConverters: More work on these settings.** -Setting up to work with AutoFeaturesConfig.yml, but having second thoughts about adding these configs to that file since it will complicate the config details. - - -* **Fixed a bug on the smelting of coal_ore which was yielding 10 times too much, but this was never seen since a silk touch pickaxe would have to been used.** - - -* **Placeholder fix for `prison_mines_blocks_mined_minename` since it was not being incremented after the fixing of the autopickup=false and handle normal drops = true.** -Also found that the calculated field for the mine's total blocks mined was not being recalculated after load the mines from their save files. This now is working properly. - - -* **Major exploit fix: sellall was not indicating that the inventory was changed within the Minepacks backpacks,** -and therefore players were able to sellall of their inventory, logoff, and then when they log back on, it will be restored. -Now, all inventory changes are forcing a save for the backpacks. - - -* **Fixed an incorrect mapping to a message: auto features tool is worn out.** - - -* **v3.3.0-alpha.11e 2022-05-23** - - -* **Bug fix: Fixed an issue with sellall when the module sellall is not defined but sellall is enabled in the config.yml file.** - - -* **Bug fix: Minepacks has a new function in their API to force backpack changes to be saved.** -Before it could only be marked as changed, which was not enough to get it to save in all situations. Prison is now calling "save()" to ensure its behaving better now. -NOTE: releasing this fix with alpha.11d even though it has been added after being set to 11d. - - -* **Prison v3.3.0-alpha.11d 2022-05-22** - - -* **GUI messages: a few more updates and corrections** - - -* **GUI: More fixes to the gui messages... including moving all of the new gui specific messages out of prison-sellall module to the prison-core module so they will still be accessible if the prison-sellall module is disabled.** - - -* **GUI cleaned up by eliminating so many excessive uses of translating amp color codes to the native color codes.** -Found some locations where there were at least 7 layers of function calls, with each layer trying to translate the color codes, which of course was excessive. - - -* **Change the name of the SpigotSellallUtilMessages class to SpigotVariousGuiMessages due to the fact these messages are used in more than just sellall.** -It should be noted that eventually the non-sellall messages may have to be removed from the sellall module. - - -* **Spigot GUI Messages: Hook up more messages to prison's messaging system.** - - -* **Sellall messages: Start to setup the correct usage of the multi-language message handling through the new prison-sellall module.** -This fixes the messaging within the SellAllUtil class. - - -* **Move auto feature messages to the spigot message file so they can be customized.** -Removed the inventory full messages from the AutoFeaturesConifg.yml file. - - -* **The normalDrops processing was not hooked up to the newest way auto pickup is disabled, which was skipping normalDrops if auto pickup was disabled.** -The number of blocks in the normalDrops is now being passed back through the code so it can identify that it was successful and finalize the processing. - - -* **3.3.0-alpha.11c 2022-05-14** - - -* **GUI Menus enable NBT support.** -This is a major change. The details for the menus options and commands are now stored in NBT data so they do not have to rely on the item name, lore, or other tricks. -This is a first phase, and more work needs to be done to remove hooks with the item names for other menu options. Main set of changes has been done to the menu tools. - - -* **Changed placeholder attributes to print the raw value and placeholder.** -Changes to the logging to allow & to be encoded to the unicode string of -`U+0026` so it can bypass the color code conversions, then it is converted back -to an & before sending to bukkit. This works far better than trying to -use Java regEx quotes. - - -* **Fixed signs for sellall to enable them to work with any wood variant.** - - -* **3.3.0-alpha.11b 2022-05-02** - - -* **Placeholder fix for formatted time segments to use the values setup in the language files within core.** -This allows the placeholders to use the proper notations for singular and plural units of times as configured for each language. - - -* **Placeholder fix for rankup_cost and rankup_cost_remaining on both the formating of the percents and the bar.** -The percents were being displayed as an integer, so with rounding, they were very misleading since they would show 100% when they were really hitting 99.5% and higher. Also the bar is not working better, and if the percentage is less than 100%, then it will always show a RED segment at the end of the bar; it will ONLY show GREEN when it's 100% or higher. - - -* **Mine Bombs fix to allow color codes within the bomb's name.** -The color codes are removed for the sake of matching and selecting when giving to players so you don't have to use them in the commands. - - -* **Placeholder issues when not prefixed with "prison_" is being addressed by prefixing the identifier with "prison_" right away.** -This "is" addressed, but it's deep in the code and for some reason certain parts of the code is not making the connection to the correct placeholder without that prefix. So this really is not the desired way to address this, but it eliminates the problem. The reason why it's not the desired way, is because it's exposing buisness rules of how to handle the placeholders, outside of the placeholder core code. - - -* **Bug fix... with placeholder prison_rank__player_cost_remaining_rankname, and its variants,** - eliminate the calculation of including the current rank since that has already been paid for. Prior to this fix, it was only excluding prior ranks. - - -* **3.3.0-alpha.11a 2022-04-25** - - -* **Mine Bombs and NBT settings: this fixes mine bombs to work with NBT tags, which are being used to identify which items are actually mine bombs.** - - -* **Fixes the mine bomb usage of lore where the lore that is defined in the settings is no longer altered so it's now used verbatim.** -Also the check for mine bomb is removed from using the name, or first line of lore, and now tries to use NBT data. -But note, that the NBT data is not working correctly yet. - - -* **Fixed the usage of setting up the NBT library within the gradle config file.** -Fixed issue with unknown, or incompatible items were unable to be parsed by XMaterial which was resulting in failures. This fixes the problem by preventing the use of a partial created SpigotItemStack. - - -* **Hook up the NBT library to the SpigotItemStack class.** -This has not been tested yet to see how it works, especially between server resets. - - -* **Added NBT support to prison. This loads a NBT library to be used only with the spigot sub-project.** -This has not been hooked up to anything yet. - - -* **Placeholder fix: Problem with the placeholder getting a prestige rank that was one too high.** -The following placeholders were fixed: prison_rrt, prison_rankup_rank_tag, prison_rrt_laddername, prison_rankup_rank_tag_laddername - - -* **Hooked up the BlockConvertersNode to the yaml file IO code so it will save and load changes to the auto features configs for anything with the BlockConverters data type.** -Removed unused functions. - - -* **Mine reset potential bug fix: Some rare conditions was causing problems, so using another collection to pass the blocks, and getting the size prior to calling the function to prevent the problems from happening.** -This appeared to be happening when a mine was being reset multiple times, at the same time. The mine should never be resetting multiple times, at the same time. May need to add more controls to prevent it from happening. - - -* **Bug Fix: The IGNORE block type was not marked as a block, therefore could not be used within a mine.** - - -* **New feature: Block Converters. Setup the initial core settings for block converters within the auto features.** -The core internal structure is in place and so is the ability to write the data to the file system. -This has not been hooked up to anything yet. - - -* **Setup placeholder formatted time values to use the language config file.** -This set of values will "NOT" reload when the command `/prison reload locales` is ran. The server must be restarted to reload these values. - - -* **CustomItems getDrops() debug mode will list the results of the get drops.** -This will help track what's going on with the getDrops function since it's a complicated process. - - -* **Placeholders: prison_rankup_rank_tag (and the ladder variants) now shows the prestiges next rank when at the top rank in the default ladder.** -This only applies to the default ladder and only if the prestiges ladder is activated. - - -* **Pull out the setBlock and blockAt functions from the SpigotWorld class so that way it would properly track within Timings.** - - - -** v3.3.0-alpha.10 2022-04-02** - -** Release notes for the v3.3.0-alpha.10 release as posted to spigotmc.org and polymart.org: - -v3.3.0-alpha.10 - -This alpha.10 release includes many significant performance improvements and bug fixes. Although this is an alpha release, it is proving to be stable enough to use on a production server. Please make backups and test prior to using. This v3.3.0-alpha.10 release is "still" backwards compatible with v3.2.11 so you should be able to down-grade back to v3.2.11 without major issues. The breaking changes that will be in the final v3.3.0 release have not been applied yet to these alpha releases. - -Please see our discord server for the full listing of all bug fixes and improvements, there have been more than 70 updates since the alpha.9 release. The following is just a simple short list. - -- Many bug fixes. Some that even predates the v3.2.11 release. - -- Performance improvements: startup validations moved to an async thread. Slight delay between mine validations to allow other tasks to run (needed for less powerful servers). Improvements with sellall performance. - -- Added more support for Custom Items (custom blocks) - -- Added support for top-n players and added over 30 new placeholders. Top-n support for blocks mined and tokens earned will be added shortly too. - -- Upgraded internal libraries: bstats, XSeries, gradle, custom items, and a couple others. - -- Many fixes: Mine bombs, sellall, autosell, auto features, block even listening and handling. - - -* **Ran in to an issue with spigot versions < 1.13 where a data value outside of the normal range prevents XMaterial from mapping to a bukkit block.** -This change provides a better fallback which ignores the data value, which is the varient. The drawback of ignoring the varient type, which is outside the valid ranges anyway, is that it may not accurately reflect the intended block types. But at least this will prevent errors and being unable to map to any blocks. - - -* **Change to prison startup details reporting to elminate duplication.** -Near the end of the prison startup process, prison would run the `/prison version` command to provide additional information in the logs. This was duplicating some of the information that was already printed during the actual startup process. -Changes were made to only add the information that was missing so the whole command does not need to re reran. Overall this is a small impact, but a useful one. It does shift where these functions live and ran from. - - -* **ChatDisplay: An internal change that controls if a chat display object (multi-lined content, such as command output) displays the title.** -This will be useful when integrating in to other commands and workflows, such as redesigning how the startup reporting is handled. - - -* **v3.3.0-alpha.9g 2022-03-29** - - -* **auto features: Enable player toggle on sellall for auto feature's autosell.** - - -* **sellall reload - fixed issue where the reload was not chaning any online valus or settings.** - - -* **Mine bombs cooldown - ran in to a null value in the cooldown timers. Handles this situation now. ** - - -* **Sellall - added debug logging on the calculation of sell prices.** - - -* **Sellall bug fix on calculation boolean config values; it was not returning the correct value.** -This was found by a report that `/sellall hand` was not working. - - -* **Auto features bug fix: was paying the player, instead of just reporting the value when in debug mode.** - - -* **Update debug info in auto features to properly show it's within the BLOCKEVENTS priority processing.** - - -* **Topn calculations: handle a null being returned for the prestige ladder.** - - -* **Enabled a sellall feature to enable the old functionality where sellall ignores the Display Name or is not a valid prison block type.** - - -* **Fixed an NPE issue with checking to see if a block exists within a mine.** -This issue was impacting spigot versions less than 1.13. The problem is with data values being abnormal and out of the standard range. - - -* **Fixed a NPE on the topn calculations.** - - -* **auto features autosell when inventory is full when using the priority BLOCKEVENTS.** - - -* **topn fix: If next rank is null, then try to use the next prestige rank for the cost.** - - -* **v3.3.0-alpha.9f 2022-03-25** - - -* **Placeholders top player: added new placeholders based upon the _nnn_ pattern to identify the player.** - - -* **Top-n players listing: added an alternative line.** - - -* **Placeholder Bar Attributes: Now supports a non-positional keyword "reverse" which will take any bar graph and reverse it.** - - -* **AutoFeatures debugging: Some color change in the logging details for failures so they are easier to see.** - - -* **Prepare for the handling of STATSPLAYERS placeholders, which will be the ones that provides the placeholders for the top-n players.** -This handles the workflow on handling the placeholders. - - -* **Slight update on how the top-n players are printed... simplifies and also cleans it up the formatting.** - - -* **Updated the rankup accuracy to be greater than or equal to 1.0.** -And conditionally only report the accuracy_out_of_range if >= 1.0. - - -* **When validating the success of a rankup transaction's abiliity for the rankup cost to be applied, the validation is now checking to see if it's within a plus/minus of 1.0 from the target final balance of the player.** -This covers the inability of floats and doubles not being able to accurately repesent base 10 numbers all of the time, which the accuracy may be off by a small value such as 0.000001, but that will prevent an equality check from passing. -By checking that it's within a range of plus/minus one will help prevent false failures. - - -* **Fixed issue where ranking does not which rank is associated with each rank.** -Now the ranks will properly track the players at their ranks. - - -* **3.3.0-alpha.9e 2022-03-14** - - -* **Top-n: More work to enable. Now supports /ranks topn, with alias /topn.** -The rank-score and penalty is not yet enabled. Placeholders will be enabled after the command is fully functional. - - -* **Prison startup performance fix: On large servers with many players, the process of getting the player's balance from the economy plugin can cause significant delays if that plugin is not able to handle the load...** -so the validation of the players and the sorting of the top-n list is now ran in an async thread so it will not cause lag or delays on startup. - - -* **Prison version: including more information on ranks and add the ladder rank listing to the prison version command.** - - -* **Removed some old code from block event processing...** - - -* **Mine bombs getting a replacement blocks from the player's location.** - - -* **CustomItems drops: If custom items do not produce a drop, then default to dropping the block itself.** - - -* **Sellall: prevent selling with custom name items.** - - -* **PlayerCache earningsPerMinute: Sychronize to prevent an issue with concurrent mods.** - - -* **Mine bombs: Fix an issue with the generated mine bomb tool not being enchanted with the specified fortune, which also was effecting the durability and dig_speed too.** - - -* **Reworked how some of the registered event listeners are setup, which is needed for expanding to supporting other plugin's enchanments.** - - -* **Update the bstats configs for v3.0.0.** -Although it compiled without the bstats-base, it failed to run. I suspect my local cache for gradle was incorrectly providing objects when it shouldn't have. - - -* **Upgrade bstats to v3.0.0, was at v2.2.1.** -Hoping this will better report the proper usage. -Added more custom details on the graphs: player count, defaultRankCount, prestigesRankCount, otherRankCounts. -Set api version to v3.3. - - -* **BugFix: Prevent a possible NPE when blocks are null when calculating gravity effected blocks, and ensuring there is a location when trying to place blocks.** -Both of these should never be an issue, but based upon different conditions, they can become an issue. - - -* **Added an autoFeatures to enable/disable the use of CustomItems' getDrops().** - - -* **CustomItems integration: Adding support for getDrops() from CUI.** -This integrates custom blocks in to getting the SpigotBlock (an internal prison block). -It's not yet functional due to issues within CUI, but this is the initial setup. - - -* **Report that bedrock users are not getting their tokens.** -When in debug mode, if their balance is not correctly updated it will report it in the console. - - -* **v3.3.0-alpha.9d 2022-03-10** - - -* **Within the SpigotBlock, now has hooks to load CustomItems blocks when trying to convert an org.bukkit.Block to a SpigotBlock.** - - -* **For unbreakable blocks, reinforce that the location, which is the key, will not be null.** -The block sometimes can be null, so by having the seperate location will not cause a failure if the block is null. - - -* **Fixed an issue when checking if a block is unbreakable... it should not have been null, so this is a temp fix to prevent an error.** - - -* **CustomItems custom blocks: Hook up the new drops for CustomItems plugin.** - - -* **Update some of the gradle settings and fix the new custom items api.** - - -* **Upgrade XSeries from v8.5.0.1 to v8.6.2.** - - -* **Update CustomItems API from v4.1.3 to v4.1.15.** -This update adds support for prison to get the drops from the CustomItem blocks. - - -* **Changed the development environment and updated the java 1.8 to the latest release.** - - -* **v3.3.0-alpha.9c 2022-03-06** - - -* **Enable the ability to split messages in to multiple lines by using the placeholder `{br}`.** - - -* **Small adjustments to the MineReset handing of the targetBlock collections.** -Prevent their instantiation in the constructor since they are being lazy loaded. Also synchronizing on the adding of target block, since there was one report on an issue with that not being synchronized. - - -* **Added more validation checks and reporting on rankups and demotes.** -So if something goes wrong, it can hopefully identified and tracked. -If rank change failed, or if a refund failed, it will now better report these conditions. - - -* **Setup a return of success, or failure, on custom currency functions.** -GemsEconomy does not indicate if it was successful, but added code to check to see if it was successfully manually/indirectly. - - -* **Sync set blocks fixes. Isolate the targetBlocks and add a null check to ensure thre are no problems.** - - -* **RankLadder: removed obsolete code that was never used.** - - -* **Some initial setup for a rankScore.** -This is not hooked up yet, but the the core basics are there and should work soon. - - -* **Bug fix: Fixed an issue were a block would be added, or changed, and it would change all similar blocks in all mines to have the same percentage.** -This issue was intermittent and was caused by directly getting the block from the master list, without cloning it. The correction to this issue was to use a search function that would clone the block, but it also would compensate for custom blocks if the block's namespace was not initially provided. - - -* **Bug fix: Risk of a null on the blockHit, so add checks to ensure it's not before trying to process.** - - -* **Bug fix: The clickable delete code is that is generated is off by 1 on the inserted row.** -The row number needed to be reduced by one since the row number was incremented right before this final injection. - - -* **v3.3.0-alpha.9b 2022-02-28** - - -* **Fixed the command '/ranks ladder command remove' when specifying a row value that was too large.** -The message was only providing one value when it should have had two, and the first parameter was '%d' instead of '%1'. - - -* **PlayerCache: Unloading Players... when a player is being unloaded, and they are not in the cache, the unloading process is now able to indicate that the player should not be loaded.** -Also when trying to load a player, it will not attempt the load if the file does not exist. - - -* **Sellall bug fix... was using the wrapper to map it to an XMaterial which was causing NPEs.** -Using the prison's compatibility functions to perform the mapping, which will now provide a safer mapping that will not cause NPEs. - - -* **Module prison-sellall cleaned up gradle config to remove a few configs that are not needed.** - - -* **Fixed a bug with the blockEvent block filter for adding blocks, it was using the blockEvents collection instead of the prison blocks collection.** - - -* **Fix placeholder for prison_player_tool_lore to provide the actual tool's lore.** -The placeholder was not hooked up. - - -* **Mine manager when enabling mines after the delayed loading from multiverse-core delayed loading...** -put a slight delay on each submission of the startup air counts for each mine... spacing them out by one tick so they are not all trying to run at the same time. - - -* **v3.3.0-alpha.9 2022-02-27** - - -* **Bug fix: Sellall error: Resolve an issue with the off-hand not being removed when selling.** -Turned out that you can read all inventory slots, which includes the off-and slot, but when removing ItemStacks, the remove(ItemStack) function then ignores the off-hand slot. Has to directly remove from the off-hand slot. - - -* **Mine bombs: fixed issue with lore not being added.** -Was adding the wrong source; was adding the destination to the destination. - - -* **Mine Bombs: Add some basic validations when loading the mine bombs from the config files** - - -* **Mine Bombs: add a reload function for mine bombs.** -/prison reload bombs or /prison utils bomb reload - - -* **Removed warnings from the Vault economy wrapper since NPCs can actually initiate commands and NPC will always return nulls for OfflinePlayers....** therefore just return a value of zero. - - -* **New command added to '/prison support runCmd' to allow an OP process, such as a NPC in Citizens, to run a command as a player.** -For example this is handy for having an NPC open the player's GUIs such as mines or ranks. - - -* **v3.3.0-alpha.8h 2022-02-26** - - -* **Bug fix: Synchronized some of the collections that are needing it within the PlayerCache.** - - -* **Bug fix: Fixed an inventory glitch that was preventing items from being added to the inventory.** -Basically the inventory had items, but it was not updating the contents of the inventory on the client side. This was fixed by updating inventory when finished processing the adds. -If autosell on full inventory is enabled, and there are extra drops, then sell them all before they make it to the inventory. This works most of the time, but sometimes the inventory still fills up. This is now more of a characteristic than a bug. - - -* **3.3.0-alpha.8g 2022-02-25** - - -* **More adjustments to the block events so the config setting can be shown in the header of the /prison support listeners blockevent command.** - - -* **Setting up support for the BLOCKEVENTS on all block break event listeners.** -Changed around how the listeners are created to simplify and be more accurate in the event states. - - -* **Extracted the BlockBreakPriority enum to be an object on its own.** -Added BLOCKEVENT and added information on what the various priorities should do. This is in preparation to refactoring how events are processed. - - -* **Prison tokens: externalize the messages related to the admin tokens commands.** - - -* **For the admin commands for tokens, added an option to be able to suppress the messages.** - - -* **v3.3.0-alpha.8f 2022-02-23** - - -* **The creation of a new sellall module which will eventually contain the code to manage multiple shops that will be based upon ranks.** - - -* **Adjustments to the configuration of the mutex to better ensure that only one job is submitted for the reset, and to ensure other tasks are not locked up, or locked out.** -There was a report that the prior way was causing the mines to lockup. - - -* **v3.3.0-alpha.8e 2022-02-20** - - -* **Mine reset mutex is conditionally enabled to ensure the locks remain balanced.** -To ensure the mutex is enabled ASAP, its engaged outside of the normal location... it may only be a few nano-seconds savings, but with OP pickaxes mining with many players within one mine, the mutex must be enabled rapidly. - - -* **Bug Fix: Mine reset changes: Eliminate paged resets, some code that is not being use anymore, disabled the RESET_ASYNC type to be similar to RESET_SYNC since they are now the same, locked out checkZeroBlockResets so mines cannot reset multiple times at the same time using the MineStateMutex.** -The major issue here was that mines were being reset in the middle of a reset action. Used a preexisting MineStateMutex to secure the checkZeroBlockResets() function to prevent it from kicking off many resets. These multiple resets were happening because many players were triggering the resets... as a side effect, there were many situations of collections failing due to concurrent modification exceptions. - - -* **Getting the collection size was an issue by the time it was done processing the blocks, so getting them first may help prevent errors.** - - -* **Made many changes to the default configurations of the autoFeatures.** -This is to try to make it easier to use prison by using more of the settings that are most useful. -Added more comments to make it easier to understand these settings too.f - - -* **Release v3.3.0-alpha.8d 2022-02-20** - - -- **Fixed issues with vault economy and withdrawing from a player's balance.** -It now also reports any errors that may be returned. - - -* **To prevent NPEs, isBlockAMatch has been changed to use the MineTargetPrisonBlock as a parameter and then internally, checking for nulls, it will extract the status data block.** -This was causing errors when processes were trying to access target blocks before they had a chance to initialize. - - -* **Address a rare condition where the mineTargetPrisonBlocks is being "accessed" before the system is done initializing the mine.** -This creates an empty collection, but it will prevent errors in the long run. - - -* **Add equals and hashCode to the MineTargetBlockKey so it can be better used in structures like HashMaps.** - - -* **Mine bombs: Added a {countdown} placeholder for use with the MineBomb's tagName field.** -A few other adjustments such as adding more "color" to the default bomb tagNames. - - -* **Added validation check to make sure the player's balance was decreased, or increased, successfully before actually applying the rank change.** -If the balance does not reflect the change, then the rank change will be prevented. - - -* **Slight adjustment to addBalance so as to help reduce out of synch possibilities.** -The access to economy hooks, has been moved in to the sychronized block. - - -* **v3.3.0-alpha.8c 2022-02-16** - - -* **Fixed a start up issue with multiverse-core in that it now runs the air-count processes so the mines can have their targetBlocks defined.** -Many issues were resulting from failure to get the target blocks. Not sure how it was working before, other than targetBlocks were not being used as much as they are now. - - -* **Fixed a potential error if targetBlocks are not loaded yet, or loaded at all for a given mine.** -Was causing NPEs.... - - -* **Added logging for when a delayed world comes online and list all mines that are activated.** - - -* **v3.3.0-alpha.8b** - - -* **Clean up the way the command tasks were being called.** -Added mine name to the blockEvent logging. - - -* **Fixed a reversal of some calculations when converting nano seconds to milliseconds.** - - -* **New feature: debug count down timer.** -Able to now set a debug count down timer where debugging is turned off after logging that number of entries. - - -* **Potential bug fix in better managing if sellall should be enabled by directly checking the configuration parameter that enables it.** -Better logging of sellall when inventory is full. - - -* **Commit some SellAllUtil comments that are useful for debugging timing issues.** -These are now disabled, but can be manually reenabled when needed. - - -* **Some changes to Sellall to provide more flexibility and to fix some potential bugs** -The isEnabled now uses the proper boolean settings to indicate if the sellall utility is enabled or not. Before it was trying to treat strings as boolean. - - -* **Add prison command descriptions that goes along with the placeholders.** -They are not yet hooked up, but they will provide more information to the admins on what the placeholders will provide, and also how they can use them since some of these will include examples of the formats. - - -* **Bug fix: The cancellation of the event was not being returned in the correct locations**, -so it was bypassing all of the before mine reset commands. The before mine commands will now run correctly. - - -* **Prison commands: reorganize some of the structures used for the prison commands.** -Hook up some of the logging to track run times for each command. - - -* **Prison commands: reorganize some of the structures used for the prison commands.** -Hook up some of the logging to track run times for each command. - - -* **Prevent the autosell happening just because someone is op.** -To make this work, and to prevent odd behaviors where OPs suddenly are not able to mine correctly, OP can no longer use the autosell based upon perms. - - -* **Setup the time durations on reporting of mine resets to use external settings.** -Enables the use of singular and plural unit names. - - -* **Rework how rankup commands are ran: in progress.** -This new way of dealing with rankup commands is to collect all commands that need to be ran, from all rankups, then run them in one group when the player is done being ranked up. -For most changes in rank, this will have zero effect on anything (mostly), but it has a huge impact with the **rankupmax** command. -When hooked up (which is is not), this will take all commands and run them in a sync task. So "every" command will run in a sync task. But each command will be monitored for run time, and if the runtime for one command exceeds a threshold, then the sync task will resubmit itself to run again after on tick. This will slow down the process of running all of the commands, but it will help prevent them from causing lag. -With tracking run times on each command, if prison is in debug-mode, then it will generate console logs identify how long it take to run each command. So if any given command is causing lag, then it would be possible to identify what the offending command is. - - -* **Fixed a problem before releasing... was not using the correct variable so the generated File object was not getting used.** - - -* **Bug fix: If a player cache file does not exist, it now prevents it from loading.** - - -* **Fixed an issue with the GUI, such that if the player does not have a rank on the ladder**, -that it will now force the creation of a PlayerRank object so it does not cause a NPE. - - -* **Mine bombs: Enable the use of color codes on the armor stands when setting off the bombs...** - - -* **Mine bombs: Added durability and digspeed enchantments to the mine bomb data.** -This will allow for greater flexibility in how the tool in hand behaves. - - -* **If using a mine bomb, then do not allow durability calculations to be used**, -since if the pseudo tool breaks, then what ever the player is holding will be removed, which is usually an item stack of mine bombs. - - -* **Mine Bombs: The mine bomb give command now is case insensitive.** - - -* **Mine Bombs: Add ability to set the Y offset.** -It defaults to a value of -1. This allows fine tuning of bombs to better position them to sink deeper in the mine to increase the number of blocks that are included. - - -* **Fix issue with mine bombs not dropping blocks.** -The underlying block changed and therefore so did the behavior of the equals() function. - - -* **Added various token functions to the prison spigot API class.** - - -***3.3.0-alpha.8 2022-02-12** - - -* **Enable debug mode from within the config.yml file.** -It was not hooked up before. This is useful for initial logging of the mine air-counts. - - -* **Redesigned the initial mine air-counts which not only identifies which blocks are within a mine upon startup, but it also establishes the number of air blocks in a mine to help ensure it's able to properly reset when the mine is empty.** - - -* **Bug fix: cleaned up the way PlayerCache files are managed.** -Eliminated a lot of old code and simplifed the logic to ensure the liklihood of preventing corruption of the player caches. There has been some reports that the files were not being properly tracked and stats were being replaced with new entries. This also fixes some performance issues by caching the files in the directories. So once loaded, the loaders no longer need to read the file listings, which could take a while with a lot of files. - - -* **Provide information on locale settings within the `/prison version` command.** -Falls back to the en_US properties file if the selected language file does not exist. -If the non en_US properties files are found to be missing a property, then the english property is used as a fallback. These fallbacks are not written back to the save files. - - -* **v3.3.0-alpha.7 2022-02-09** -Set this back on an alpha release schedule. The betas appear to have been pretty stable. - - -* **Disable the player's nms attempts to get their locale... spigot 1.17 and higher no longer can get that value.** -Just use the server's default value. - - -* **For the /prison support commands, the output is now sent to the player instead of just the console.** - - -* **Some minor changes to /prison debug to give it an alias of /prison support debug.** -Format a few of the messages to make it easier to understand. - - -* **Removed the backpack's object from the player's cache.** - Backpacks are too massive for the player's cache and needs thier own cache system. - - -* **On the command /ranks set tag, added the note that if a tag is removed from a rank, then the rank name will be used instead.** -Fixed the placeholder for rank tags so if it is null, it no longer show a null, but now it show the rank's name. - - -* **Fixed the generation of the player mined block count placeholders.** -Was missing one _ after generating the specific block related placeholder. - - -* **Upgrade gradle from v7.3 to v7.3.1 to v7.3.2 to v7.3.3** -This is at the latest release. - - -* **Upgrade gradle from v7.2 to v7.3** - - Changes to provide better security when runnign gradle to prevent injection attacks. - - -* **Upgrade gradle from v7.1 to v7.1.1 to v7.2.** - - -* **Upgrade gradle from v7.0.2 to v7.1.** -NOTE: There are a number of updates to apply for gradle. Will commit on the minor versions and final version. - - -* **Added a few new placeholders and a new placeholder type of PLAYERBLOCKS.** -Added raws to the player_block_total per mine. Added player_blocks_total and its raw counts, which is a PLAYERBLOCKS. - - -* **Added a few new placeholders and a new placeholder type of PLAYERBLOCKS.** -Added raws to the player_block_total per mine. Added player_blocks_total and its raw counts, which is a PLAYERBLOCKS. - - -* **Changed around the logging of messages related to the use of autofeatures autosell.** -Added permissions to enable autosell on a per block. - - -* **Update CustomItems api from v3.7.17 to v4.1.3.** -This newer version of the API still does not have a getDrops() function. - - -* **Add more support for CustomItems plugin.** -It appears like this is working really well with auto pickup. It should be noted that the CustomItems' API does not have a getDrops() so it's impossible to get the correctly configured drops for the block, so for now, it will only return the block itself and not any configured drops. -Sellall may need to be fixed and there could be some other areas that needs some fine tuning, but so far all is working well. - - -* **For CustomBlockIntegrations added getDrops().** -This has to be used instead of bukkit's getDrops() since that will return only the base item drops, which are the wrong items. -For CustomItems plugin, there currently isn't a getDrops() function in the CustomItems API so instead, the integration's getDrops() returns the block. - - -* **If cancelAllBlockEventBlockDrops is enabled when it's not valid on the server version, then it will print the error to console, then turn off this features** - - -* **CustomItems: Hook up on server startup the ability to check for custom blocks when scanning the mines to set the air counts and block counts.** - - -* **Clean up the formatting on `/mines block list` so it's easier to read and looks better.** - - -* **If fail on /mines reset, then needed a missing return so the mine reset success message won't follow the error message.** - - -* **Bug Fix: When mine reset time is disabled, set to -1, and then all mines are reset with '/mines reset `*all*` details' it would terminate the reset chain on that mine.** -This change allows the next mine to be reset by not trying to set this mine's next action... which is none because reset time is -1. - - -* **v3.3.0-beta.2 2022-02-03** - - -* **Added an error message when failed to add a prestige multiplier.** - - -* **New feature: cached adding of earnings for the default currency.** -This was causing a significant amount of lag/slow down when performing autosell, or spamming of sellall. The lag was in the economy plugin not being able to accept additions of money fast enough. -Now this simple cache, will wait 3 seconds before adding the player's earnings to the economy plugin. When it does, it will do so in an async thread so as to not impact any performance in bukkit's main thread. Also prison's getBalance() functions, which includes the use of all prison placeholders, will include the cached amount, which means the player's balances appear as if they are not being cached. -Still need to cache the custom currencies. - - -* **Update /ranks autoConfigure to set notifications to a radius of 25 blocks, and enabled skip resets at a limit of 90% with 24 skips.** -Also moved DARK_PRISMARINE down a few levels since it's not as valuable as the other blocks. - - -* **Bug fix: Correct the comparison of a prison ItemStack by using compareTo.** -The old code was using enums, so the check for equality of enums resulted in comparing pointers, which will never work. -Updated a few other parts of the code to use the compareTo function instead of the equals function since that may not work correctly all the time. - - -* **For command /mines set notification added *all* for mine name so all mines can be changed at the same time.** - - -* **Change notification alerts from runnign every 5 minutes to every hour.** -Got a few complaints within the last fewa days that the notifications are too frequent. - - -* **Modified SpigotPlayer to add getRankPlayer() and modified RankPlayer to add getRankLadder, with short cuts for default and prestige so you don't have to always refer to their names (reduce errors).** -This is to remove the "mess" from other functions that need to get these player objects, of which sometimes they are not going about it the correct way. - - -* **sellall multiplier add - Now reports if a multiplier cannot be added. Also now adds the multiplier based upon the actual rank name**, -of which it was what the user entered with the command, which may not match the actual rank name. - - -* **RankLadders - Added a boolean function to check if the ladder is the default ladder or prestiges ladder.** - - -* **sellall multiplier - Now able to list all multipliers.** -It lists them in a 5 column listing. - - -* **Add debug logging when calling the external events.** -Will have to revisit this when hooked up to multi-block events, otherwise it could overwhelm the logging. - - -* **Ladder rank cost multiplier has 100 percent limits removed.** -Value can be any positive or negative number now. - - -* **Update some documentation related to CMI Economy.** - - -* **Broadcast the prison welcome message to all online players when prison is loaded with no mines or ranks defined.** -The messag is loggd to console 8 sconds after prison loads. The broadcast messags are sent 16 seconds after logging the welcome message. -The intention is to help bring awareness to new mods/admins that there is an easy way to get started with prison. - - -* **Broadcast the failed ranks loading to all online players.** -Its important that they know ranks failed to load. - - -* **Release v3.3.0-beta.1 !! Hooray!!** 2022-01-29 2:11 PM EST - - -* **Added nano-second timing autosell to confirm if there is a performance issue.** -My initial testings are showing that sellall has significant chance of performance problems in that selling items takes way too long. Will address in the future. - - -* **Disable all ranks related commands within the GUI menus.** -GUI was bypassing safeguards that were in place when the ranks module failed to load. - - -* **Update the placeholderAPI docs to correct the formatting of the docs to match what they should be.** -Had to indent by two spaces. - - -* **Created updated documents for the placeholderAPI wiki.** -These are local copies of the content since the prior content was removed/vandelized. - - - -* **New Feature: Added support for Quests so that block breakage within mines can now be tracked and be applied towards quests.** - - -* **Bug fix: Lapis_ore appently does not drop lapis_laluzi when using the bukkit's getDrops() function, it instead drops blue_dye, then when it gets to the player's inventory, it is then converted to lapis_lazuli.** -Therefore, auto sell cannot sell lapis_ore drops unles blue_dye is within the shop. I added blue_dye with the same value of lapis_lazuli to the sellall shop. This allows it to be sold now through auto pickup and auto sell. - - - -* **Bug Fix: Damage was being applied all the time.** -Found a field being initialized with a value of 1 when it should have been 0. - - -* **Prevent sellall from loading if ranks does not load. Sellall uses too many rank functions to stand alone.** - - -* **Bug Fix: The new Ranks error message handler which intercepts all ranks messags was failing to load properly when prison startup was not set for a delayed startup,** - which was because the ranks gui command (/ranks) was always being set even when ranks module failed to load. Now /ranks gui loads only if ranks was successful in being started. - - -* **Initially setup to use the actionBar for the messages, but that is not working correctly with such high volume of messages.** -So disabled them for now, but will switch them over shortly... - - -* **Format the earnings amount properly, so it will have a consistant format.** -Once in a while, instead of showing a value like 165.00 it shows 165.000000000000001. This is caused by the fact that doubles are binary, not base-10 so it canot always show the correct values. - - -* **Deprecated the MessagesConfig class since it is not implemented correctly.** -The messages should have been handled through Prison's multi-language tool, of which this does not use. - - -* **Try to use a different way to identify the item stack, especially if the bukkit item stack does not exist.** -This was a random error when using gravel, sand, and dirt on spigot/paper 1.12.2. - - -* **Clean up some of the refrences to the new/old block models.** - - -* **Added the new command: '/sellall list' that will list all blocks and their prices.** - - -* **Added comments that usage of auto features cancel drops will not work from spigot v1.8 through 1.12.x.** -Should work with v1.13.x and newer. - - -* **Fix some block issues, mostly getting the correct block bukkit block and limit it to only one location and function that ultimately provides these hooks.** -This release appears to be more functional, but it still should not be used since it's not fully tested. - - -* **First pass at removing the old block model. Do not use this release!!** -This compiles and runs on the server. Most commands appear to work, including mine resets, but no visual confirmation has been performed in game yet. Since so much has been changed and it has not yet been tested in-game, this release should not be used until such rudementary testing can be performed. +
+# Older change logs: +## 3.3.0-alpha.7 2022-01-22* * **3.3.0-alpha.7 2022-01-22** diff --git a/docs/changelog_v3.3.xb.md b/docs/changelog_v3.3.xb.md new file mode 100644 index 000000000..3bad87b22 --- /dev/null +++ b/docs/changelog_v3.3.xb.md @@ -0,0 +1,2272 @@ + +# Note: This is part 2 to the current change log: + +## Prison Change Logs for v3.3.x + +** Current change log:** +- **[v3.3.0-alpha - Current](changelog_v3.3.x.md)** + + + +
+ + +## Current change log - Part 2: + + +### 3.3.0-alpha.17 2024-04-20 and older: + + + + +# 3.3.0-alpha.17 2024-04-20 + +**v3.3.0-alpha.17** 2024-04-20 + + + +* **Mines messages: Secondary placeholders. Added support for mines' messages to be able to support secondary placeholders within the language files. NOTE: Not usable at this time.** +But... this is basically useless. Within the mines language files, the vast majority of all messages are related to admin messages and are not viewable by the players. +Therefore the admin-only messages will not support the secondary placeholders since the players will never see them. +At this time, there are no messages that supports the use of these secondary placeholders, although the feature has been enabled for mines. +If a need is required, then please reach out and request such features should be enabled. At this time, effort and work will not be performed blindly upon items that will never be used, so if you see a need for this, I'd be happy to add them since you would have a need. + + + +* **Placeholder bug: The placeholder 'prison_rankup_cost_percent' uses the calculated value of a percentage, but when used with the placeholder attribute, it was found to use the price instead.** As such, the actual value returned for the placeholder was incorrect. + + +* **Player Manager: Secondary Placeholders: Setup the secondary placeholder support on the PlayerManager, but it has not been enabled yet** since secondary placeholders on placeholders do not make a lot of sense because each placeholder is only one value and they cannot contain alternative text. At least not yet. + + +* **Localizable: Secondary placeholders: Rewrote the whole support of secondary placeholders related to players.*** +Expanded the support by making them generic so other data sources can also have their own custom set of placeholders too. Such as mines. +This now supports a new interface that will provide the generic support. +Player's commands have been modified to pass a RankPlayer object, which supports the new interface. Non-player commands have not been converted since players will never see those messages (such as admin commands). + + +* **Added a comment in the ranks message files indicating that there is now some support for player based placeholders to farther customize messages.** +This also fixes an issue with the broadcast messages to use the intended player instead of the target player who is being sent the message. + + + +* **Localization: If admin adds extra parameters, or other parsing failures, happens on a message, the error will now be trapped and logged to the console without formatting.** + + + +* **Economy: For economies that prison supports that has a method to check if the player has an account, prison now tries to check if there is an account for the player before trying to use the economy.** +This could potentially prevent issues or run time failures. + + +* **Prison API: Added a few new functions to work with ItemStacks.** + + + +* **Players: Shift the function of getting a player object to the Player classes, such as CommandSender.** +This is to simplify the code and to put the functionality in one location. + + + +* **Sellall: New command: '/sellall items inspect'** +This new command will inspect what the player is holding, and dump the details so the admin can see exactly how an item/block is created, including lore and enchantments. +Eventually this information can be used to enhance the ability to sell and buy non-standard items by allowing the admins to filter on lore, enchantments, and/or NBTs. + + + +* **SpigotPlayer: Fixed a potential issue if trying to use getRankPlayer() if the ranks module is not enabled.** +Added a check to ensure it's active. +We have not seen any reports of issues related to this. + + + +* **Prison Player: Added a new sendMessage function using Lists of Strings. ** +Added a new function getPlatformPlayer() which gets a bukkit player object if the player is online. This will consolidate a lot of other duplicate code. + + +* **Mine Bombs: wrapped up the changes to enable the placement of a mine bomb when using the BlockPlaceEvent which is used when using a block for the bomb's item.** + + +* **Prison ItemStack: remove enchantments from the core ItemStack since prison cannot properly represent it in versions lower than 1.13.x**, plus it was wrong for all spigot versions greater than 1.12.x. +Added the proper enchantment functions to the SpigotItemStack object. + + +* **Initial setup of sellall lore filtering** +A little clean up. + + +**3.3.0-alpha.16c 2024-03-11** + + +* **PlaceholderAPI: Upgrade from v2.11.2 to v2.11.5** + + +* **XSeries: Upgrade from v9.8.0 to v9.9.0** + + +* **Mine bombs: add support for BlockPlacementEvent so if someone is using a Block they can use it as the mine bomb's item.** + + +* **Prison's NBT: Add support for using NBTs with bukkit's Block.** + + +* **Add support for getting the "hand" from the BlockPlaceEvent.** + + +* **Prison support listeners: added support for listening to and providing dumps for PlayerDropItemEvent, PlayerPickupItemEvent, and BlockPlaceEvent.** + + +* **Promote & Demote: Improved upon reporting issues with the command.** +There were few situations where the command would exit without reporting why, which was leading to difficulties with using the command effectively. + + +* **New feature: TopN customization now possible. The messages and placeholders that you can use are located in the core multi-language files.** +See the bottom of the files for instructions on usage. +TopN data is set to delay load so it does not lengthen the startup process. As such, it now reports that the data is being loaded so it is now clear why there are no entries in the list initially. + + +* **Mines: eliminate a field no longer used: includeInLayerCalculations.** +This was obsoleted with better use of logic. + + +* **Mine resets: Reworked how prison is selecting random blocks per layer, to properly include constraints.** +The addition of various new features in the past made a mess of the logic, so it's been cleaned up greatly so it now makes sense and should work properly now. +There is a slight risk, that as blocks are removed from a layer due to reaching it's max constraint value, that future random selections were missing blocks selections and was then inserting AIR. This fixed code now will insert a filler block which has been selected with no constraints, and the largest chance value. + + +* **mines block layerStats: rewrote to improve and get rid of the collection manipulations.** +Found potential problem with air being inserted in to mines. +Renamed a lot of uses of Location objects to include the name "location" in their variable names instead of "block". + + +* **Mines block layer: Added colors for same IDs so it's easier to read.** Added a check that sees what block actually exists. If counts of what should have spawned match whats in the mine for that layer, then it shows only one number. It shows two numbers if a block's intended spawn does not match what's in the mine. + + +* **Mine reset: added a force to the reset so it will ignore an existing mine reset and allow a new one to begin.*** +When a mine is being reset, there is no way to actually cancel it. So this allows a large mine to undergo multiple concurrent resets. Use at your own risk. + + + +* **Bug fix: the check for the time the reset has been going on was incorrect and was fixed.** +Also all the code for submitting the reset task was moved in to the mutext. Now, if the reset got hung up, this will properly terminate it and resubmit it. + + +* **File format: Eliminate the check for file types since there is only one.** +Currently there isn't a setting to specify what it should be. + + +* **Mines block layerStats: Added a new command that shows which blocks are in each layer in the mine.** +There are a lot of future enhancements that can be added to this command, such as checking the actual blocks to see if they are still there, or if there was a problem with the spawning of the blocks. + + +* **Block lists: Added the total chance percentage to be displayed with the blocks.** + + +* **File output technique: Changes to how the "replace" existing files works.** +If the file does not exist, then it opens it to create it, otherwise it truncates it. + + +* **Mine bombs: Ability to prevent a bomb's blocks from count towards the player's block totals.** + + +* **Sellall and autosell: Refinements were made to the handling of the sellall settings to better stabilize the use of the commands.** Setting status for the players were moved to the player objects and is now used in all of the related calculations so there is better stability and consistency. + + +* **Mines import: prevent the processing of an importing of a mine if there are problems with the mine's name, or locations.** + + +* **AutoSell: Bug fix: When autosell and sell on inventory is full was all turned off, it would still sell.** +This fixes some of the logic to simplify the code, and to fix those issues. + + +* **Mine skip reset messaging: Did not have it hooked up in the correct location, so the skip messages were not happening.** + + +* **Mine reset: Under heavy load when performing a mine import, there were seen occasionally errors with concurrent modification errors.** +Code was changed to minimize that possibility. + + +* **Sellall and GUI message failures: a number of messages that would indicate the player does not have access to that command were changed to remove the permission from the message.** +This was requested by a couple of admins because they did not want the players to see the internal workings that would otherwise control how the software would behave. + + + +* **Mine imports: Fix some minor issues to get this to work even better.** + + +* **Mine skip reset: If a mine is reset, send a message to players, but only if the message is defined and not empty: 'skip_reset_message='** + + + +* **Player sellall Multipliers: Fixed the ranks multiplier to include all ranks that are defined within the sellall multipliers.** +Added a new function that will gather and list all multipliers that go in to the calculation of the player's total multipliers, which includes the rank multipliers (the sellall multipliers) and also permission based multipliers. +This detailed list of the individual multipliers, is viewable for each player that is online with the command `/ranks player ` and reveals the actual details of how it's calculated. + + + +**3.3.0-alpha.16b 2024-02-24** + + +* **Import Mines: Added the ability to import mines from JetPrisonMines config files.** +`/mines import jetprisonmines help` + + +* **Prison Command Handler: using config.yml you can now change all of prison's root commands with 'prisonCommandHandler.command-roots'.** +Can now map 'prison', 'mines', 'ranks', 'gui', 'sellall' to all new command that you want. + + +* **File saving: alternative technique for saving files. Do not use!** +This is a more dangerous technique that could possibly result in lost configurations. This is being provided as a degraded service if the fail-safe technique is not working ideally on a degraded server. +This should never be used, unless directed by a prison support admin. + + + +* **Prison startup bug: There was an issue with the prison startup when there was an error and prison tried to log the error**, only to find that resources that were needed for logging were not yet loaded nor were their dependencies. This fixes some of the entanglements to allow the error messages to be properly logged. + + +* **Bug fix: GUI configuration: Found a problem that when configuring the gui initial settings, that there were problems when trying to access mines and ranks when they don't yet exist.** + + +* **Add prison debug option to filter on blockConstraints when regenerating the blocks within the mines.** + + +* **Bug fix: prison support submit: if the bukkit system cannot extract a file from the jar**, such as plugin.yml, this will prevent the failure of the command. This will allow the command to continue being processed, but may just skip the extraction. + + + +* **Placeholders: Top player rank was using the wrong ladder, which was incorrectly the prestiges rank and not the default rank.** +Correcting the rank fixed the problem. This only was an issue if the player did not have a prestige rank. + + + +* **Mines set resetTime: fix typo in the description where it shows '*all' instead of '*all*'.** + + +* **ranks ladder: applyRanksCostMultiplier command was changed to allow the value of 'true' to be used along with the value of 'apply'.** This helps to eliminate some confusion on how the command works. + + +* **Bug fix: Prison command handler. When players are de-op'd, and they do the commands such as `/ranks help` or `/mines help` it was incorrectly showing other sub commands they did not have access to.** +This now shows the correct sub commands that they have access to. + + +* **Placeholders: topn players - bug fix. If a player did not have a prestige rank, then it would cause a NPE when using the `prison_top_player_rank_prestiges_nnn_tp` placeholder.** +Just check to ensure its not null... if it is, then return an empty string. + + +* **Bug fix: Player manager startup: fixed a problem where all players were being updated** even though they did not have a name change. Only when name changes are detected are the files updated or when a new player is found. + + +* **Add debug statements to identify how each block was calculated during a mine reset.** + + +* **Bug fix: block constraints: fix an issue with the selection of lower limits.** + + +* **updated the help on the `/mines block constraint` to indicate that the layer count is originating from the top, not the bottom.** + + +* **alpha.16a - 2023-12-28** + NOTE: I just noticed that alpha.16a was never committed. So this is not the correct location of when it was set with the local builds. + + +* **Mines: Fixes an issue for when mines are disabled and they are being checked in other processes to see if they are active.** +If the instance of PrisonMines is null, then it will create a temp instance just to prevent an NPE. + + +* **Mines unit tests: Setup a new constructor for mines that is only to be used with unit tests which allows the mines to be created,** but it does not initialize them since such tasks and processes are not needed in the unit tests. +As a side effect, these two unit test run much faster since it's not trying to setup tasks. + + +* **Prison Block change: Add support for display name, which is optional.** +Setup sellall so it can use the display name now, so renamed items will not be mistaken for vanilla minecraft items. +More work needs to be done to hook up displayName to other features, such as sellall and add prison block to mines. + + +* **Bug fix: Fixed the command `/mines set accessPermission` where it was apply the given perm to all mines.** + Likewise, all mines parameter was failing to do anything. + + +* **NOTE: This alpha version "should" support spigot 20.0.4.** +After a few days, if no other issues surface pertaining to 20.0.4, or other related plugins, this will be released as a public release. + + +* **Fix issue with BlockEvent's SellAll when isAutoSellIfInventoryIsFullForBLOCKEVENTSPriority feature is enabled.** +This was not using the correct new functions that checks to see if a player can use autsell, or if they have it temporarily toggled off. This also checks to see if the player has the correct perms, if perms are enabled for the sellall event. + + +* **Breaking change in XSeries: GRASS has been changed to SHORT_GRASS for v20.0.4!** It's disappointing to say the least that after all of these damn years, XSeries screwed up and pushed a breaking change to their repo. They should have kept GRASS so they would have remained compatible will all past code and configs that had to refer to GRASS directly, but nope... they opted for causing problems. Very disappointing. +Setup a converter to automatically convert all GRASS to SHORT_GRASS as the mines are loaded. + + + +* **Upgrade XSeries from v9.7.0 to v9.8.0.** +* **Upgrade nbt-api from v2.12.0 to v2.12.2.** + + +* **config.yml - changed the default values for remapping aliases and restricting players from using commands.** +The default, which used `/mines tp` was actually causing conflict with normal usage. + + +* **AutoFeatures auto permissions: enable the ability to 'disable' the perms.** Any op'd player, if perms are enabled, will have these auto features enabled. There is no other way around this, since this is the correct behavior of OP'd players. + + +* **Mine resets: If a mine reset takes longer than 4 minutes, then that is probably a failure and the mine reset did not complete.** Therefore, reset the mine reset mutex and try again. This allows a "crashed" mine reset to auto fix itself if it can. The 4 minute wait time is LONG, but it will prevent a normal reset from being canceled and restarted in the middle of a restart. + + +* **Performance: Changed the defaults for the mine reset settings to help improve the performance on larger servers.** +The older settings would allow other commands to backup and it would appear as if there was lag happening, TPS would rarely drop below 20. This helps to keep performance a little more responsive. +The side effect is that there will need to be more "chunks" submitted which could possibly result in longer wall-time for mine resets. + + +* **Mine resets: If a suggested block is null, then set it to air. This was causing an NPE under some conditions.** + + +* **BlockEvents: Added the ability to update block events** +instead of deleting them and re-adding them. Follow directions when using '/mines blockevent update help', or whenever a block event listing is shown in game, you can now click on the commands to auto populate the block event update command... then just edit the needed changes and submit. + + +* **Upgrade XSeries to v9.7.0 from v9.4.0.** + + +* **Bug Fix: Mine resets and block constraints.** +This fixes a few issues with block constrains using min and max, along with exclude from top and bottom too. + + +* **Bug Fix: GUI ranks, mines, and prestiges were not using the default item name correctly.** It was using the template correctly, but was not translating the use of placeholders. Only name and tag are supported. +Mines: `{mineName}` and `{mineTag}` +Ranks and prestiges: `{rankName}` and `{rankTag}` + + +* **Mines: Added support for '*all*' for mine names for the following mine commands: resetDelay, resetThreshhold, notificationPerm, and accessPermission** + + +* **Localizable: Bug fix. Blanks were being removed by the use of trim() so the spaces were being ignored.** + + +**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.** + + + +* **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** + + + +See [Prison Change log v3.2.3-alpha.15](prison_changelog_v3.3.0-alpha.15.md) + + + +**Prison v3.3.0-alpha.14 2023-01-23** + + +See [Prison Change log v3.2.3-alpha.14](prison_changelog_v3.3.0-alpha.14.md) + + + +--------------------------- + + + +**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. + + +* Added a new tool: `mines tp list` which will show a player all of the mines they have access to. They can also click on a listed mine to generate the TP command. This command can also be ran from the console to inspect what players have access to. +* Fixed a recently introduced bug where if the server starts up, but someone has no ranks, it was not able to properly assign them their first default rank. It was leading to circular references. +* Fixed an issue with color codes not being translated correctly with placeholderAPI. +* Prison has a rank cost multiplier where ranks on different ladders can increase, or decrease, the cost of all ranks the player buys. So when they prestige, it makes ranks A-Z cost more each time. What's new is that now you can control which ladders these rank cost multipliers are applied to, such as not on prestiges, but only on default. +* Fixed calculations of the placeholder `prison_rank__player_cost_rankname`. It was not fully working with every possible rank on every possible ladder. Now it works correctly if trying to get the player's cost for even many prestige ranks out (it includes cals for all A-Z mines at multiple passes). +* Mine bombs: Changed to only allow mine bombs to be setoff withn mines the player has access to. Fixed an issue with color codes within the mine bomb's tags. +* Fixes issues with NBT, color codes with prison broadcast commands. +* Rewrote topN for better performance: `/topn`. Older players are archived within topN and can be queried: `/topn archive`. +* Update ladder details on a few commands. +* Update XSeries from v8.8.0 to v9.0.0 so prison now supports 1.19.x blocks. +* Bug fixes with first join events. Bug fix with a few guis. +* CMI update: If CMI is detected at startup, and delayed startup is not enabled, prison will go in a simple delayed startup mode to allow CMI a chance to enable it's economy through vault. This reduces the learning curve with CMI users. +* New feature: Prison will now make an auto backup of all files in it's directory when it detects a change in version. Can manually backup too. The backup stores temp files then removes them from the server, this helps keep the server clean. +* Update bstats: Gained control of the account and started to add useful custom reports to help zero in on what we need to help support. +* More work on block converts. Will be added in the next alpha releases. +* Bug fixes: mines gui fixes for virtual mines. Sellall bug fixes. Placeholders fixes. + + + + +* **Minor addition to bstats.** + + +* **Player Mine GUI had the wrong calculation for volume which also threw off blocks remaining and percent remaining.** +The calculation for volume was using the surface area and not the total number of blocks. + + +**v3.3.0-alpha.12L 2022-08-25** + + +* **Updates to the bstats....** + + +* **New placeholders: `prison_rank__linked_mine_tag_rankname` and alias `prison_r_lmt_rankname`.** +Similar to `prison_rank__linked_mine_rankname` but uses the mine's tag instead of the mine's name. + + +* **Mine TP list: use mine tags and clickable mines to teleport to them.** + + +* **Mines TP list. Added a new options to mines tp command to list all mines that the player actually has access to.** +Not finished with it... will add clickable links to them when in game. + + +* **There was an unused updated tool in prison. It's against my policy to auto update this plugin, which would need to be consented to anyway, but I feel that admins need to be in full control of updates and know what is included in the updates. There was identified a potential exploit called zip-slip-vulnerability that could hijack a server if malicious zip is extracted. Prison never used this tool, so it's been fully disabled with no intention of reenabling. It may be deleted in the near future.** + + +* **TopN bug fix: If a player was in an archived state, they were not being moved to active when they would login.** + + +* **If the player is holding the mine bomb in their off hand, then remove the inventory from their off hand.** + + +* **v3.3.0-alpha.12k** + + +* **Fixed an issue when starting the server an no ranks exist. Also fixes an issue when starting the server an a player has no rank.** +Was using a mix of really old code, and the latest code, which caused a conflict since neither was doing what it was really supposed to. + + +* **Added the custom bstats report for Prison Vault Plugins.** +This reports all plugins that have been integrated through Vault. This report does not impact any other plugins report. This is segmented by integration type. + + +* **Fixed bug when server starts up when no player ranks exist.** +It will now bypass the player validation until ranks have been configured. + + +* **v3.3.0-alpha.12j 2022-08-21** + + +* **Update bstats to remove old custom reports that are not wanted/needed anymore.** +Added 6 new placeholder reports that classifies placeholders ini various categories related to how they are used within prison. Any placeholder that appears in these lists, will not be included in the generic 4-category placeholder lists. +Added a few more simple pie charts to cover a lot of the details on ranks, ladders, and players. Simple is better so you can just glance at all of them, without having to drill down on each one. + + +* **v3.3.0-alpha.12i 2022-09-19** + + +* **TopN players - fixed an issue where topN was being processed before the offline players were validated and fixed.** +There was an issue with processing an invalid player that did not have a default rank. + + +* **v3.3.0-alpha.12h 2022-08-19** + + +* **Rankup costs: Minor clean up of existing code. Using the calculateTargetPlayerRank function within the RankPlayer object.** + + +* **PAPI Placeholders: Force color code translations on all resulting placeholders.** +There were a few issues where placeholder color codes were not being properly translated. This was not consistent with everyone. Not sure why it was working for most. +These changes are more in line with how chat handlers and MVdW placeholders works. + + +* **Ladder: apply rank cost multiplier to a ladder or not.** +This new feature enables you to disable all rank cost multipliers for a specific ladder. Normally that rank cost multiplier applies to all ladders, but now you can suppress it. It's for the whole ladder, and not on a per rank basis. + + +* **Fixed an issue with calculating the player's rank cost when they already on the presetiges ladder and calculating the higher prestige ranks.** +Appears as if this becomes an issue when at the last rank on the default ladder. + + +* **v3.3.0-alpha12g 2022-08-14** + + +* **Fxing of the calculations of the placeholder prison_rank__player_cost_rankname and related placeholders.** +The original implementation did not take in to consideration the prestige ranks in relation to the default rank. +The improvements in this calculation now generates a list of all ranks between the current rank and the target rank. So if a few prestige ranks out from the player's current prestige rank will result in calculating every rank in between including multiple passes through all default ranks. So if there are 26 default ranks, and the player is at rank A with no prestiges, then to calculate rank P4 would include the following ranks: +b --> z + p1 + a --> z + p2 + a --> z + p3 + a --> z + p4. +This results in a total of 107 ranks that must be collected, then the player's cost for each rank will have to be calculated. Then all of these must be added together to get the player's cost on rank P4. +This calculation has to be performed for each rank in it's entirety +Warning: this calculation on high prestige ranks will be a performance issue. If this becomes a problem on any particular server, then the only recommendation that can be provided is not to use any of the prison_rank__player_cost placeholders. + + +* **TopN : a few more adjustments to fix a few issues with duplicates and also with using values from within the topN to include in the report to help minimize the need to recalculate everything especially with archived entries.** + + +* **Mine bombs: Fixed an issue with the mine bomb names not always working with color codes.** +Honestly the wrong function was being used so how it even worked I don't know. lol + + +* **New topN functionality: far better performance, with regular updates.** +TopN now is a singleton and is self contained. When the singleton is instantiated, it then loads and setup the prisonTopN.json file on the first run. 30 seconds after the initial load, it then hits all players to load their balances in an async thread. +The command /ranks topn, or just /topn has new parameter: "archived". Any player who has not been online for more than 90 days will be marked as archived. The archived option will show just the archived players. +Setup new parameters within config.yml to control the topn behavior with the async task. + + +* **v3.3.0-alpha.12f 2022-08-08 ** (forgot to commit when made this version) + + +* **Mine Bombs: Only allow bombs to be placed when within a mine that the player has access to.** +This will help prevent wasted bombs. + + +* **Fixed an issue with nbt items not having a value for toString().** + + +* **Encode color codes for the prison utils broadcast command.** + + +* **Added an "invalid player name" message to the rankup commands.** +Also added missing messages to the zh_TW.properties file. + + +* **BlockEvents were changed to auto display the existing rows so it's easier for the end user to know which row to select.** +All they need to do is to enter the mine's name, then press enter to submit the command, and then the existing rows details will be shown. Then the user can select the row and complete the command. +Updated docs on block events. + + +* **BlockEvents were changed to auto display the existing rows so it's easier for the end user to know which row to select.** +All they need to do is to enter the mine's name, then press enter to submit the command, and then the existing rows details will be shown. Then the user can select the row and complete the command. + + +* **minor updates for disabled mine reset times. No functional changes were made.** + + +* **Fixed a potential NPE with giving the players overflow blocks, but not sure what the exact cause was, but looked like there was an issue with mapping to a spigot item stack.** + + + **CMI delayed startup: Added new feature to try to auto enable Prison's delayed startup if CMI is detected as an active plugin, and if the delayed startup is disabled within the config.yml.** +This is to help get more CMI users up and running without more effort, but yet still provide the ability to customize how it is triggered. +If CMI is active, there is NO WAY to disable a delayed startup check.* + +* **Added the the option for playerName to the `/rankup` command so the command can be scripted and ran from the console.** + + +* **There was another issue with using `/gui` related to no ladders being loaded.** +This fixes that problem, and it appears like the issue was caused by plugman messing things up. This does not "solve" the problem with ladders not being loaded, but prevents the NPE from happening. + + +* **There was an issue with `/prison reload gui` causing a NPE.** + + +* **Fixed the `/ranks topn` command (`/topn`) to sort the list of players before printing the list.** +The list was being set a server startup time, and if someone would rankup or prestige, it was not reflecting their new position. The list is also now sorted after each rankup. Sorting should be a low cost operation since the list used never is regenerated so the changes made during sorting is minimal at best. + + +* **Added the ability to control the prefix spaces on the unit names.** +NOTE: may need to enable the use of the `core_text__time_units_short` since the long units are not being used. May need to create another placeholder for short/long. It used to be short, so may need to use long with the new placeholder and convert the calcs to the short as the default. +This was requested by PassBL. + + +* **v3.3.0-alpha.12e** + + +* **Fixed issue rank null issues when showing ladder details.** + + +* **Prison backups: Fixed an issue with folders not existing when running the backups the first time.** + + +* **v3.3.0-alpha.12d 2022-07-25** + + +* **Added more information on ladder listing to show name, number of ranks, and rank cost multiplier.** + + +* **bStats update: Added a new bstats custom chart for auto features.** + + +* **Update some docs. Added docs for Prison Backups** +[Prison Backup Document](prison_docs_050_Prison_backups.md) + + +* **Upgrade XSeries from v8.8.0 to v9.0.0** + + +* **Fixed issue with prison version check triggering a backup upon startup.** +It was always bypassing the previous version check, so it was always creating another backup. + + +* **Update bstats by moving to its own class in its own package.** +Added 4 new custom charts to split the plugins in to 4 parts. + + +* **Fixed a few issues with the ranks gui where they were using the wrong message key (placeholder).** + + +* **Prison v3.3.0-alpha.12c** + + + +* **Prison bstats: setup 4 new bstats charts for prison. May change a few charts or add new ones in the near future.** +Got control over the prison bstats so can now add custom stats. + + +* **Prison backups: Created a Prison/backups/versions.log file which gets logs when a new prison version is detected on startup, which also performs a backup.** +All backups are also logged in the versions.log file too. + + +* **v3.3.0-alpha.12b** +- Added the fix for the placeholders. See next note. + + +* **Fixed an issue with placeholders not be properly evaluated; there were 3 sections and they were combined in to one so it would not bypass any.** + + +* **Possible bug fix with first join: it appears like it was inconsistant with running the rank commands. Fixed by rewriting how the first join event is handled.** + + + +* **Prison backups: Added new features where it is generating a stats file in the root of the zip file which contains all of the "prison support submit" items.** +This is just about ready, but lacking support for auto backups when prison versions change, or job submission to run auto backups at regular intervals. + + +* **Setup a prison backup command that will backup all files within the prison plugin folder.** +When finished, it will delete all temp files since they have been included in the backup. +The new command is `/prison support backup help`. + + +* **v3.3.0-alpha.12a** + + +* **Added a new set of intelligent placeholders: these show the tags for the default ladder and prestige ladder, for the "next" rank but are linked together.** +They only apply to the default ladder and the prestige ladders. The tags are only shown if the player has that rank, or if that will become their next rank. +These ONLY show the tags that will be appropriate when the next rank up. So if the can still rankup on the default ladder, then only the default rank shows the next ranks tag. If they are at the end of the default rank, then it will show the next rank on the prestiges ladder; if they do not have a rank there currently, then it will show the next prestige rank with the default rank showing the first rank on that ladder. + + +* **When the command handler starts up, it now logs the pluigin's root command and the command prefix which is used if there are duplicate commands found during bukkit command registration.** + + +* **Bug fix: Placeholders search was missing the assignment of the placeholderKey, which is what would like the search results on the raw placeholders, with the actual data that is tied back to the player.** +In otherwords, without the PlaceholderKey it was not possible to extract the player's data to be displayed within the command: /prison placeholders search. + + +* **Added constants for the default and prestiges ladder name so it does not have to be duplicated all over the place, which can lead to bugs with typos.** + + +* **Sellall bug fix: There wasn't a common point of refernce to check if sellall is enabled. Many locations were directly checking config.yml, but the new setting has been moved to the modules.yml file. ** +If config.yml has sellall enabled in there, it will be used as a secondary setting if the sellall setting in modules.yml is not defined or set to false. Eventually the config.yml setting will be removed. + + +* **Found that bStats was erroring out with the servers hitting the rate limit so this makes a few adjustments to try to get prison to work with bstats.** +Basically plugins that load last will be unable to report their stats since every single plugin that is using bstats submits on it's own, and therefore it quickly reaches the limits. + + +* **BlockConverters: More changes to block converters.** +Added defaults for auto blocking, and for auto features with support for *all* blocks. + + +* **Bug fix: mines gui was not able to handle virtual mines with the internal placeholders. +This bug fix was included with the deployment of alpha.12 to spigotmc.org. + + + +* **Pull Request from release.branch.v3.3.0-alpha.12 to Master - 2022-06-25** + + +This represents about six months of a lot of work with many bug fixes, performance improvements, and new features that have been introduced. The last two alphas were not pulled back to main, but they were released, This PR will preserve the released alpha as it has been published. + +Also, this helps to ensure that this work will not be lost in the event the bleeding branch is lost/removed. Hopefully it won't be, but a lot of work has gone in to it and it will be impossible to recreate the current state of the alpha release. + +This version, v3.3.0-alpha.12, has 300 commits and 323 changed files. The list of actual changes since v3.2.11 is substantial and the change log should be referenced. + +Highlights of some of the changes include (a sparse list): + +* new block model - full support for CustomItems custom blocks - updated XSeries which mean prison supports Spigot 1.19. +* major improvements to auto features - streamlined and new code - higher performance - many bugs eliminated - now supports drop canceling to make prison more compatible with other plugins +* better multi-language support - supports UTF-8 +* Improved rankup - rankup commands are now ran in batch and will not lag the server if players spam it +* rewrite of the async mine resets - next to impossible for mine resets to cause lag - Uses a new intelligence design that will throttle placing blocks as the server load increases, which makes it next to impossible for it to cause lag. +* Enhanced debugging tools - if a server owner is having issues, prison has more useful tools and logging to better identify where the issues are - new areas are not able to log details when in debug mode - debug mode now has a "count down timer" where if debug mode is 8enabled like /prison debug 10 then it will only allow 10 debug messages to print, then it will turn off debug mode automatically. This is very useful on very heavy servers when a lot of players are active... it prevents massive flooding of the console. +* Major rewrite of the placeholder code that identifies which placeholder raw text is tied to, so it can then retrieve and process the data. - Pre-cache that provides mapping to raw text, so once it is mapped, it can prevent the expensive costs of finding the correct placeholder - Added the beginning of tracking stats (through the pre-cache0 and will be adding an actual placeholder cache in the near future. +* Mine Bombs - fixes and enhancements +* Starting to create a new sellall module that will support multiple shops and custom blocks (not just XMaterial names) +* Block Converters - Will allow full customization on all block specific things within auto features - will eliminate all hard coded block +* Started to add NBT support. - Used in mine bombs - Starting to use in GUI's to simplify the complexity of hooking actions up with the menu items. +* Added rank scores and top-n players - Rank score is a fair way to score players within a rank. It's currently the percentage of money they have to rank up (0 to 100 percent), but once they cross the 100% threshold, then 10% of the excess subtracts from their rank score. This prevents camping at levels. +* There is more stuff, some major, a bunch of minor, and many bug fixes along the way. + + + + + +* **v3.3.0-alpha.12 2022-06-25** + + + +* **v3.3.0-alpha.11k 2022-06-20** +Plus luckperms doc update. + + +* **Mine resets: Fixed an issue when dealing with zero-block resets on a very small mine, such as a one block mine in that the 5 second delay was preventing from rapid resets.** +Bypass both 5 second cooldown on resets and blockmatching when 25 blocks or less for the mine size. +With running resets in async mode, with rapid resets for a one-block mine, the handling of the block breaks can occur out of order, which will trigger the block mismatch. + + +* **Fix issue: On the creation of a new mine, it would reset the mine a number of times. This fixes the problem by only allowing one reset every 5 seconds at the soonest.** + + + +* **Placeholder fix: The PAPI placeholder integrations should not be prefixing raw text with "prison_"; that is the task for PlaceholderIdentifier.** + + +* **minor items changed with the GUIs... no functional changes.** + + +* **Update a number of docs...** + + +* **Fixed an issue where if you try to use a % on a number it's causing String format errors.** +This now strips off % and $ if they are used. + + +* **Update Docs: LuckPerms groups and tracks... added images and fixes a few minor things too.** + + +* **Update some of the docs on setting up luckperms and tracks.** + + +* **v3.3.0-alpha.11j** + + +* **Since the chat event is handled within the spigot module, and since ranks and mines would just duplicate the processing since they both will hit the SpigotPlaceholder class, it made sense to handle the chat event directly within the spigot module.** + + +* **Updates to the prison placeholder handler. This fixes a bug with chat messages return a null value.** +These changes also allows the pre-cache to track invalid placeholders now, so it can fast-fail them so it does not have to waste CPU time trying to look up which placeholder key they are tied to. + + +* **v3.3.0-alpha.11i** +Getting ready to release alpha.12. + + +* **Placeholder stats: A new feature that is tracking usage counts with placeholders.** +This is not a placeholder cache that caches the results, but it caches the placeholder that is associated with text placeholder. The stats currently only tracks the total number of hits, and the average run time to calculate the placeholder. +The pre-cache will reduce some overhead costs. This also provides the framework to hooking up a formal placeholder cache. + + +* **Placeholders: changed the two top_player line placeholders that are the headings** + since they originally had _nnn_ pattern that is getting messed up in some settings. So removal of the nnn helped to getting it working. + + +* **GUI MInes: Update support for custom lore support within the gui configs.** + + +* **Update XSeries from v8.7.1 to v8.8.0 to better support the newest blocks.** + + +* **Updated item-nbt-api-plugin from v2.9.2 to v2.10.0.** + + +* **v3.3.0-alpha.11h 2022-06-14** + + +* **Prison Placeholders: General clean up of obsolete code.** +Since the new placeholder system is working well with the new class PlaceholderIdentifier, obsolete code that was commented out has been removed. +The obsolete class that used to be the key component to identifying placeholders was PlaceholderResults and is no longer used anywhere. It's core components were moved to PlaceholderIdentifier and therefore all references to this obsolete class has been eliminated. +At this time, PlaceholderResults has not been deleted, but will be at some future time. + + +* **Prison Placeholders: Major rewrite the handling of placeholders.** +Prison's placeholder handling was completely rewritten to better handle the matching of a placeholder text with the actual placeholder objects. Over the last few years, many new features were added to prison's placeholders, but the way they were implemented were through patching existing code. This rewrite starts from scratch on how placeholder are decoded. Placeholders are now only decoded once instead of being decoded when attempting to match each internal placeholder. The results are significant performance improvements and eliminates a lot of redundant code. Some new features were add, such as supporting more than one placeholder attribute at a time. Also it streamlines how parameters and data is passed from the outer most layers of prison to where the placeholders are calculated. + +Another major benefit of this rewrite, beside reduction of code complexity and performance improvements, is that it opens the door to being able to implement an internal placeholder cache. Some plugins request placeholder data once per tick, or 20 times per second. Multiply that by 50 online players, and you got prison performing the same calculation 1000 times per second. Caching could help reduce that to only one calculation per second (assuming a cache time to live value of 1 second. Caching will not always be so simple, or possible, or every placeholder. Player-based placeholders can't be cached like static mine placeholders (mine names and mine tags as an example). + + +* **Add support for Portuguese.** + + +* **BlockConverters: fix issue when block converters are not active.** + + +**v3.3.0-alpha.11g - 2022-06-11** + + +* **Disable the gui for autofeatures configs. They are so out of date, they were causing problems.** +Autofeatures should be manually edited. + + +* **Fix a problem when BlockConverters are disabled, and doing a reload on auto features, it's not able to find that config file so its throwing an exception.** + + +* **The build was failing intermittently on the continual integration (CI)** +pertaining to the item-nbt-api-plugin, so an entry to added to "lock it in" to the correct path within the mavenrepository.com repo. +This should prevent the resource from being paired with the wrong repo. + + +* **There is a situation when checking for new updates to the language files, that it needs to write the new file, but the old one has not been archived.** +This now checks to make sure the old one has been renamed, and if it hasn't, then it will rename it. + + +* **Added an entry for the sellall module in the modules.yml file.** +Code has been setup to check, with a default fall-back on to the sellall settings within config.yml file. The entry in config.yml has been commented out. +Either will work, but the setting within modules.yml will take priority. + + +* **Update XSeries to v8.7.1 from v8.6.2.** +Note that this does not add any of the newer 1.19 blocks or items. + + +* **GUI: Fixed some issues with the gui and admin perms. Added some admin perms to a few gui commands to lock them down.** +Found a serious issue with non-admins being able to edit rank costs and sellall item costs. The GUIs were not locked down and if the players knew the commands, they could edit the costs. + + +* **v3.3.0-alpha.11f 2022-06-06** + + +* **BlockConverters: minor changes.** + + +* **Bug fix: Backpacks were not working properly with just ".save()" but had to add ".setChanged()" too, otherwise minepacks will not actually save the status of the backpacks.** + + +* **BlockConverters: rename targets to outputs.** + + +* **BlockConversions: hooked up the code to not only filter and return the blockConversions for the player and the block, but to also return the item stacks from the results.** +This is just about ready to be used in the code. + + +* **Romanian Locale language files were placed in the wrong location.** +Oreoezi provide two new language files for the Romanian Locale, but they were placed in the wrong location. +They were added to "prison-core/out/production/resources/lang/core/" and ".../mines/". For them to actually +work correctly, without being deleted, need to be placed within the following path: +"prison-core/src/main/resources/lang/core/" and "prison-core/src/main/resources/lang/mines". +These should now be usable. Also the LocaleManager now has alternatives setup to default to en_US; future +alternative languages can be added in the future. + + +* **BlockConverters: add some validators to the BlockConverters.** +Reports various issues, fixes non-lowercase source block names, and also disables invalid settings. + + +* **BlockConverters: Adjusting around how they are setup, and how they are generated.** +BlockConverters are now in their own config file: blockConvertersConfig.json. +They are no longer being stacked/placed in the autoFeaturesConfig.yml file, so all the conversion code is no longer required. With it being json, it now can reflect the java classes without any special considerations on the conversion process. + + +* **BlockConverters: More work on these settings.** +Setting up to work with AutoFeaturesConfig.yml, but having second thoughts about adding these configs to that file since it will complicate the config details. + + +* **Fixed a bug on the smelting of coal_ore which was yielding 10 times too much, but this was never seen since a silk touch pickaxe would have to been used.** + + +* **Placeholder fix for `prison_mines_blocks_mined_minename` since it was not being incremented after the fixing of the autopickup=false and handle normal drops = true.** +Also found that the calculated field for the mine's total blocks mined was not being recalculated after load the mines from their save files. This now is working properly. + + +* **Major exploit fix: sellall was not indicating that the inventory was changed within the Minepacks backpacks,** +and therefore players were able to sellall of their inventory, logoff, and then when they log back on, it will be restored. +Now, all inventory changes are forcing a save for the backpacks. + + +* **Fixed an incorrect mapping to a message: auto features tool is worn out.** + + +* **v3.3.0-alpha.11e 2022-05-23** + + +* **Bug fix: Fixed an issue with sellall when the module sellall is not defined but sellall is enabled in the config.yml file.** + + +* **Bug fix: Minepacks has a new function in their API to force backpack changes to be saved.** +Before it could only be marked as changed, which was not enough to get it to save in all situations. Prison is now calling "save()" to ensure its behaving better now. +NOTE: releasing this fix with alpha.11d even though it has been added after being set to 11d. + + +* **Prison v3.3.0-alpha.11d 2022-05-22** + + +* **GUI messages: a few more updates and corrections** + + +* **GUI: More fixes to the gui messages... including moving all of the new gui specific messages out of prison-sellall module to the prison-core module so they will still be accessible if the prison-sellall module is disabled.** + + +* **GUI cleaned up by eliminating so many excessive uses of translating amp color codes to the native color codes.** +Found some locations where there were at least 7 layers of function calls, with each layer trying to translate the color codes, which of course was excessive. + + +* **Change the name of the SpigotSellallUtilMessages class to SpigotVariousGuiMessages due to the fact these messages are used in more than just sellall.** +It should be noted that eventually the non-sellall messages may have to be removed from the sellall module. + + +* **Spigot GUI Messages: Hook up more messages to prison's messaging system.** + + +* **Sellall messages: Start to setup the correct usage of the multi-language message handling through the new prison-sellall module.** +This fixes the messaging within the SellAllUtil class. + + +* **Move auto feature messages to the spigot message file so they can be customized.** +Removed the inventory full messages from the AutoFeaturesConifg.yml file. + + +* **The normalDrops processing was not hooked up to the newest way auto pickup is disabled, which was skipping normalDrops if auto pickup was disabled.** +The number of blocks in the normalDrops is now being passed back through the code so it can identify that it was successful and finalize the processing. + + +* **3.3.0-alpha.11c 2022-05-14** + + +* **GUI Menus enable NBT support.** +This is a major change. The details for the menus options and commands are now stored in NBT data so they do not have to rely on the item name, lore, or other tricks. +This is a first phase, and more work needs to be done to remove hooks with the item names for other menu options. Main set of changes has been done to the menu tools. + + +* **Changed placeholder attributes to print the raw value and placeholder.** +Changes to the logging to allow & to be encoded to the unicode string of +`U+0026` so it can bypass the color code conversions, then it is converted back +to an & before sending to bukkit. This works far better than trying to +use Java regEx quotes. + + +* **Fixed signs for sellall to enable them to work with any wood variant.** + + +* **3.3.0-alpha.11b 2022-05-02** + + +* **Placeholder fix for formatted time segments to use the values setup in the language files within core.** +This allows the placeholders to use the proper notations for singular and plural units of times as configured for each language. + + +* **Placeholder fix for rankup_cost and rankup_cost_remaining on both the formating of the percents and the bar.** +The percents were being displayed as an integer, so with rounding, they were very misleading since they would show 100% when they were really hitting 99.5% and higher. Also the bar is not working better, and if the percentage is less than 100%, then it will always show a RED segment at the end of the bar; it will ONLY show GREEN when it's 100% or higher. + + +* **Mine Bombs fix to allow color codes within the bomb's name.** +The color codes are removed for the sake of matching and selecting when giving to players so you don't have to use them in the commands. + + +* **Placeholder issues when not prefixed with "prison_" is being addressed by prefixing the identifier with "prison_" right away.** +This "is" addressed, but it's deep in the code and for some reason certain parts of the code is not making the connection to the correct placeholder without that prefix. So this really is not the desired way to address this, but it eliminates the problem. The reason why it's not the desired way, is because it's exposing buisness rules of how to handle the placeholders, outside of the placeholder core code. + + +* **Bug fix... with placeholder prison_rank__player_cost_remaining_rankname, and its variants,** + eliminate the calculation of including the current rank since that has already been paid for. Prior to this fix, it was only excluding prior ranks. + + +* **3.3.0-alpha.11a 2022-04-25** + + +* **Mine Bombs and NBT settings: this fixes mine bombs to work with NBT tags, which are being used to identify which items are actually mine bombs.** + + +* **Fixes the mine bomb usage of lore where the lore that is defined in the settings is no longer altered so it's now used verbatim.** +Also the check for mine bomb is removed from using the name, or first line of lore, and now tries to use NBT data. +But note, that the NBT data is not working correctly yet. + + +* **Fixed the usage of setting up the NBT library within the gradle config file.** +Fixed issue with unknown, or incompatible items were unable to be parsed by XMaterial which was resulting in failures. This fixes the problem by preventing the use of a partial created SpigotItemStack. + + +* **Hook up the NBT library to the SpigotItemStack class.** +This has not been tested yet to see how it works, especially between server resets. + + +* **Added NBT support to prison. This loads a NBT library to be used only with the spigot sub-project.** +This has not been hooked up to anything yet. + + +* **Placeholder fix: Problem with the placeholder getting a prestige rank that was one too high.** +The following placeholders were fixed: prison_rrt, prison_rankup_rank_tag, prison_rrt_laddername, prison_rankup_rank_tag_laddername + + +* **Hooked up the BlockConvertersNode to the yaml file IO code so it will save and load changes to the auto features configs for anything with the BlockConverters data type.** +Removed unused functions. + + +* **Mine reset potential bug fix: Some rare conditions was causing problems, so using another collection to pass the blocks, and getting the size prior to calling the function to prevent the problems from happening.** +This appeared to be happening when a mine was being reset multiple times, at the same time. The mine should never be resetting multiple times, at the same time. May need to add more controls to prevent it from happening. + + +* **Bug Fix: The IGNORE block type was not marked as a block, therefore could not be used within a mine.** + + +* **New feature: Block Converters. Setup the initial core settings for block converters within the auto features.** +The core internal structure is in place and so is the ability to write the data to the file system. +This has not been hooked up to anything yet. + + +* **Setup placeholder formatted time values to use the language config file.** +This set of values will "NOT" reload when the command `/prison reload locales` is ran. The server must be restarted to reload these values. + + +* **CustomItems getDrops() debug mode will list the results of the get drops.** +This will help track what's going on with the getDrops function since it's a complicated process. + + +* **Placeholders: prison_rankup_rank_tag (and the ladder variants) now shows the prestiges next rank when at the top rank in the default ladder.** +This only applies to the default ladder and only if the prestiges ladder is activated. + + +* **Pull out the setBlock and blockAt functions from the SpigotWorld class so that way it would properly track within Timings.** + + + +** v3.3.0-alpha.10 2022-04-02** + +** Release notes for the v3.3.0-alpha.10 release as posted to spigotmc.org and polymart.org: + +v3.3.0-alpha.10 + +This alpha.10 release includes many significant performance improvements and bug fixes. Although this is an alpha release, it is proving to be stable enough to use on a production server. Please make backups and test prior to using. This v3.3.0-alpha.10 release is "still" backwards compatible with v3.2.11 so you should be able to down-grade back to v3.2.11 without major issues. The breaking changes that will be in the final v3.3.0 release have not been applied yet to these alpha releases. + +Please see our discord server for the full listing of all bug fixes and improvements, there have been more than 70 updates since the alpha.9 release. The following is just a simple short list. + +- Many bug fixes. Some that even predates the v3.2.11 release. + +- Performance improvements: startup validations moved to an async thread. Slight delay between mine validations to allow other tasks to run (needed for less powerful servers). Improvements with sellall performance. + +- Added more support for Custom Items (custom blocks) + +- Added support for top-n players and added over 30 new placeholders. Top-n support for blocks mined and tokens earned will be added shortly too. + +- Upgraded internal libraries: bstats, XSeries, gradle, custom items, and a couple others. + +- Many fixes: Mine bombs, sellall, autosell, auto features, block even listening and handling. + + +* **Ran in to an issue with spigot versions < 1.13 where a data value outside of the normal range prevents XMaterial from mapping to a bukkit block.** +This change provides a better fallback which ignores the data value, which is the varient. The drawback of ignoring the varient type, which is outside the valid ranges anyway, is that it may not accurately reflect the intended block types. But at least this will prevent errors and being unable to map to any blocks. + + +* **Change to prison startup details reporting to elminate duplication.** +Near the end of the prison startup process, prison would run the `/prison version` command to provide additional information in the logs. This was duplicating some of the information that was already printed during the actual startup process. +Changes were made to only add the information that was missing so the whole command does not need to re reran. Overall this is a small impact, but a useful one. It does shift where these functions live and ran from. + + +* **ChatDisplay: An internal change that controls if a chat display object (multi-lined content, such as command output) displays the title.** +This will be useful when integrating in to other commands and workflows, such as redesigning how the startup reporting is handled. + + +* **v3.3.0-alpha.9g 2022-03-29** + + +* **auto features: Enable player toggle on sellall for auto feature's autosell.** + + +* **sellall reload - fixed issue where the reload was not chaning any online valus or settings.** + + +* **Mine bombs cooldown - ran in to a null value in the cooldown timers. Handles this situation now. ** + + +* **Sellall - added debug logging on the calculation of sell prices.** + + +* **Sellall bug fix on calculation boolean config values; it was not returning the correct value.** +This was found by a report that `/sellall hand` was not working. + + +* **Auto features bug fix: was paying the player, instead of just reporting the value when in debug mode.** + + +* **Update debug info in auto features to properly show it's within the BLOCKEVENTS priority processing.** + + +* **Topn calculations: handle a null being returned for the prestige ladder.** + + +* **Enabled a sellall feature to enable the old functionality where sellall ignores the Display Name or is not a valid prison block type.** + + +* **Fixed an NPE issue with checking to see if a block exists within a mine.** +This issue was impacting spigot versions less than 1.13. The problem is with data values being abnormal and out of the standard range. + + +* **Fixed a NPE on the topn calculations.** + + +* **auto features autosell when inventory is full when using the priority BLOCKEVENTS.** + + +* **topn fix: If next rank is null, then try to use the next prestige rank for the cost.** + + +* **v3.3.0-alpha.9f 2022-03-25** + + +* **Placeholders top player: added new placeholders based upon the _nnn_ pattern to identify the player.** + + +* **Top-n players listing: added an alternative line.** + + +* **Placeholder Bar Attributes: Now supports a non-positional keyword "reverse" which will take any bar graph and reverse it.** + + +* **AutoFeatures debugging: Some color change in the logging details for failures so they are easier to see.** + + +* **Prepare for the handling of STATSPLAYERS placeholders, which will be the ones that provides the placeholders for the top-n players.** +This handles the workflow on handling the placeholders. + + +* **Slight update on how the top-n players are printed... simplifies and also cleans it up the formatting.** + + +* **Updated the rankup accuracy to be greater than or equal to 1.0.** +And conditionally only report the accuracy_out_of_range if >= 1.0. + + +* **When validating the success of a rankup transaction's abiliity for the rankup cost to be applied, the validation is now checking to see if it's within a plus/minus of 1.0 from the target final balance of the player.** +This covers the inability of floats and doubles not being able to accurately repesent base 10 numbers all of the time, which the accuracy may be off by a small value such as 0.000001, but that will prevent an equality check from passing. +By checking that it's within a range of plus/minus one will help prevent false failures. + + +* **Fixed issue where ranking does not which rank is associated with each rank.** +Now the ranks will properly track the players at their ranks. + + +* **3.3.0-alpha.9e 2022-03-14** + + +* **Top-n: More work to enable. Now supports /ranks topn, with alias /topn.** +The rank-score and penalty is not yet enabled. Placeholders will be enabled after the command is fully functional. + + +* **Prison startup performance fix: On large servers with many players, the process of getting the player's balance from the economy plugin can cause significant delays if that plugin is not able to handle the load...** +so the validation of the players and the sorting of the top-n list is now ran in an async thread so it will not cause lag or delays on startup. + + +* **Prison version: including more information on ranks and add the ladder rank listing to the prison version command.** + + +* **Removed some old code from block event processing...** + + +* **Mine bombs getting a replacement blocks from the player's location.** + + +* **CustomItems drops: If custom items do not produce a drop, then default to dropping the block itself.** + + +* **Sellall: prevent selling with custom name items.** + + +* **PlayerCache earningsPerMinute: Sychronize to prevent an issue with concurrent mods.** + + +* **Mine bombs: Fix an issue with the generated mine bomb tool not being enchanted with the specified fortune, which also was effecting the durability and dig_speed too.** + + +* **Reworked how some of the registered event listeners are setup, which is needed for expanding to supporting other plugin's enchanments.** + + +* **Update the bstats configs for v3.0.0.** +Although it compiled without the bstats-base, it failed to run. I suspect my local cache for gradle was incorrectly providing objects when it shouldn't have. + + +* **Upgrade bstats to v3.0.0, was at v2.2.1.** +Hoping this will better report the proper usage. +Added more custom details on the graphs: player count, defaultRankCount, prestigesRankCount, otherRankCounts. +Set api version to v3.3. + + +* **BugFix: Prevent a possible NPE when blocks are null when calculating gravity effected blocks, and ensuring there is a location when trying to place blocks.** +Both of these should never be an issue, but based upon different conditions, they can become an issue. + + +* **Added an autoFeatures to enable/disable the use of CustomItems' getDrops().** + + +* **CustomItems integration: Adding support for getDrops() from CUI.** +This integrates custom blocks in to getting the SpigotBlock (an internal prison block). +It's not yet functional due to issues within CUI, but this is the initial setup. + + +* **Report that bedrock users are not getting their tokens.** +When in debug mode, if their balance is not correctly updated it will report it in the console. + + +* **v3.3.0-alpha.9d 2022-03-10** + + +* **Within the SpigotBlock, now has hooks to load CustomItems blocks when trying to convert an org.bukkit.Block to a SpigotBlock.** + + +* **For unbreakable blocks, reinforce that the location, which is the key, will not be null.** +The block sometimes can be null, so by having the seperate location will not cause a failure if the block is null. + + +* **Fixed an issue when checking if a block is unbreakable... it should not have been null, so this is a temp fix to prevent an error.** + + +* **CustomItems custom blocks: Hook up the new drops for CustomItems plugin.** + + +* **Update some of the gradle settings and fix the new custom items api.** + + +* **Upgrade XSeries from v8.5.0.1 to v8.6.2.** + + +* **Update CustomItems API from v4.1.3 to v4.1.15.** +This update adds support for prison to get the drops from the CustomItem blocks. + + +* **Changed the development environment and updated the java 1.8 to the latest release.** + + +* **v3.3.0-alpha.9c 2022-03-06** + + +* **Enable the ability to split messages in to multiple lines by using the placeholder `{br}`.** + + +* **Small adjustments to the MineReset handing of the targetBlock collections.** +Prevent their instantiation in the constructor since they are being lazy loaded. Also synchronizing on the adding of target block, since there was one report on an issue with that not being synchronized. + + +* **Added more validation checks and reporting on rankups and demotes.** +So if something goes wrong, it can hopefully identified and tracked. +If rank change failed, or if a refund failed, it will now better report these conditions. + + +* **Setup a return of success, or failure, on custom currency functions.** +GemsEconomy does not indicate if it was successful, but added code to check to see if it was successfully manually/indirectly. + + +* **Sync set blocks fixes. Isolate the targetBlocks and add a null check to ensure thre are no problems.** + + +* **RankLadder: removed obsolete code that was never used.** + + +* **Some initial setup for a rankScore.** +This is not hooked up yet, but the the core basics are there and should work soon. + + +* **Bug fix: Fixed an issue were a block would be added, or changed, and it would change all similar blocks in all mines to have the same percentage.** +This issue was intermittent and was caused by directly getting the block from the master list, without cloning it. The correction to this issue was to use a search function that would clone the block, but it also would compensate for custom blocks if the block's namespace was not initially provided. + + +* **Bug fix: Risk of a null on the blockHit, so add checks to ensure it's not before trying to process.** + + +* **Bug fix: The clickable delete code is that is generated is off by 1 on the inserted row.** +The row number needed to be reduced by one since the row number was incremented right before this final injection. + + +* **v3.3.0-alpha.9b 2022-02-28** + + +* **Fixed the command '/ranks ladder command remove' when specifying a row value that was too large.** +The message was only providing one value when it should have had two, and the first parameter was '%d' instead of '%1'. + + +* **PlayerCache: Unloading Players... when a player is being unloaded, and they are not in the cache, the unloading process is now able to indicate that the player should not be loaded.** +Also when trying to load a player, it will not attempt the load if the file does not exist. + + +* **Sellall bug fix... was using the wrapper to map it to an XMaterial which was causing NPEs.** +Using the prison's compatibility functions to perform the mapping, which will now provide a safer mapping that will not cause NPEs. + + +* **Module prison-sellall cleaned up gradle config to remove a few configs that are not needed.** + + +* **Fixed a bug with the blockEvent block filter for adding blocks, it was using the blockEvents collection instead of the prison blocks collection.** + + +* **Fix placeholder for prison_player_tool_lore to provide the actual tool's lore.** +The placeholder was not hooked up. + + +* **Mine manager when enabling mines after the delayed loading from multiverse-core delayed loading...** +put a slight delay on each submission of the startup air counts for each mine... spacing them out by one tick so they are not all trying to run at the same time. + + +* **v3.3.0-alpha.9 2022-02-27** + + +* **Bug fix: Sellall error: Resolve an issue with the off-hand not being removed when selling.** +Turned out that you can read all inventory slots, which includes the off-and slot, but when removing ItemStacks, the remove(ItemStack) function then ignores the off-hand slot. Has to directly remove from the off-hand slot. + + +* **Mine bombs: fixed issue with lore not being added.** +Was adding the wrong source; was adding the destination to the destination. + + +* **Mine Bombs: Add some basic validations when loading the mine bombs from the config files** + + +* **Mine Bombs: add a reload function for mine bombs.** +/prison reload bombs or /prison utils bomb reload + + +* **Removed warnings from the Vault economy wrapper since NPCs can actually initiate commands and NPC will always return nulls for OfflinePlayers....** therefore just return a value of zero. + + +* **New command added to '/prison support runCmd' to allow an OP process, such as a NPC in Citizens, to run a command as a player.** +For example this is handy for having an NPC open the player's GUIs such as mines or ranks. + + +* **v3.3.0-alpha.8h 2022-02-26** + + +* **Bug fix: Synchronized some of the collections that are needing it within the PlayerCache.** + + +* **Bug fix: Fixed an inventory glitch that was preventing items from being added to the inventory.** +Basically the inventory had items, but it was not updating the contents of the inventory on the client side. This was fixed by updating inventory when finished processing the adds. +If autosell on full inventory is enabled, and there are extra drops, then sell them all before they make it to the inventory. This works most of the time, but sometimes the inventory still fills up. This is now more of a characteristic than a bug. + + +* **3.3.0-alpha.8g 2022-02-25** + + +* **More adjustments to the block events so the config setting can be shown in the header of the /prison support listeners blockevent command.** + + +* **Setting up support for the BLOCKEVENTS on all block break event listeners.** +Changed around how the listeners are created to simplify and be more accurate in the event states. + + +* **Extracted the BlockBreakPriority enum to be an object on its own.** +Added BLOCKEVENT and added information on what the various priorities should do. This is in preparation to refactoring how events are processed. + + +* **Prison tokens: externalize the messages related to the admin tokens commands.** + + +* **For the admin commands for tokens, added an option to be able to suppress the messages.** + + +* **v3.3.0-alpha.8f 2022-02-23** + + +* **The creation of a new sellall module which will eventually contain the code to manage multiple shops that will be based upon ranks.** + + +* **Adjustments to the configuration of the mutex to better ensure that only one job is submitted for the reset, and to ensure other tasks are not locked up, or locked out.** +There was a report that the prior way was causing the mines to lockup. + + +* **v3.3.0-alpha.8e 2022-02-20** + + +* **Mine reset mutex is conditionally enabled to ensure the locks remain balanced.** +To ensure the mutex is enabled ASAP, its engaged outside of the normal location... it may only be a few nano-seconds savings, but with OP pickaxes mining with many players within one mine, the mutex must be enabled rapidly. + + +* **Bug Fix: Mine reset changes: Eliminate paged resets, some code that is not being use anymore, disabled the RESET_ASYNC type to be similar to RESET_SYNC since they are now the same, locked out checkZeroBlockResets so mines cannot reset multiple times at the same time using the MineStateMutex.** +The major issue here was that mines were being reset in the middle of a reset action. Used a preexisting MineStateMutex to secure the checkZeroBlockResets() function to prevent it from kicking off many resets. These multiple resets were happening because many players were triggering the resets... as a side effect, there were many situations of collections failing due to concurrent modification exceptions. + + +* **Getting the collection size was an issue by the time it was done processing the blocks, so getting them first may help prevent errors.** + + +* **Made many changes to the default configurations of the autoFeatures.** +This is to try to make it easier to use prison by using more of the settings that are most useful. +Added more comments to make it easier to understand these settings too.f + + +* **Release v3.3.0-alpha.8d 2022-02-20** + + +- **Fixed issues with vault economy and withdrawing from a player's balance.** +It now also reports any errors that may be returned. + + +* **To prevent NPEs, isBlockAMatch has been changed to use the MineTargetPrisonBlock as a parameter and then internally, checking for nulls, it will extract the status data block.** +This was causing errors when processes were trying to access target blocks before they had a chance to initialize. + + +* **Address a rare condition where the mineTargetPrisonBlocks is being "accessed" before the system is done initializing the mine.** +This creates an empty collection, but it will prevent errors in the long run. + + +* **Add equals and hashCode to the MineTargetBlockKey so it can be better used in structures like HashMaps.** + + +* **Mine bombs: Added a {countdown} placeholder for use with the MineBomb's tagName field.** +A few other adjustments such as adding more "color" to the default bomb tagNames. + + +* **Added validation check to make sure the player's balance was decreased, or increased, successfully before actually applying the rank change.** +If the balance does not reflect the change, then the rank change will be prevented. + + +* **Slight adjustment to addBalance so as to help reduce out of synch possibilities.** +The access to economy hooks, has been moved in to the sychronized block. + + +* **v3.3.0-alpha.8c 2022-02-16** + + +* **Fixed a start up issue with multiverse-core in that it now runs the air-count processes so the mines can have their targetBlocks defined.** +Many issues were resulting from failure to get the target blocks. Not sure how it was working before, other than targetBlocks were not being used as much as they are now. + + +* **Fixed a potential error if targetBlocks are not loaded yet, or loaded at all for a given mine.** +Was causing NPEs.... + + +* **Added logging for when a delayed world comes online and list all mines that are activated.** + + +* **v3.3.0-alpha.8b** + + +* **Clean up the way the command tasks were being called.** +Added mine name to the blockEvent logging. + + +* **Fixed a reversal of some calculations when converting nano seconds to milliseconds.** + + +* **New feature: debug count down timer.** +Able to now set a debug count down timer where debugging is turned off after logging that number of entries. + + +* **Potential bug fix in better managing if sellall should be enabled by directly checking the configuration parameter that enables it.** +Better logging of sellall when inventory is full. + + +* **Commit some SellAllUtil comments that are useful for debugging timing issues.** +These are now disabled, but can be manually reenabled when needed. + + +* **Some changes to Sellall to provide more flexibility and to fix some potential bugs** +The isEnabled now uses the proper boolean settings to indicate if the sellall utility is enabled or not. Before it was trying to treat strings as boolean. + + +* **Add prison command descriptions that goes along with the placeholders.** +They are not yet hooked up, but they will provide more information to the admins on what the placeholders will provide, and also how they can use them since some of these will include examples of the formats. + + +* **Bug fix: The cancellation of the event was not being returned in the correct locations**, +so it was bypassing all of the before mine reset commands. The before mine commands will now run correctly. + + +* **Prison commands: reorganize some of the structures used for the prison commands.** +Hook up some of the logging to track run times for each command. + + +* **Prison commands: reorganize some of the structures used for the prison commands.** +Hook up some of the logging to track run times for each command. + + +* **Prevent the autosell happening just because someone is op.** +To make this work, and to prevent odd behaviors where OPs suddenly are not able to mine correctly, OP can no longer use the autosell based upon perms. + + +* **Setup the time durations on reporting of mine resets to use external settings.** +Enables the use of singular and plural unit names. + + +* **Rework how rankup commands are ran: in progress.** +This new way of dealing with rankup commands is to collect all commands that need to be ran, from all rankups, then run them in one group when the player is done being ranked up. +For most changes in rank, this will have zero effect on anything (mostly), but it has a huge impact with the **rankupmax** command. +When hooked up (which is is not), this will take all commands and run them in a sync task. So "every" command will run in a sync task. But each command will be monitored for run time, and if the runtime for one command exceeds a threshold, then the sync task will resubmit itself to run again after on tick. This will slow down the process of running all of the commands, but it will help prevent them from causing lag. +With tracking run times on each command, if prison is in debug-mode, then it will generate console logs identify how long it take to run each command. So if any given command is causing lag, then it would be possible to identify what the offending command is. + + +* **Fixed a problem before releasing... was not using the correct variable so the generated File object was not getting used.** + + +* **Bug fix: If a player cache file does not exist, it now prevents it from loading.** + + +* **Fixed an issue with the GUI, such that if the player does not have a rank on the ladder**, +that it will now force the creation of a PlayerRank object so it does not cause a NPE. + + +* **Mine bombs: Enable the use of color codes on the armor stands when setting off the bombs...** + + +* **Mine bombs: Added durability and digspeed enchantments to the mine bomb data.** +This will allow for greater flexibility in how the tool in hand behaves. + + +* **If using a mine bomb, then do not allow durability calculations to be used**, +since if the pseudo tool breaks, then what ever the player is holding will be removed, which is usually an item stack of mine bombs. + + +* **Mine Bombs: The mine bomb give command now is case insensitive.** + + +* **Mine Bombs: Add ability to set the Y offset.** +It defaults to a value of -1. This allows fine tuning of bombs to better position them to sink deeper in the mine to increase the number of blocks that are included. + + +* **Fix issue with mine bombs not dropping blocks.** +The underlying block changed and therefore so did the behavior of the equals() function. + + +* **Added various token functions to the prison spigot API class.** + + +***3.3.0-alpha.8 2022-02-12** + + +* **Enable debug mode from within the config.yml file.** +It was not hooked up before. This is useful for initial logging of the mine air-counts. + + +* **Redesigned the initial mine air-counts which not only identifies which blocks are within a mine upon startup, but it also establishes the number of air blocks in a mine to help ensure it's able to properly reset when the mine is empty.** + + +* **Bug fix: cleaned up the way PlayerCache files are managed.** +Eliminated a lot of old code and simplifed the logic to ensure the liklihood of preventing corruption of the player caches. There has been some reports that the files were not being properly tracked and stats were being replaced with new entries. This also fixes some performance issues by caching the files in the directories. So once loaded, the loaders no longer need to read the file listings, which could take a while with a lot of files. + + +* **Provide information on locale settings within the `/prison version` command.** +Falls back to the en_US properties file if the selected language file does not exist. +If the non en_US properties files are found to be missing a property, then the english property is used as a fallback. These fallbacks are not written back to the save files. + + +* **v3.3.0-alpha.7 2022-02-09** +Set this back on an alpha release schedule. The betas appear to have been pretty stable. + + +* **Disable the player's nms attempts to get their locale... spigot 1.17 and higher no longer can get that value.** +Just use the server's default value. + + +* **For the /prison support commands, the output is now sent to the player instead of just the console.** + + +* **Some minor changes to /prison debug to give it an alias of /prison support debug.** +Format a few of the messages to make it easier to understand. + + +* **Removed the backpack's object from the player's cache.** + Backpacks are too massive for the player's cache and needs thier own cache system. + + +* **On the command /ranks set tag, added the note that if a tag is removed from a rank, then the rank name will be used instead.** +Fixed the placeholder for rank tags so if it is null, it no longer show a null, but now it show the rank's name. + + +* **Fixed the generation of the player mined block count placeholders.** +Was missing one _ after generating the specific block related placeholder. + + +* **Upgrade gradle from v7.3 to v7.3.1 to v7.3.2 to v7.3.3** +This is at the latest release. + + +* **Upgrade gradle from v7.2 to v7.3** + - Changes to provide better security when runnign gradle to prevent injection attacks. + + +* **Upgrade gradle from v7.1 to v7.1.1 to v7.2.** + + +* **Upgrade gradle from v7.0.2 to v7.1.** +NOTE: There are a number of updates to apply for gradle. Will commit on the minor versions and final version. + + +* **Added a few new placeholders and a new placeholder type of PLAYERBLOCKS.** +Added raws to the player_block_total per mine. Added player_blocks_total and its raw counts, which is a PLAYERBLOCKS. + + +* **Added a few new placeholders and a new placeholder type of PLAYERBLOCKS.** +Added raws to the player_block_total per mine. Added player_blocks_total and its raw counts, which is a PLAYERBLOCKS. + + +* **Changed around the logging of messages related to the use of autofeatures autosell.** +Added permissions to enable autosell on a per block. + + +* **Update CustomItems api from v3.7.17 to v4.1.3.** +This newer version of the API still does not have a getDrops() function. + + +* **Add more support for CustomItems plugin.** +It appears like this is working really well with auto pickup. It should be noted that the CustomItems' API does not have a getDrops() so it's impossible to get the correctly configured drops for the block, so for now, it will only return the block itself and not any configured drops. +Sellall may need to be fixed and there could be some other areas that needs some fine tuning, but so far all is working well. + + +* **For CustomBlockIntegrations added getDrops().** +This has to be used instead of bukkit's getDrops() since that will return only the base item drops, which are the wrong items. +For CustomItems plugin, there currently isn't a getDrops() function in the CustomItems API so instead, the integration's getDrops() returns the block. + + +* **If cancelAllBlockEventBlockDrops is enabled when it's not valid on the server version, then it will print the error to console, then turn off this features** + + +* **CustomItems: Hook up on server startup the ability to check for custom blocks when scanning the mines to set the air counts and block counts.** + + +* **Clean up the formatting on `/mines block list` so it's easier to read and looks better.** + + +* **If fail on /mines reset, then needed a missing return so the mine reset success message won't follow the error message.** + + +* **Bug Fix: When mine reset time is disabled, set to -1, and then all mines are reset with '/mines reset `*all*` details' it would terminate the reset chain on that mine.** +This change allows the next mine to be reset by not trying to set this mine's next action... which is none because reset time is -1. + + +* **v3.3.0-beta.2 2022-02-03** + + +* **Added an error message when failed to add a prestige multiplier.** + + +* **New feature: cached adding of earnings for the default currency.** +This was causing a significant amount of lag/slow down when performing autosell, or spamming of sellall. The lag was in the economy plugin not being able to accept additions of money fast enough. +Now this simple cache, will wait 3 seconds before adding the player's earnings to the economy plugin. When it does, it will do so in an async thread so as to not impact any performance in bukkit's main thread. Also prison's getBalance() functions, which includes the use of all prison placeholders, will include the cached amount, which means the player's balances appear as if they are not being cached. +Still need to cache the custom currencies. + + +* **Update /ranks autoConfigure to set notifications to a radius of 25 blocks, and enabled skip resets at a limit of 90% with 24 skips.** +Also moved DARK_PRISMARINE down a few levels since it's not as valuable as the other blocks. + + +* **Bug fix: Correct the comparison of a prison ItemStack by using compareTo.** +The old code was using enums, so the check for equality of enums resulted in comparing pointers, which will never work. +Updated a few other parts of the code to use the compareTo function instead of the equals function since that may not work correctly all the time. + + +* **For command /mines set notification added *all* for mine name so all mines can be changed at the same time.** + + +* **Change notification alerts from runnign every 5 minutes to every hour.** +Got a few complaints within the last fewa days that the notifications are too frequent. + + +* **Modified SpigotPlayer to add getRankPlayer() and modified RankPlayer to add getRankLadder, with short cuts for default and prestige so you don't have to always refer to their names (reduce errors).** +This is to remove the "mess" from other functions that need to get these player objects, of which sometimes they are not going about it the correct way. + + +* **sellall multiplier add - Now reports if a multiplier cannot be added. Also now adds the multiplier based upon the actual rank name**, +of which it was what the user entered with the command, which may not match the actual rank name. + + +* **RankLadders - Added a boolean function to check if the ladder is the default ladder or prestiges ladder.** + + +* **sellall multiplier - Now able to list all multipliers.** +It lists them in a 5 column listing. + + +* **Add debug logging when calling the external events.** +Will have to revisit this when hooked up to multi-block events, otherwise it could overwhelm the logging. + + +* **Ladder rank cost multiplier has 100 percent limits removed.** +Value can be any positive or negative number now. + + +* **Update some documentation related to CMI Economy.** + + +* **Broadcast the prison welcome message to all online players when prison is loaded with no mines or ranks defined.** +The messag is loggd to console 8 sconds after prison loads. The broadcast messags are sent 16 seconds after logging the welcome message. +The intention is to help bring awareness to new mods/admins that there is an easy way to get started with prison. + + +* **Broadcast the failed ranks loading to all online players.** +Its important that they know ranks failed to load. + + +* **Release v3.3.0-beta.1 !! Hooray!!** 2022-01-29 2:11 PM EST + + +* **Added nano-second timing autosell to confirm if there is a performance issue.** +My initial testings are showing that sellall has significant chance of performance problems in that selling items takes way too long. Will address in the future. + + +* **Disable all ranks related commands within the GUI menus.** +GUI was bypassing safeguards that were in place when the ranks module failed to load. + + +* **Update the placeholderAPI docs to correct the formatting of the docs to match what they should be.** +Had to indent by two spaces. + + +* **Created updated documents for the placeholderAPI wiki.** +These are local copies of the content since the prior content was removed/vandelized. + + + +* **New Feature: Added support for Quests so that block breakage within mines can now be tracked and be applied towards quests.** + + +* **Bug fix: Lapis_ore appently does not drop lapis_laluzi when using the bukkit's getDrops() function, it instead drops blue_dye, then when it gets to the player's inventory, it is then converted to lapis_lazuli.** +Therefore, auto sell cannot sell lapis_ore drops unles blue_dye is within the shop. I added blue_dye with the same value of lapis_lazuli to the sellall shop. This allows it to be sold now through auto pickup and auto sell. + + + +* **Bug Fix: Damage was being applied all the time.** +Found a field being initialized with a value of 1 when it should have been 0. + + +* **Prevent sellall from loading if ranks does not load. Sellall uses too many rank functions to stand alone.** + + +* **Bug Fix: The new Ranks error message handler which intercepts all ranks messags was failing to load properly when prison startup was not set for a delayed startup,** + which was because the ranks gui command (/ranks) was always being set even when ranks module failed to load. Now /ranks gui loads only if ranks was successful in being started. + + +* **Initially setup to use the actionBar for the messages, but that is not working correctly with such high volume of messages.** +So disabled them for now, but will switch them over shortly... + + +* **Format the earnings amount properly, so it will have a consistant format.** +Once in a while, instead of showing a value like 165.00 it shows 165.000000000000001. This is caused by the fact that doubles are binary, not base-10 so it canot always show the correct values. + + +* **Deprecated the MessagesConfig class since it is not implemented correctly.** +The messages should have been handled through Prison's multi-language tool, of which this does not use. + + +* **Try to use a different way to identify the item stack, especially if the bukkit item stack does not exist.** +This was a random error when using gravel, sand, and dirt on spigot/paper 1.12.2. + + +* **Clean up some of the refrences to the new/old block models.** + + +* **Added the new command: '/sellall list' that will list all blocks and their prices.** + + +* **Added comments that usage of auto features cancel drops will not work from spigot v1.8 through 1.12.x.** +Should work with v1.13.x and newer. + + +* **Fix some block issues, mostly getting the correct block bukkit block and limit it to only one location and function that ultimately provides these hooks.** +This release appears to be more functional, but it still should not be used since it's not fully tested. + + +* **First pass at removing the old block model. Do not use this release!!** +This compiles and runs on the server. Most commands appear to work, including mine resets, but no visual confirmation has been performed in game yet. Since so much has been changed and it has not yet been tested in-game, this release should not be used until such rudementary testing can be performed. + + + +
+- + diff --git a/docs/prison_changelogs.md b/docs/prison_changelogs.md index 189d308f2..594a647da 100644 --- a/docs/prison_changelogs.md +++ b/docs/prison_changelogs.md @@ -19,6 +19,7 @@ may be insightful in to some of the evolutionary processes. These build logs represent the work that has been going on within prison. - **[v3.3.0-alpha - Current](changelog_v3.3.x.md)** + - **[v3.3.0-alpha - Current - Part 2](changelog_v3.3.xb.md)** - Future updates will be under the v3.3.x release From 9121d667ebae0a2db8925ff3119e39b03c4d74a5 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 27 Apr 2025 13:26:25 -0400 Subject: [PATCH 278/323] Blocks: added an isPassable() function to the compatibility functions since this function does not exist in bukkit versions less than 1.14. This is used when throwing bombs. --- docs/changelog_v3.3.x.md | 7 +- .../spigot/compat/CompatibilityBlocks.java | 21 +++++ .../spigot/compat/Spigot_1_14_Blocks.java | 25 ++++++ .../spigot/compat/Spigot_1_8_Blocks.java | 79 +++++++++++++++++++ .../prison/spigot/game/SpigotPlayer.java | 4 +- 5 files changed, 134 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index a86ed892c..b2e03c38c 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.19h 2025-04-07 +# 3.3.0-alpha.19h 2025-04-27 + + +* **Blocks: added an isPassable() function to the compatibility functions since this function does not exist in bukkit versions less than 1.14.** +This is used when throwing bombs. + * **Change logs: Restructured the change logs so the primary file is not quite as large. It was starting to run in to some lag issues when editing.** 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 8b1be84a3..b0d5f7f45 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 @@ -102,5 +102,26 @@ public interface CompatibilityBlocks */ public void setCustomModelData( ItemStack itemStack, int customModelData ); + + /** + *

With spigot 1.14 and newer, there is a function on a block that + * identifies if a block is passable. The description in the api docs are: + *

+ * + *
+	 * Checks if this block is passable.
+
+A block is passable if it has no colliding parts that would prevent 
+players from moving through it.
+
+Examples: Tall grass, flowers, signs, etc. are passable, but open doors, 
+fence gates, trap doors, etc. are not because they still have parts that 
+can be collided with.
+	 * 

+ * + * @param bBlock + * @return + */ + public boolean isPassable( Block bBlock ); } 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 index 9a76d4372..8cbcbbcd4 100644 --- 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 @@ -2,6 +2,7 @@ import java.lang.reflect.Method; +import org.bukkit.block.Block; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; @@ -106,4 +107,28 @@ public void setCustomModelData( ItemStack itemStack, int customModelData ) { } } + + /** + *

With spigot 1.14 and newer, there is a function on a block that + * identifies if a block is passable. The description in the api docs are: + *

+ * + *
+	 * Checks if this block is passable.
+
+A block is passable if it has no colliding parts that would prevent 
+players from moving through it.
+
+Examples: Tall grass, flowers, signs, etc. are passable, but open doors, 
+fence gates, trap doors, etc. are not because they still have parts that 
+can be collided with.
+	 * 

+ * + * @param bBlock + * @return + */ + @Override + public boolean isPassable( Block bBlock ) { + return bBlock.isPassable(); + } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_8_Blocks.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_8_Blocks.java index cb0d7773e..fd9532537 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_8_Blocks.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_8_Blocks.java @@ -6,6 +6,7 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.scheduler.BukkitRunnable; +import com.cryptomorin.xseries.XBlock; import com.cryptomorin.xseries.XMaterial; import tech.mcprison.prison.internal.block.BlockFace; @@ -845,4 +846,82 @@ public void setCustomModelData( ItemStack itemStack, int customModelData ) { + /** + *

With spigot 1.14 and newer, there is a function on a block that + * identifies if a block is passable. The description in the api docs are: + *

+ * + *
+	 * Checks if this block is passable.
+
+A block is passable if it has no colliding parts that would prevent 
+players from moving through it.
+
+Examples: Tall grass, flowers, signs, etc. are passable, but open doors, 
+fence gates, trap doors, etc. are not because they still have parts that 
+can be collided with.
+	 * 

+ * + *

For 1.8 through 1.13.x, just check the material type for + * some of the possibilities like what is listed. This does not + * need to be a complete list, but it can also be expanded as + * needed based upon feedback too. Some items really don't matter, + * such as crops or short grass, since it's only about one block + * from the ground, so the item, if thrown, will land near that + * area. + *

+ * + * @param bBlock + * @return + */ + @Override + public boolean isPassable( Block bBlock ) { + boolean results = false; + + if ( bBlock != null ) { + + + XMaterial xMat = getXMaterial( bBlock ); + + if ( xMat != null ) { + + boolean isSign = xMat.name().toLowerCase().contains("sign"); + + if ( isSign || XBlock.isCrop(xMat) ) { + results = true; + } + + else { + + + switch ( xMat ) { + case AIR: + + case SHORT_GRASS: + case TALL_GRASS: + case SEAGRASS: + case TALL_SEAGRASS: + + case VINE: + case CAVE_VINES_PLANT: + case TWISTING_VINES_PLANT: + case WEEPING_VINES_PLANT: + + results = true; + break; + + default: + break; + } + } + + + + } + + } + + return results; + } + } 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 e29b72523..d5988d3e3 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 @@ -315,10 +315,12 @@ public SpigotBlock getLineOfSightBlock() { // List results = new ArrayList<>(); + + List blocks = bukkitPlayer.getLineOfSight( null, 256 ); for ( Block block : blocks ) { if ( block != null && block.getType() != Material.AIR && - !block.isPassable() ) { + !SpigotCompatibility.getInstance().isPassable(block) ) { // return the first non-null and non-AIR block, which will From 9e30bf2e6fbea8a8d68f23199a82c10752a8e6dd Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 20 May 2025 03:37:55 -0400 Subject: [PATCH 279/323] Mines: Last block break bug fix. Fixes an issue where the task to break the last few blocks is getting canceled on some servers because the mine reset is running before the blocks can be removed. The mine reset was canceling all tasks, when it should not be. The idea of canceling the tasks was if there was another reset being submitted, but that cannot happen due to the mutex. --- docs/changelog_v3.3.x.md | 6 +++++- .../tech/mcprison/prison/mines/data/MineScheduler.java | 9 ++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index b2e03c38c..ae6aa5100 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.19h 2025-04-27 +# 3.3.0-alpha.19h 2025-05-20 + + +* **Mines: Last block break bug fix. Fixes an issue where the task to break the last few blocks is getting canceled on some servers because the mine reset is running before the blocks can be removed.** +The mine reset was canceling all tasks, when it should not be. The idea of canceling the tasks was if there was another reset being submitted, but that cannot happen due to the mutex. * **Blocks: added an isPassable() function to the compatibility functions since this function does not exist in bukkit versions less than 1.14.** diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineScheduler.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineScheduler.java index bf1d23288..3f3d94ee3 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineScheduler.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineScheduler.java @@ -889,9 +889,12 @@ private void manualReset( MineResetScheduleType resetType, double delayActionSec // cancel existing job: - if ( getTaskId() != null ) { - PrisonTaskSubmitter.cancelTask( getTaskId() ); - } + // Warning... do not cancel current tasks. It may be breaking the + // last block. If another thread is initiating a reset then it won't make it to + // this part of the code. +// if ( getTaskId() != null ) { +// PrisonTaskSubmitter.cancelTask( getTaskId() ); +// } // Clear jobStack and set currentJob to run the RESET with zero delay: getJobStack().clear(); From 3c30ed79314e5e0b8a2df2a6ddcd4becd3554a8f Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 22 Jun 2025 13:06:21 -0400 Subject: [PATCH 280/323] Bounds: Fixed an obscure bug where changing the World was not updating existing instances of a world. This would mostly be impacting unit tests, so this would never have been an issue with actual running of prison. Cleaned up the equals since something was not looking correct with some of the logic. Nothing really changed, but slightly altered to simplify the logic to ensure there are not problems. --- docs/changelog_v3.3.x.md | 7 +- .../tech/mcprison/prison/util/Bounds.java | 31 +++++++-- .../tech/mcprison/prison/util/BoundsTest.java | 67 ++++++++++++++++++- 3 files changed, 96 insertions(+), 9 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index ae6aa5100..8142c8e94 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.19h 2025-05-20 +# 3.3.0-alpha.19h 2025-06-22 + + +* **Bounds: Fixed an obscure bug where changing the World was not updating existing instances of a world.** This would mostly be impacting unit tests, so this would never have been an issue with actual running of prison. +Cleaned up the equals since something was not looking correct with some of the logic. Nothing really changed, but slightly altered to simplify the logic to ensure there are not problems. + * **Mines: Last block break bug fix. Fixes an issue where the task to break the last few blocks is getting canceled on some servers because the mine reset is running before the blocks can be removed.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/util/Bounds.java b/prison-core/src/main/java/tech/mcprison/prison/util/Bounds.java index deed8bbc5..27ecf35bc 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/util/Bounds.java +++ b/prison-core/src/main/java/tech/mcprison/prison/util/Bounds.java @@ -327,6 +327,8 @@ public void reconnectObjects() { /** *

Sets the world on the min, max, and center objects. + * If the other locations have a different world set, it + * will be replaced with this new world. *

* * @param world @@ -334,13 +336,13 @@ public void reconnectObjects() { public void setWorld( World world ) { if ( world != null ) { - if ( getMin().getWorld() == null ) { + if ( getMin() != null ) { getMin().setWorld( world ); } - if ( getMax().getWorld() == null ) { + if ( getMax() != null ) { getMax().setWorld( world ); } - if ( getCenter().getWorld() == null ) { + if ( getCenter() != null ) { getCenter().setWorld( world ); } } @@ -524,6 +526,13 @@ public String toString() { return "Bounds{" + "min=" + min.toCoordinates() + ", max=" + max.toCoordinates() + '}'; } + + /** + *

This will check to see if two Bounds are equal. + * If any point is null, then this should always return + * false. + *

+ */ @Override public boolean equals(Object o) { if (this == o) { @@ -534,9 +543,19 @@ public boolean equals(Object o) { } Bounds bounds = (Bounds) o; - return min != null ? - min.equals(bounds.min) : - bounds.min == null && (max != null ? max.equals(bounds.max) : bounds.max == null); + + // If any point is null, then this must return false: + if ( getMin() == null || getMax() == null || + bounds.getMin() == null || bounds.getMax() == null ) { + return false; + } + + return getMin().equals(bounds.getMin()) && + getMax().equals(bounds.getMax()); + +// return min != null ? +// min.equals(bounds.min) : +// bounds.min == null && (max != null ? max.equals(bounds.max) : bounds.max == null); } @Override public int hashCode() { diff --git a/prison-core/src/test/java/tech/mcprison/prison/util/BoundsTest.java b/prison-core/src/test/java/tech/mcprison/prison/util/BoundsTest.java index fe8c78a1f..28620cbf7 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/util/BoundsTest.java +++ b/prison-core/src/test/java/tech/mcprison/prison/util/BoundsTest.java @@ -37,13 +37,76 @@ public void equals() throws Exception { Bounds otherBounds = new Bounds(new Location(null, 0.0, 0.0, 0.0), new Location(null, 10.0, 10.0, 10.0)); + // Since world is null, this cannot be true: + // Bounds should never exist without a world, otherwise it is virtual. + assertFalse(bounds.equals(otherBounds)); + + // NOTE: How would this ever be true??? +// assertTrue(bounds.equals(otherBounds)); + + TestWorld world1 = new TestWorld("test1"); + TestWorld world2 = new TestWorld("test2"); + + bounds.setWorld( world1 ); + otherBounds.setWorld( world2 ); + + assertFalse(bounds.equals(otherBounds)); + + otherBounds.setWorld( world1 ); + + assertTrue(bounds.equals(otherBounds)); + + otherBounds.getMax().setX( 10.1 ); + assertTrue(bounds.equals(otherBounds)); } @Test - public void fail() throws Exception { - assertTrue( true ); + public void equalsInSameBlock() throws Exception { + + TestWorld world1 = new TestWorld("test1"); + + Bounds bounds = + new Bounds(new Location(world1, 0.0, 0.0, 0.0), new Location(world1, 10.0, 10.0, 10.0)); + Bounds otherBounds = + new Bounds(new Location(world1, 0.0, 0.0, 0.0), new Location(world1, 10.0, 10.0, 10.0)); + + + // Check to ensure these are identical before changing anything: + assertTrue(bounds.equals(otherBounds)); + + + // Confirm that it will fail if outside of existing block: + otherBounds.getMax().setX( 9.0 ); + assertFalse(bounds.equals(otherBounds)); + + + // Now try a somewhere in the original block, using fractions: + otherBounds.getMax().setX( 10.001 ); + assertTrue(bounds.equals(otherBounds)); + + // And a few other variations: + otherBounds.getMax().setX( 10.5 ); + assertTrue(bounds.equals(otherBounds)); + + otherBounds.getMax().setX( 10.999999 ); + assertTrue(bounds.equals(otherBounds)); + + otherBounds.getMax().setX( 10.000001 ); + otherBounds.getMax().setY( 10.999999 ); + otherBounds.getMax().setY( 10.5 ); + assertTrue(bounds.equals(otherBounds)); + + + assertTrue(bounds.equals(otherBounds)); + + } + +// @Test +// public void fail() throws Exception { +// assertTrue( true ); +// } @Test public void within() throws Exception { From eeaef45779c75140c12212edad8e23a6ef275df7 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 22 Jun 2025 13:15:50 -0400 Subject: [PATCH 281/323] Locations: Fixed a potential problem with getting the wrong block, or processing the wrong block. Found the older code was rounding doubles within the block, so instead of being able to confirm that the given block was the same as another, if the position was greater than or equal to x.5 then it would round up to a different block next to it. Fixed by using floor and comparing integer values so the selected block will always be the same block. I am not aware of any specific reported bug related to this problem, but it would have occurred around selecting blocks (like when laying out a mine) or be an issue one the edge of mines where if a block is hit near the edge the rounding could have checked the block outside of the mine instead. I suspect occurrences of this bug were not too frequent, and appeared intermittent. Note that in the prior commit, BoundsTest class was also benefiting from this fix and should have been included in this commit. --- docs/changelog_v3.3.x.md | 7 ++ .../tech/mcprison/prison/util/Location.java | 68 ++++++++++++++++--- 2 files changed, 67 insertions(+), 8 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 8142c8e94..b98d3080e 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.19h 2025-06-22 +* **Locations: Fixed a potential problem with getting the wrong block, or processing the wrong block.** +Found the older code was rounding doubles within the block, so instead of being able to confirm that the given block was the same as another, if the position was greater than or equal to x.5 then it would round up to a different block next to it. +Fixed by using floor and comparing integer values so the selected block will always be the same block. +I am not aware of any specific reported bug related to this problem, but it would have occurred around selecting blocks (like when laying out a mine) or be an issue one the edge of mines where if a block is hit near the edge the rounding could have checked the block outside of the mine instead. I suspect occurrences of this bug were not too frequent, and appeared intermittent. +Note that in the prior commit, BoundsTest class was also benefiting from this fix and should have been included in this commit. + + * **Bounds: Fixed an obscure bug where changing the World was not updating existing instances of a world.** This would mostly be impacting unit tests, so this would never have been an issue with actual running of prison. Cleaned up the equals since something was not looking correct with some of the logic. Nothing really changed, but slightly altered to simplify the logic to ensure there are not problems. 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 960d018b3..31e3911be 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 @@ -178,16 +178,23 @@ public void setDirection( Vector direction ) { this.direction = direction; } + /** + *

Return the integer part of the double, which means + * it should not be rounded; use floor instead. + *

+ * + * @return + */ public int getBlockX() { - return Math.toIntExact(Math.round(getX())); + return (int) Math.floor(getX()); } public int getBlockY() { - return Math.toIntExact(Math.round(getY())); + return (int) Math.floor(getY()); } public int getBlockZ() { - return Math.toIntExact(Math.round(getZ())); + return (int) Math.floor(getZ()); } public Block getBlockAt() { @@ -224,6 +231,40 @@ public void setCorner(boolean isCorner) { this.isCorner = isCorner; } + /** + *

This compares to see if two different locations are the same. + *

+ * + *

There are a few problems with this function. First we need to + * figure out if we want to check to see if we have exactly the same + * object or not, of which we shouldn't expect it to be the same object + * or we could just use the "==" equality test on the two objects. + * Therefore, we know it's not going to be the same object, but we want + * to determine if two objects are at the same location. This is + * yet another problem. What does it mean to be in the same location? + * If item A has an x value of 3.84928 and item B has 3.1489203 should + * that be the same location? Yes, it should. Because the two items + * are within the same "block" for that x value (ignoring y and z axis + * for this example). + *

+ * + *

Therefore, this should check to see if two locations are within + * the same block or not. Likewise, where the "item" is looking should + * never be a factor since two items can be looking off in to different + * directions and still be in the same block. In other words, this + * check of having the same location is for the physical block, and not + * where they are looking. + *

+ * + *

There may be situations were the pitch and yaw must match, but + * in general, it should not be used for this function. Also, the float + * values should NOT be used either since an x value of 3.123456 will not + * be considered in the same block if it has a value of 3.123450 since + * the block is not what that is checking. So integer values must + * be used in this method. + *

+ * + */ @Override public boolean equals(Object o) { if (this == o) { @@ -235,11 +276,22 @@ public boolean equals(Object o) { Location location = (Location) o; - return Double.compare(location.x, x) == 0 && Double.compare(location.y, y) == 0 - && Double.compare(location.z, z) == 0 && Float.compare(location.pitch, pitch) == 0 - && Float.compare(location.yaw, yaw) == 0 && (world != null ? - world.getName().equals(location.world.getName()) : - location.world == null); + // Must be in the same world: + if ( world == null || location.world == null || + !getWorld().getName().equalsIgnoreCase( location.getWorld().getName()) ) { + return false; + } + + + return location.getBlockX() == getBlockX() && + location.getBlockY() == getBlockY() && + location.getBlockZ() == getBlockZ(); + +// return Double.compare(location.x, x) == 0 && Double.compare(location.y, y) == 0 +// && Double.compare(location.z, z) == 0 && Float.compare(location.pitch, pitch) == 0 +// && Float.compare(location.yaw, yaw) == 0 && (world != null ? +// world.getName().equals(location.world.getName()) : +// location.world == null); } From 9f1375c3428526ab07c4617170949fc52ebb504c Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 26 Jun 2025 02:32:37 -0400 Subject: [PATCH 282/323] Mine Bombs: Bug fixes. There are a few bug fixes in these changes which were resulting in mine bombs not working at all, or causing some odd behaviors. One internal change was to pass the mine in to more functions so some of the processes can be more mine aware, and to prevent trying to find the mine a second time. Benefit is reduced processing and slightly faster speeds. One issue was that the initial block being processed for the explosion was not actually in the mine when it was on the surface, so prison would ignore that event. Fix was to shift the block down in to the mine so it would be usable. This was primarily when the Y-offset was set to ZERO. If it was any negative value, then the bombs would work well, but zero was the default value. Some messages sent to the console have been enhanced to provide better clues with what's happening when in debug mode. So if it is a config setting that is preventing the bomb from being tied to the mine, it will be more obvious. --- docs/changelog_v3.3.x.md | 8 ++- .../spigot/block/OnBlockBreakMines.java | 34 +++++++-- .../spigot/utils/PrisonBombListener.java | 69 +++++++++++++++---- .../utils/PrisonUtilsMineBombsTasks.java | 33 ++++++++- 4 files changed, 122 insertions(+), 22 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index b98d3080e..8cb5c1be8 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.19h 2025-06-22 +# 3.3.0-alpha.19h 2025-06-26 + + +* **Mine Bombs: Bug fixes. There are a few bug fixes in these changes which were resulting in mine bombs not working at all, or causing some odd behaviors.** +One internal change was to pass the mine in to more functions so some of the processes can be more mine aware, and to prevent trying to find the mine a second time. Benefit is reduced processing and slightly faster speeds. +One issue was that the initial block being processed for the explosion was not actually in the mine when it was on the surface, so prison would ignore that event. Fix was to shift the block down in to the mine so it would be usable. This was primarily when the Y-offset was set to ZERO. If it was any negative value, then the bombs would work well, but zero was the default value. +Some messages sent to the console have been enhanced to provide better clues with what's happening when in debug mode. So if it is a config setting that is preventing the bomb from being tied to the mine, it will be more obvious. * **Locations: Fixed a potential problem with getting the wrong block, or processing the wrong block.** 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 b958caaf8..9f7a0eee7 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 @@ -204,24 +204,38 @@ public void setSpigotBlock(SpigotBlock spigotBlock) { } - public Mine findMine( SpigotPlayer player, SpigotBlock sBlock, List altBlocksSource, PrisonMinesBlockBreakEvent pmEvent ) + public Mine findMineIncludeTopBottomOfMine( SpigotPlayer player, SpigotBlock sBlock, + List altBlocksSource, PrisonMinesBlockBreakEvent pmEvent ) { - return findMine( player.getUniqueId(), sBlock, altBlocksSource, pmEvent ); + return findMine( player.getUniqueId(), sBlock, altBlocksSource, pmEvent, false ); + } + + public Mine findMine( SpigotPlayer player, SpigotBlock sBlock, + List altBlocksSource, PrisonMinesBlockBreakEvent pmEvent ) + { + return findMine( player.getUniqueId(), sBlock, altBlocksSource, pmEvent, true ); } public Mine findMine( Player player, SpigotBlock sBlock, List altBlocksSource, PrisonMinesBlockBreakEvent pmEvent ) { - return findMine( player.getUniqueId(), sBlock, altBlocksSource, pmEvent ); + return findMine( player.getUniqueId(), sBlock, altBlocksSource, pmEvent, true ); } - public Mine findMine( UUID playerUUID, SpigotBlock sBlock, List altBlocksSource, PrisonMinesBlockBreakEvent pmEvent ) + public Mine findMine( UUID playerUUID, SpigotBlock sBlock, + List altBlocksSource, PrisonMinesBlockBreakEvent pmEvent ) { + return findMine( playerUUID, sBlock, altBlocksSource, pmEvent, true ); + } + public Mine findMine( UUID playerUUID, SpigotBlock sBlock, + List altBlocksSource, PrisonMinesBlockBreakEvent pmEvent, boolean exact ) { // Long playerUUIDLSB = Long.valueOf( playerUUID.getLeastSignificantBits() ); // Get the cached mine, if it exists: Mine mine = getPlayerCache().get( playerUUID.toString() ); - if ( mine == null || sBlock != null && !mine.isInMineExact( sBlock.getLocation() ) ) + if ( mine == null || sBlock != null && + ( exact && !mine.isInMineExact( sBlock.getLocation() ) || + !exact && !mine.isInMineIncludeTopBottomOfMine( sBlock.getLocation() ) ) ) { // Look for the correct mine to use. // Set mine to null so if cannot find the right one it will return a @@ -240,7 +254,10 @@ public Mine findMine( UUID playerUUID, SpigotBlock sBlock, List altBlocks for ( Block bBlock : altBlocksSource ) { SpigotBlock sBlockAltBlock = SpigotBlock.getSpigotBlock( bBlock ); - mine = findMineLocation( sBlockAltBlock ); + + mine = exact ? + findMineLocation( sBlockAltBlock ) : + findMineLocationIncludeTopBottomOfMine( sBlockAltBlock ); if ( mine != null ) { @@ -970,6 +987,11 @@ private Mine findMineLocation( SpigotBlock block ) { null : getPrisonMineManager().findMineLocationExact( block.getLocation() ); } + private Mine findMineLocationIncludeTopBottomOfMine( SpigotBlock block ) { + return getPrisonMineManager() == null || block == null || block.getLocation() == null ? + null : getPrisonMineManager().findMineLocationIncludeTopBottomOfMine( block.getLocation() ); + } + private TreeMap getPlayerCache() { return getPrisonMineManager() == null ? 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 f84e86a67..b0f9eb545 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 @@ -242,16 +242,50 @@ public void run() { .runTaskTimer( new Runnable() { private List locs = new ArrayList<>(); + private int checks = 0; + + /** + *

Remove the bomb. + *

+ */ + private void removeBomb() { + + // Cancel this task: + SpigotPrison.getInstance().getScheduler().cancelTask( mineBomb.getTask() ); + + // Cancel the cancellation task: + SpigotPrison.getInstance().getScheduler().cancelTask(taskId); + + + // remove armor stand: + aStnd.remove(); + } public void run() { Location loc = aStnd.getLocation(); locs.add(loc); + // Only keep no more than 4 locations in the list. Purge the oldest. if ( locs.size() > 4 ) { locs.remove(0); } +// String msg = String.format( +// "### MineBomb: tracking minebomb movements. count=%s locs=%s current: %s", +// Integer.toString(checks++), +// Integer.toString(locs.size()), +// loc.toWorldCoordinates() ); +// Output.get().logInfo( msg ); + + // If mine bomb does not land it may have fallen in the void.. so remove it: + if ( checks > 100 ) { + removeBomb(); + } + if ( locs.size() == 4 ) { + + // When there are four locations, then check to ensure the mine + // bomb is no longer moving... if ( locs.get(0).equals(locs.get(1)) && locs.get(1).equals(locs.get(2)) && locs.get(2).equals(locs.get(3)) @@ -260,15 +294,17 @@ public void run() { // Set the mine bomb's location where the item has landed: mineBomb.setPlacedBombLocation( loc ); - // Cancel this task: - SpigotPrison.getInstance().getScheduler().cancelTask( mineBomb.getTask() ); - - // Cancel the cancellation task: - SpigotPrison.getInstance().getScheduler().cancelTask(taskId); + removeBomb(); - - // remove armor stand: - aStnd.remove(); +// // Cancel this task: +// SpigotPrison.getInstance().getScheduler().cancelTask( mineBomb.getTask() ); +// +// // Cancel the cancellation task: +// SpigotPrison.getInstance().getScheduler().cancelTask(taskId); +// +// +// // remove armor stand: +// aStnd.remove(); // Start mine bomb animation: // loc.setY( loc.getY() ); @@ -283,7 +319,7 @@ public void run() { // if ( iStack.getAmount() == 0 ) { // player.getInventory().removeItem( iStack ); // } - + processBombTriggerEvent( sPlayer, mine, mineBomb, targetBlock, hand ); } @@ -529,7 +565,7 @@ private boolean processBombTriggerEvent( SpigotPlayer sPlayer, boolean canceled = false; - if ( getPrisonUtilsMineBombs().setBombInHand( sPlayer, mineBomb, sBlock, hand ) ) { + if ( getPrisonUtilsMineBombs().setBombInHand( sPlayer, mine, mineBomb, sBlock, hand ) ) { // The item was a bomb and it was activated. // Cancel the event so the item will not be placed or processed farther. @@ -557,13 +593,22 @@ private boolean processBombTriggerEvent( SpigotPlayer sPlayer, * @return */ private Mine getMine(SpigotPlayer sPlayer, MineBombData mineBomb, SpigotBlock sBlock ) { - Mine mine = blockBreakMines.findMine( sPlayer, sBlock, null, null); + + Mine mine = blockBreakMines.findMineIncludeTopBottomOfMine( sPlayer, sBlock, null, null); + + if ( mine == null ) { + // Try testing one block lower: + SpigotBlock altSBlock = (SpigotBlock) sBlock.getLocation() + .getLocationAtDelta(0, -1, 0) + .getBlockAt(); + mine = blockBreakMines.findMineIncludeTopBottomOfMine( sPlayer, altSBlock, null, null); + } if ( mine == null ) { // player is not in a mine, so do not allow them to trigger a mine bomb: if ( Output.get().isDebug() ) { - String msg = "MineBombs: Cannot use mine bombs use outside of mines."; + String msg = "MineBombs: Cannot use mine bombs outside of mines."; sPlayer.setActionBar( msg ); // Output.get().logInfo( msg ); } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTasks.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTasks.java index e036b3fc0..415d5568e 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTasks.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTasks.java @@ -20,6 +20,7 @@ import tech.mcprison.prison.bombs.MineBombs; import tech.mcprison.prison.bombs.MineBombs.ExplosionOrientation; import tech.mcprison.prison.bombs.MineBombs.ExplosionShape; +import tech.mcprison.prison.mines.data.Mine; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.api.ExplosiveBlockBreakEvent; @@ -233,7 +234,8 @@ public void run() { } public boolean setoffBombDelayed( SpigotPlayer sPlayer, MineBombData bomb, // Item droppedBomb, - SpigotBlock targetBlock ) { + SpigotBlock targetBlock, + Mine mine ) { boolean results = false; final Location location = ( targetBlock.getLocation() == null ? @@ -257,11 +259,26 @@ public void run() { List blocks = calculatBlocksForExplosion( bomb, location, mBombs ); + if ( Output.get().isDebug() ) { + String msg = String.format( + "PrisonUtilsMineBombsTasks: calculatedExplosion: Gathered blocks: initial block: %s Mine: %s " + + " isBlockInMine: %s blocksInExplosion: %d", + targetBlock.getLocation().toWorldCoordinates(), + (mine == null ? "none" : mine.getTag()), + Boolean.toString( mine.isInMine( targetBlock )), + blocks.size() + + ); + Output.get().logDebug( msg ); + } + + // SpigotBlock targetBlock = (SpigotBlock) world.getBlockAt( location ); ExplosiveBlockBreakEvent explodeEvent = new ExplosiveBlockBreakEvent( targetBlock.getWrapper(), sPlayer.getWrapper(), blocks ); + explodeEvent.setTriggeredBy( bomb.getName() ); explodeEvent.setMineBomb( bomb ); @@ -295,18 +312,27 @@ public void run() { // Normally the explosion will ONLY work if the center target block was non-AIR. // This setting allows the explosion to be processed even if it is air. explodeEvent.setForceIfAirBlock( true ); + + // Detonate bomb here!! + // Call the explodeEvent, of which, prison will handle the explosion. If prison does not + // cancel the event, then it was not able to use the bomb and the explosion failed. Bukkit.getServer().getPluginManager().callEvent( explodeEvent ); // We want the event to be cancelled since that means prison processed it: if ( explodeEvent.isCancelled() ) { + // Run the finish event... after Prison exploded the bomb! + // Run all of the EffectState.finished effects: submitBombEffects( bomb, EffectState.finished, location ); if ( Output.get().isDebug() ) { Output.get().logDebug( "Mine Bomb's ExplosiveBlockBreakEvent has been canceled. " + - "It may have been processed successfully." ); + "This good and may mean it was processed successfully by prison " + + "(look for block break events before this message), " + + "or another plugin canceled it. " + ); } } else { @@ -315,7 +341,8 @@ public void run() { //droppedBomb.remove(); if ( Output.get().isDebug() ) { - Output.get().logDebug( "Mine Bomb's ExplosiveBlockBreakEvent has NOT been canceled." ); + Output.get().logDebug( "Mine Bomb's ExplosiveBlockBreakEvent has NOT been canceled: " + + "Bomb was not processed by prison. This may be a problem.." ); } } From 8122a5b8f79fada9f0ce057143a9519aa62cd554 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 26 Jun 2025 02:45:27 -0400 Subject: [PATCH 283/323] Release v3.3.0-alpha19i 2025-06-26. --- 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 8cb5c1be8..92a7561c7 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.19h 2025-06-26 +# 3.3.0-alpha.19i 2025-06-26 + + + +* **3.3.0-alpha.19i 2025-06-26** * **Mine Bombs: Bug fixes. There are a few bug fixes in these changes which were resulting in mine bombs not working at all, or causing some odd behaviors.** diff --git a/gradle.properties b/gradle.properties index 1a7e90252..c0c1bc1d1 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.19h +version=3.3.0-alpha.19i From 23e8233030da4b1fafdfac5d2256f6202df71001 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 26 Jun 2025 02:52:49 -0400 Subject: [PATCH 284/323] Mine Bombs: Bug fixes. There are a few bug fixes in these changes which were resulting in mine bombs not working at all, or causing some odd behaviors. One internal change was to pass the mine in to more functions so some of the processes can be more mine aware, and to prevent trying to find the mine a second time. Benefit is reduced processing and slightly faster speeds. One issue was that the initial block being processed for the explosion was not actually in the mine when it was on the surface, so prison would ignore that event. Fix was to shift the block down in to the mine so it would be usable. This was primarily when the Y-offset was set to ZERO. If it was any negative value, then the bombs would work well, but zero was the default value. Some messages sent to the console have been enhanced to provide better clues with what's happening when in debug mode. So if it is a config setting that is preventing the bomb from being tied to the mine, it will be more obvious. --- .../spigot/utils/PrisonUtilsMineBombs.java | 105 ++++++++++++++---- 1 file changed, 81 insertions(+), 24 deletions(-) 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 55435c530..13d2c6ebc 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 @@ -40,7 +40,6 @@ import tech.mcprison.prison.mines.data.Mine; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.spigot.api.ExplosiveBlockBreakEvent; -import tech.mcprison.prison.spigot.block.OnBlockBreakMines; import tech.mcprison.prison.spigot.block.PrisonItemStackNotSupportedRuntimeException; import tech.mcprison.prison.spigot.block.SpigotBlock; import tech.mcprison.prison.spigot.block.SpigotItemStack; @@ -1202,12 +1201,14 @@ public MineBombData getBombItem( Player player ) { *

* * @param sPlayer + * @param mine2 * @param bomb * @param sBlock * @param hand * @return */ public boolean setBombInHand( SpigotPlayer sPlayer, + Mine mine, MineBombData bomb, SpigotBlock sBlock, tech.mcprison.prison.spigot.compat.Compatibility.EquipmentSlot hand ) { @@ -1306,25 +1307,50 @@ else if ( bomb != null ) { - // For mine bombs, take the block below where the bomb's item was dropped. The floating - // item is not the block that needs to be the target block for the explosion. Also, the block - // if it is on top of the mine, would be identified as being outside of the mine. - int count = 0; - boolean isAir = bombBlock.isEmpty(); - while ( (count++ <= ( isAir ? 1 : 0 ) || bombBlock.isEmpty()) && bombBlock.getLocation().getBlockY() > 1 ) { - - int adjustY = bomb.getPlacementAdjustmentY(); + // For mine bombs, apply any y adjustments for each bomb. This would either raise + // or lower the bomb block. + int adjustY = bomb.getPlacementAdjustmentY(); + + if ( adjustY != 0 ) { - Block tempBlock = bombBlock.getLocation().getBlockAtDelta( 0, adjustY, 0 ); - if ( tempBlock != null && tempBlock instanceof SpigotBlock ) { - bombBlock = (SpigotBlock) tempBlock; - } + bombBlock = getNextBlockInTheMine(mine, bombBlock, adjustY); + } + + + // if the block is air, then try 3 times to get a non-air block by taking + // the next lower block: + int i = 0; + while ( i++ <= 3 && bombBlock.isAir() || + !mine.isInMineExact( bombBlock.getLocation() )) { -// Output.get().logInfo( -// "#### PrisonUtilsMineBombs: bomb y loc: " + bombBlock.getWrapper().getLocation().getBlockY() + -// " " + bombBlock.getLocation().getBlockY() + " count= " + count ); + bombBlock = getNextBlockInTheMine(mine, bombBlock, -1 ); } +// // This did not help... the block was not in the mine, +// // but it did not help with setting it off... +// if ( !mine.isInMine( bombBlock ) ) { +// // if selected block is not in the mine, then it's probably on top. +// // Take the block that is under it: +// +// bombBlock = getNextLowerBlockInTheMine(mine, bombBlock, 1 ); +// +// } + + // DO NOT USE: If placementAdjustmentY is zero then this goes in to endless loop: +// int count = 0; +// while ( (count++ <= ( isAir ? 1 : 0 ) || bombBlock.isEmpty()) && bombBlock.getLocation().getBlockY() > 1 ) { +// +// +// Block tempBlock = bombBlock.getLocation().getBlockAtDelta( 0, adjustY, 0 ); +// if ( tempBlock != null && tempBlock instanceof SpigotBlock ) { +// bombBlock = (SpigotBlock) tempBlock; +// } +// +//// Output.get().logInfo( +//// "#### PrisonUtilsMineBombs: bomb y loc: " + bombBlock.getWrapper().getLocation().getBlockY() + +//// " " + bombBlock.getLocation().getBlockY() + " count= " + count ); +// } + bomb.setPlacedBombBlock( bombBlock ); // Output.get().logInfo( @@ -1333,15 +1359,15 @@ else if ( bomb != null ) { //int throwSpeed = 2; - + // NOTE: we already got the correct mine: // check if in a mine: - OnBlockBreakMines obbm = new OnBlockBreakMines(); - Mine mine = obbm.findMine( sPlayer, bombBlock, null, null ); +// OnBlockBreakMines obbm = new OnBlockBreakMines(); +// Mine mine = obbm.findMine( sPlayer, bombBlock, null, null ); - if ( mine == null ) { - // Cannot set the bomb outside of a mine, so cancel: - return isABomb; - } +// if ( mine == null ) { +// // Cannot set the bomb outside of a mine, so cancel: +// return isABomb; +// } // Setting activated to true indicates the bomb is live and it has // been removed from the player's inventory: @@ -1389,7 +1415,7 @@ else if ( bomb != null ) { public void runDetonation() { // Submit the bomb's task to go off: - setoffBombDelayed( sPlayer, bomb, sBombBlock ); + setoffBombDelayed( sPlayer, bomb, sBombBlock, mine ); } }; @@ -1454,6 +1480,37 @@ public void runDetonation() { return isABomb; } + + private SpigotBlock getNextBlockInTheMine(Mine mine, SpigotBlock bombBlock, int adjustY) { + + int yMin = (int) mine.getBounds().getyMin(); + int yMax = (int) mine.getBounds().getyMax(); + + int y = bombBlock.getLocation().getBlockY(); + + int deltaY = adjustY( y, yMin, yMax, adjustY ); + + + Block tempBlock = (Block) bombBlock.getLocation().getBlockAtDelta( 0, deltaY, 0 ); + if ( tempBlock != null && tempBlock instanceof SpigotBlock ) { + bombBlock = (SpigotBlock) tempBlock; + } + return bombBlock; + } + + protected int adjustY( int y, int yMin, int yMax, int deltaY ) { + + int y2 = y + deltaY; + + if ( y2 < yMin ) { + deltaY += yMin - y2; + } + else if ( y2 > yMax ) { + deltaY -= y2 - yMax; + } + + return deltaY; + } public boolean validateMineBombsSpigotVersion() { From a265890a61e53f2e5952553ad98a0d51f8e4cccd Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 28 Jun 2025 23:27:27 -0400 Subject: [PATCH 285/323] Mines: Support falling sand and player placed objects. Prison normally does not support mining blocks that it did not place in the mine. The reason is to prevent players from getting credit and money for mining invalid blocks, of which, could lead to other problems. But this also prevents mining sand blocks when they fall because their supporting blocks were removed. This change now turns off prisons validation of the blocks that are being mine, which will allow mining of fallen sand. As a side effect, it will allow mining of any block found in the mine, for better or for worse. To enable this, start prison so prison can modify the autoFeaturesConfig.yml file. Then edit it and set the following setting to false: 'validateBlocksWerePlacedByPrison: false' --- docs/changelog_v3.3.x.md | 8 +++++++- .../autofeatures/AutoFeaturesFileConfig.java | 2 ++ .../spigot/block/OnBlockBreakEventCore.java | 16 ++++++++++++---- .../prison/spigot/block/OnBlockBreakMines.java | 4 +++- 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 92a7561c7..2a744dffc 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,9 +14,15 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.19i 2025-06-26 +# 3.3.0-alpha.19i 2025-06-28 +* **Mines: Support falling sand and player placed objects.** +Prison normally does not support mining blocks that it did not place in the mine. The reason is to prevent players from getting credit and money for mining invalid blocks, of which, could lead to other problems. But this also prevents mining sand blocks when they fall because their supporting blocks were removed. +This change now turns off prisons validation of the blocks that are being mine, which will allow mining of fallen sand. As a side effect, it will allow mining of any block found in the mine, for better or for worse. +To enable this, start prison so prison can modify the autoFeaturesConfig.yml file. Then edit it and set the following setting to false: +'validateBlocksWerePlacedByPrison: false' + * **3.3.0-alpha.19i 2025-06-26** 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 b0f2cd94a..852a6f1dd 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 @@ -167,6 +167,8 @@ public enum AutoFeatures { isCalculateXPEnabled(general, true), givePlayerXPAsOrbDrops(general, false), + validateBlocksWerePlacedByPrison(general, true), + ifBlockIsAlreadyCountedThenCancelEvent(general, true), processMonitorEventsOnlyIfPrimaryBlockIsAIR(general, true), 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 9f71f2b5a..96c6ca8c0 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 @@ -440,6 +440,13 @@ protected boolean validateEvent( PrisonMinesBlockBreakEvent pmEvent ) debugInfo.append( "itemInHand=[" + ( itemInHand == null ? "AIR" : itemInHand.getDebugInfo()) + "] "); + boolean validateBlocksWerePlacedByPrison = isBoolean( AutoFeatures.validateBlocksWerePlacedByPrison ); + if ( !validateBlocksWerePlacedByPrison ) { + pmEvent.setDebugColorCodeWarning(); + debugInfo.append( "(TargetBlock match requirement is disabled [validateBlocksWerePlacedByPrison: false]) " ); + pmEvent.setDebugColorCodeDebug(); + } + // Since BlastUseEvent (crazy enchant) does not identify the block that is initially // broke, an explosion for them is greater than 1. @@ -491,7 +498,8 @@ protected boolean validateEvent( PrisonMinesBlockBreakEvent pmEvent ) // If MONITOR or BLOCKEVENTS or etc... and block does not match, and if the block is AIR, // and the block has not been mined before, then allow the breakage by // setting bypassMatchedBlocks to true to allow normal processing: - if ( !matchedBlocks && + if ( !validateBlocksWerePlacedByPrison || + !matchedBlocks && targetBlock != null && !targetBlock.isMined() && sBlockHit.isAir() && @@ -530,7 +538,7 @@ protected boolean validateEvent( PrisonMinesBlockBreakEvent pmEvent ) // NOTE: for the primary block pmEvent.getSpigotBlock() the unbreakable will be checked later: if ( targetBlock != null && sBlockHit != null ) { - if ( !targetBlock.isMined() || !targetBlock.isAirBroke() ) { + if ( !validateBlocksWerePlacedByPrison || !targetBlock.isMined() || !targetBlock.isAirBroke() ) { // The field isMined() is used to "reserve" a block to indicate that it is in // the stages of being processed, since much later in the processing will the @@ -696,13 +704,13 @@ else if ( pmEvent.getBbPriority().isMonitor() && sBlockMined.isEmpty() && noTargetBlock++; } - else if ( targetExplodedBlock.isMined() ) { + else if ( validateBlocksWerePlacedByPrison && targetExplodedBlock.isMined() ) { alreadyMined++; } else { - if ( !targetExplodedBlock.isMined() ) { + if ( !validateBlocksWerePlacedByPrison || !targetExplodedBlock.isMined() ) { // Check to make sure the block is the same block that was placed there. // If not, then do not process it. 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 9f7a0eee7..73d3c875e 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 @@ -653,7 +653,9 @@ else if ( bbPriority.isMonitor() && !sBlock.isEmpty() && // } // // } - else { + else if ( AutoFeaturesWrapper.getInstance().isBoolean( AutoFeatures.validateBlocksWerePlacedByPrison ) ) { + + // validate if the block being targeted is the one prison placed in the mine: MineTargetPrisonBlock targetBlock = mine.getTargetPrisonBlock( sBlock ); From c485c7960e45aa1bc08d780b23d84b450928ebd4 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 29 Jun 2025 19:53:05 -0400 Subject: [PATCH 286/323] Mine Bombs: Fixed some issues with mine bombs, such as prison is now check all "throw" events, even if another plugin cancels it. Eliminated a few NPEs since some of them are now being triggered since validation can be turned off. --- docs/changelog_v3.3.x.md | 7 ++- .../spigot/block/OnBlockBreakEventCore.java | 14 +++-- .../spigot/block/OnBlockBreakMines.java | 20 +++++++ .../spigot/utils/PrisonBombListener.java | 2 +- .../utils/PrisonUtilsMineBombsTest.java | 58 +++++++++++++++++++ 5 files changed, 95 insertions(+), 6 deletions(-) create mode 100644 prison-spigot/src/test/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTest.java diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 2a744dffc..fc96feaf5 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.19i 2025-06-28 +# 3.3.0-alpha.19i 2025-06-29 + + +* **Mine Bombs: Fixed some issues with mine bombs, such as prison is now check all "throw" events, even if another plugin cancels it.** +Eliminated a few NPEs since some of them are now being triggered since validation can be turned off. + * **Mines: Support falling sand and player placed objects.** 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 96c6ca8c0..6438f6831 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 @@ -333,21 +333,27 @@ protected void finalizeBreakTheBlocks( PrisonMinesBlockBreakEvent pmEvent ) .append( count ) .append( ":finished)" ); } - + } + + private List finalizeBreakTheBlocksCollectEm( PrisonMinesBlockBreakEvent pmEvent ) { List blocks = new ArrayList<>(); - if ( pmEvent.getTargetBlock() != null && pmEvent.getTargetBlock().getMinedBlock() != null ) { + MineTargetPrisonBlock tBlock = pmEvent.getTargetBlock(); + + if ( tBlock != null && tBlock.getMinedBlock() != null && + tBlock.getPrisonBlock() != null && + tBlock.getPrisonBlock().getBlockName() != null ) { SpigotBlock minedBlock = ((SpigotBlock) pmEvent.getTargetBlock().getMinedBlock()); // Only add the minedBlock to the blocks list if it matches the expected targetBlock name, which // indicates it has not been replaced by something else, such as the result of a block event. - if ( pmEvent.getTargetBlock().getPrisonBlock().getBlockName().equalsIgnoreCase( minedBlock.getBlockName() )) { + if ( tBlock.getPrisonBlock().getBlockName().equalsIgnoreCase( minedBlock.getBlockName() )) { blocks.add( minedBlock ); - pmEvent.getTargetBlock().setAirBroke( true ); + tBlock.setAirBroke( true ); // pmEvent.getTargetBlock().setMinedBlock( null ); } 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 73d3c875e..051beda84 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 @@ -852,6 +852,25 @@ public boolean isBlockAMatch( MineTargetPrisonBlock targetBlock, PrisonBlock pbB *

The function isBlockAMatch() should be used prior to calling this function. *

* + *

Note, it is now possible that block validation can be disabled. If that is the case, then + * the blocks may not match the same type as the targetBlock, or may not have been place in the + * mine by prison (ie.. a player or admin). + * Therefore, actions should be based upon the actual block and not the targetBlock. + * For this function, the targetBlock is only being used to identify if it were a custom + * block type. May want to remove dependency upon targetBlock for this check. Like maybe use the + * mined block to get the "core" prison block type to make that determination. + *

+ * + *

Note: if the target block is a custom block, but yet the actual block is not, calling the + * custom block's getDrop() will not produce the wrong drops. It depends on the plugin handling + * the drops, but it may return the bukkit drops, or no drops. + *

+ * + *

NOTE: to better handle the situation where falling sand may not get the correct target block, + * it may make sense to tag all placed blocks with an NBT tag to identify it's original location, + * then use that location for the correct target block. + *

+ * * @param bukkitDrops * @param targetBlock * @param itemInHand @@ -864,6 +883,7 @@ public boolean collectBukkitDrops( List bukkitDrops, MineTarget boolean results = false; if ( targetBlock != null && + targetBlock.getPrisonBlock() != null && targetBlock.getPrisonBlock().getBlockType().isCustomBlockType() ) { List cbIntegrations = 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 b0f9eb545..8289c092b 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 @@ -139,7 +139,7 @@ public void mineBombPlacementEvent( BlockPlaceEvent event ) { * * @param event */ - @EventHandler( priority = EventPriority.LOW ) + @EventHandler( priority = EventPriority.LOW, ignoreCancelled = false ) public void mineBombThrowEvent( PlayerInteractEvent event ) { ItemStack iStack = event.getItem(); diff --git a/prison-spigot/src/test/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTest.java b/prison-spigot/src/test/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTest.java new file mode 100644 index 000000000..63e164248 --- /dev/null +++ b/prison-spigot/src/test/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTest.java @@ -0,0 +1,58 @@ +package tech.mcprison.prison.spigot.utils; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class PrisonUtilsMineBombsTest extends PrisonUtilsMineBombs { + +// @Test + public void testAdjustYA() { + + // yAdjust too high. Reduce to fit in mine. + int yMin = 50; + int yMax = 100; + + int y = 110; + int yAdjust = -5; + + int deltaY = adjustY( y, yMin, yMax, yAdjust ); + + assertEquals( -10, deltaY ); + + } + +// @Test + public void testAdjustYB() { + + // yAdjust is too much, reduce it so it stays in the mine. + int yMin = 50; + int yMax = 100; + + int y = 52; + int yAdjust = -5; + + int deltaY = adjustY( y, yMin, yMax, yAdjust ); + + assertEquals( -2, deltaY ); + + } + +// @Test + public void testAdjustYC() { + + // Its in the mine, so no adjustment. + + int yMin = 50; + int yMax = 100; + + int y = 80; + int yAdjust = -5; + + int deltaY = adjustY( y, yMin, yMax, yAdjust ); + + assertEquals( -5, deltaY ); + + } + +} From d28b552d05b49f9a3635f78d7d3dc102764da24c Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 30 Jun 2025 03:45:12 -0400 Subject: [PATCH 287/323] Mines: Startup air block counts: Changed slightly to start this task later, and to put a slightly longer delay between mine counts so it puts less load on the server. --- docs/changelog_v3.3.x.md | 6 +++++- .../mcprison/prison/mines/data/MineReset.java | 3 ++- ...StartupRefreshBlockBreakCountSyncTask.java | 20 +++++++++++++++---- .../prison/mines/managers/MineManager.java | 11 ++++++---- 4 files changed, 30 insertions(+), 10 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index fc96feaf5..193fa1c61 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.19i 2025-06-29 +# 3.3.0-alpha.19i 2025-06-30 + + +* **Mines: Startup air block counts: Changed slightly to start this task later, and to put a slightly longer delay between mine counts so it puts less load on the server.** + * **Mine Bombs: Fixed some issues with mine bombs, such as prison is now check all "throw" events, even if another plugin cancels it.** 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 901bd530e..94c963411 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 @@ -91,7 +91,8 @@ public abstract class MineReset public static final long MINE_RESET__PAGE_TIMEOUT_CHECK__BLOCK_COUNT = 250; - public static final long MINE_RESET__AIR_COUNT_BASE_DELAY = 30000L; // 30 seconds + public static final long MINE_RESET__AIR_COUNT_BASE_DELAY_TICKS = 6 * 20L; // 6 seconds + public static final long MINE_RESET__AIR_COUNT_SUBMIT_GAP_TICKS = 5; // 0.25 second private transient List mineTargetPrisonBlocks = null; diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/OnStartupRefreshBlockBreakCountSyncTask.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/OnStartupRefreshBlockBreakCountSyncTask.java index 625a09b3d..81e6cdb30 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/OnStartupRefreshBlockBreakCountSyncTask.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/OnStartupRefreshBlockBreakCountSyncTask.java @@ -69,10 +69,16 @@ public void submit( long delay ) { setJobId( PrisonTaskSubmitter.runTaskLater( this, delay) ); DecimalFormat dFmt = new DecimalFormat( "#,##0.0" ); + DecimalFormat iFmt = new DecimalFormat( "#,##0" ); + + long gapTicks = MineReset.MINE_RESET__AIR_COUNT_SUBMIT_GAP_TICKS; String msg = String.format( - "Startup Block Count Task Submitted to run in %s seconds.", - dFmt.format(delay / 20) + "&dStartup Block Count Task Submitted " + + "&6to run in %s seconds, with a %s tick gap between " + + "each task.", + dFmt.format(delay / 20), + iFmt.format( gapTicks ) ); Output.get().logInfo( msg ); @@ -97,12 +103,17 @@ private Mine getNextMine() { m.getResetCount() == 0 && m.refreshAirCountSyncTaskCheckBeforeSubmit() ) { - // Prevents the mine from being counted again: + // Prevents the mine from being counted again when the next + // check is ran. m.setResetCount( 1 ); countCurrentMine++; + // Sets this mine to be processed next: mine = m; + + // Added this mine to the processedMines list even though it has not + // been processed yet: processedMines.add( m ); break; @@ -159,7 +170,8 @@ private void resubmit() { elapsedNanos = 0; - delay = 2; + delay = MineReset.MINE_RESET__AIR_COUNT_SUBMIT_GAP_TICKS; +// delay = 10; // Delay of 10 ticks, or 1/2 a second } if ( mine != null ) { 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 fc88b70d7..04f00f1a9 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 @@ -35,6 +35,7 @@ import tech.mcprison.prison.internal.block.PrisonBlock.PrisonBlockType; import tech.mcprison.prison.mines.PrisonMines; import tech.mcprison.prison.mines.data.Mine; +import tech.mcprison.prison.mines.data.MineReset; import tech.mcprison.prison.mines.data.OnStartupRefreshBlockBreakCountSyncTask; import tech.mcprison.prison.mines.data.MineScheduler.MineResetActions; import tech.mcprison.prison.mines.data.MineScheduler.MineResetScheduleType; @@ -255,8 +256,9 @@ public void loadFromDbCollection( PrisonMines pMines ) { getMines().size(), offsetTimingMs)); - // Start task to count air blocks: - OnStartupRefreshBlockBreakCountSyncTask.getInstance().submit( 60 ); + // Count the blocks for the mines that were just loaded.. n-sec delay + long submitDelay = MineReset.MINE_RESET__AIR_COUNT_BASE_DELAY_TICKS; + OnStartupRefreshBlockBreakCountSyncTask.getInstance().submit( submitDelay ); // // When finished loading the mines, then if there are any worlds that @@ -706,8 +708,9 @@ public void assignAvailableWorld( String worldName ) { } - // Count the blocks for the mines that were just loaded.. 2 sec delay - OnStartupRefreshBlockBreakCountSyncTask.getInstance().submit( 40 ); + // Count the blocks for the mines that were just loaded.. n-sec delay + long submitDelay = MineReset.MINE_RESET__AIR_COUNT_BASE_DELAY_TICKS; + OnStartupRefreshBlockBreakCountSyncTask.getInstance().submit( submitDelay ); // // Purge all removed mines from the unenabledMines list: From 94e8cdb49a3313d27bda678133cee137ce802839 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 30 Jun 2025 03:56:40 -0400 Subject: [PATCH 288/323] Mine bombs: Added a mine bombStatus so it's better documented if a mine bomb was successful or not. Toned down the status message after a mine bomb is submitted since it sounded like it may always be a possible failure when it really isn't. The bombStatus will now be a clearer indication on success or not. --- docs/changelog_v3.3.x.md | 4 +++ .../mcprison/prison/bombs/MineBombData.java | 26 +++++++++++++++++++ ...nagerPrisonsExplosiveBlockBreakEvents.java | 10 +++++++ .../utils/PrisonUtilsMineBombsTasks.java | 8 +++--- 4 files changed, 44 insertions(+), 4 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 193fa1c61..a948900f2 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.19i 2025-06-30 +* **Mine bombs: Added a mine bombStatus so it's better documented if a mine bomb was successful or not.** +Toned down the status message after a mine bomb is submitted since it sounded like it may always be a possible failure when it really isn't. The bombStatus will now be a clearer indication on success or not. + + * **Mines: Startup air block counts: Changed slightly to start this task later, and to put a slightly longer delay between mine counts so it puts less load on the server.** 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 c534a8777..167fb84e5 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 @@ -289,6 +289,20 @@ public class MineBombData private transient int taskId = -1; + private BombStatus bombStatus; + + public enum BombStatus { + unprocessed, + event_ignored, + event_not_enabled, + canceled, + no_access, + failed_validation, + monitor_successful, + successful + ; + } + public MineBombData() { super(); @@ -298,6 +312,7 @@ public MineBombData() { this.allowedMines = new ArrayList<>(); this.preventedMines = new ArrayList<>(); + } @@ -373,6 +388,7 @@ public MineBombData( String name, String itemType, String explosionShape, this.placedBombBlock = null; this.placedBombLocation = null; + this.bombStatus = BombStatus.unprocessed; } @@ -458,6 +474,8 @@ public MineBombData clone() { } + cloned.setBombStatus( getBombStatus() ); + return cloned; } @@ -930,5 +948,13 @@ public int getTask() { public void setTaskId(int taskId ) { this.taskId = taskId; } + + + public BombStatus getBombStatus() { + return bombStatus; + } + public void setBombStatus(BombStatus bombStatus) { + this.bombStatus = bombStatus; + } } 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 f7f22c93d..f9f7b2c4a 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 @@ -16,6 +16,7 @@ import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; import tech.mcprison.prison.autofeatures.AutoFeaturesWrapper; import tech.mcprison.prison.bombs.MineBombData; +import tech.mcprison.prison.bombs.MineBombData.BombStatus; import tech.mcprison.prison.mines.features.MineBlockEvent.BlockEventType; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.spigot.SpigotPrison; @@ -252,6 +253,7 @@ protected void handleExplosiveBlockBreakEvent( ExplosiveBlockBreakEvent e, bbPriority, true ); if ( eventResults.isIgnoreEvent() ) { + if ( mineBomb != null ) mineBomb.setBombStatus( BombStatus.event_ignored ); return; } @@ -297,6 +299,7 @@ protected void handleExplosiveBlockBreakEvent( ExplosiveBlockBreakEvent e, if ( checkIfNoAccess( pmEvent, start ) ) { e.setCancelled( true ); + if ( mineBomb != null ) mineBomb.setBombStatus( BombStatus.no_access ); return; } @@ -327,6 +330,8 @@ protected void handleExplosiveBlockBreakEvent( ExplosiveBlockBreakEvent e, // than one. if ( mineBomb != null ) { + pmEvent.setForceIfAirBlock( true ); + pmEvent.setMineBomb( mineBomb ); pmEvent.setCalculateDurability( false ); @@ -359,6 +364,8 @@ protected void handleExplosiveBlockBreakEvent( ExplosiveBlockBreakEvent e, e.setCancelled( true ); } + if ( mineBomb != null ) mineBomb.setBombStatus( BombStatus.failed_validation ); + debugInfo.append( "(doAction failed validation) " ); } @@ -369,6 +376,7 @@ protected void handleExplosiveBlockBreakEvent( ExplosiveBlockBreakEvent e, else if ( pmEvent.getBbPriority().isMonitor() ) { // Stop here, and prevent additional processing. // Monitors should never process the event beyond this. + if ( mineBomb != null ) mineBomb.setBombStatus( BombStatus.monitor_successful ); } @@ -391,6 +399,7 @@ else if ( pmEvent.getBbPriority().isMonitor() ) { if ( cancelBy == EventListenerCancelBy.event ) { e.setCancelled( true ); + debugInfo.append( "(event canceled) " ); } else if ( cancelBy == EventListenerCancelBy.drops ) { @@ -414,6 +423,7 @@ else if ( cancelBy == EventListenerCancelBy.drops ) { } } + if ( mineBomb != null ) mineBomb.setBombStatus( BombStatus.successful ); } if ( pmEvent.getSpigotPlayer().isInventoryFull() ) { diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTasks.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTasks.java index 415d5568e..7e3b19c40 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTasks.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTasks.java @@ -329,9 +329,9 @@ public void run() { if ( Output.get().isDebug() ) { Output.get().logDebug( "Mine Bomb's ExplosiveBlockBreakEvent has been canceled. " + - "This good and may mean it was processed successfully by prison " - + "(look for block break events before this message), " - + "or another plugin canceled it. " + "This may mean it was processed successfully by prison " + + "(look for block break events before this message). " + + "Mine Bomb status: " + bomb.getBombStatus().name() ); } } @@ -342,7 +342,7 @@ public void run() { if ( Output.get().isDebug() ) { Output.get().logDebug( "Mine Bomb's ExplosiveBlockBreakEvent has NOT been canceled: " - + "Bomb was not processed by prison. This may be a problem.." ); + + "Mine Bomb status: " + bomb.getBombStatus().name() ); } } From 290ddccaa7103fc1e0d40d69b4de6b11267e644e Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 26 Jul 2025 01:32:57 -0400 Subject: [PATCH 289/323] Mine bombs: Fixed an issue with the item stack not correctly duplicating itself when transitioning from an item in hand to being placed or thrown. As such, lore and NBTs were being lost or removed, which resulted in the mine bombs not being recognized when going through the explosion processing. --- docs/changelog_v3.3.x.md | 6 +- .../prison/spigot/nbt/PrisonNBTUtil.java | 274 +++++++++++++++++- .../spigot/utils/PrisonBombListener.java | 58 +++- .../spigot/utils/PrisonUtilsMineBombs.java | 205 ++++++++++--- 4 files changed, 475 insertions(+), 68 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index a948900f2..a26518771 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.19i 2025-06-30 +# 3.3.0-alpha.19i 2025-07-26 + + +* **Mine bombs: Fixed an issue with the item stack not correctly duplicating itself when transitioning from an item in hand to being placed or thrown.** +As such, lore and NBTs were being lost or removed, which resulted in the mine bombs not being recognized when going through the explosion processing. * **Mine bombs: Added a mine bombStatus so it's better documented if a mine bomb was successful or not.** 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 02f14af1e..ad5de1939 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,16 +1,21 @@ package tech.mcprison.prison.spigot.nbt; + import java.util.Set; +import java.util.TreeMap; import java.util.function.Function; +import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.BlockState; import org.bukkit.entity.Entity; import org.bukkit.inventory.ItemStack; import de.tr7zw.changeme.nbtapi.NBT; +import de.tr7zw.changeme.nbtapi.NBTType; import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT; import de.tr7zw.changeme.nbtapi.iface.ReadableItemNBT; import de.tr7zw.changeme.nbtapi.iface.ReadableNBT; +import tech.mcprison.prison.file.JsonFileIO; import tech.mcprison.prison.output.Output; /** @@ -49,18 +54,24 @@ public static String getNBTString( ItemStack bukkitStack, String key ) { try { Function gsFnc = nbt -> { + String value = null; - try { - Object vObj = nbt.getString(key); - - if ( vObj != null ) { - value = (String) vObj; - } - } - catch (Exception e) { + if ( nbt.hasNBTData() && nbt.hasTag( key ) ) { + value = nbt.getString(key); } + +// try { +// Object vObj = nbt.getString(key); +// +// if ( vObj != null ) { +// value = (String) vObj; +// } +// } +// catch (Exception e) { +// } + // if ( Output.get().isDebug() ) { // Output.get().logInfo( "PrisonNBTUtil.getNBTString():ItemStack: %s", nbt.toString() ); // } @@ -280,7 +291,210 @@ public static void setNBTString( Entity entity, String key, String value ) { } } + public static String getNBTData( Entity entity ) { + String results = null; + + try { + results = NBT.get(entity, nbt -> { + String mString = null; + + + + TreeMap map = new TreeMap<>(); + + JsonFileIO json = new JsonFileIO(); + + try { + String nbtDump = json.toString( nbt ); + String msg = String.format( + "PrisonNBTUtil.getNBTStrings: json nbt dump: %s ", + json.toString( nbtDump ) + ); + Output.get().logInfo( msg ); + } + catch ( Exception e ) { + Output.get().logWarn( "PrisonNBTUtil.getNBTData - Error:: " + e.getMessage() ); + e.fillInStackTrace(); + } + + try { + Set keys = nbt.getKeys(); + + for (String key : keys) { + + NBTType type = nbt.getType(key); + + switch (type) { + case NBTTagString: + { + String val = nbt.getString(key); + map.put(key, val); + } + break; + + case NBTTagDouble: + { + Double val = nbt.getDouble(key); + map.put(key, Double.toString(val) ); + } + break; + + case NBTTagFloat: + { + Float val = nbt.getFloat(key); + map.put(key, Float.toString(val) ); + } + break; + + case NBTTagInt: + { + Integer val = nbt.getInteger(key); + map.put(key, Integer.toString(val) ); + } + break; + + case NBTTagLong: + { + Long val = nbt.getLong(key); + map.put(key, Long.toString(val) ); + } + break; + + case NBTTagShort: + { + Short val = nbt.getShort(key); + map.put(key, Short.toString(val) ); + } + break; + + case NBTTagByte: + { + Byte val = nbt.getByte(key); + map.put(key, Byte.toString(val) ); + } + break; + + case NBTTagIntArray: + { + int[] val = nbt.getIntArray(key); + map.put(key, val.toString() ); + } + break; + + case NBTTagByteArray: + { + byte[] val = nbt.getByteArray(key); + map.put(key, val.toString() ); + } + break; + + case NBTTagLongArray: + { + long[] val = nbt.getLongArray(key); + map.put(key, val.toString() ); + } + break; + + +// case NBTTagList: +// { +// getNbtListValues( key, nbt, map ); +// +// } +// break; + + default: + String msg = String.format( + "PrisonNBTUtil.getNBTData: Unhandled NBT type: %s NBT key: %s ", + type.name(), + key + ); + Output.get().logInfo( msg ); + break; + } + } + + + + mString = json.toString( map ); + + + } + catch (Exception e) { + Output.get().logWarn( "PrisonNBTUtil.getNBTData: Error:: " + e.getMessage() ); + e.fillInStackTrace(); + } + + return mString; + }); + + } + catch (Exception e) { + Output.get().logWarn( "PrisonNBTUtil.getNBTData: Error: " + e.getMessage() ); + e.fillInStackTrace(); + + // ignore exception... these are very common if there are no NBTs on the ItemStack + +// Output.get().logInfo( +// "PrisonNBTUtil.getNBTString(): Failure trying to use NBTs. " +// + "Contact prison support. The NBT library may need to be updated. [%s]", +// e.getMessage() +// ); + } + + return results; + } +// private static void getNbtListValues( String key, ReadableNBT nbt, TreeMap map) { +// +// try { +// +// NBTType listType = nbt.getListType(key); +// +// switch (listType) { +// case NBTTagString: +// map.put( key, nbt.getStringList(key) ); +// break; +// case NBTTagInt: +// map.put( key, nbt.getIntegerList(key) ); +// break; +// case NBTTagIntArray: +// map.put( key, nbt.getIntArrayList(key) ); +// break; +// +// case NBTTagDouble: +// map.put( key, nbt.getDoubleList(key) ); +// break; +// case NBTTagLong: +// map.put( key, nbt.getLongList(key) ); +// break; +// case NBTTagFloat: +// map.put( key, nbt.getFloatList(key) ); +// break; +//// case NBTTagCompound: +//// map.put( key, nbt.getCompoundList(key) ); +//// break; +// +// default: +// String msg = String.format( +// "PrisonNBTUtil.getNbtListValues: Unhandled NBT list type: %s NBT key: %s ", +// listType.name(), +// key +// ); +// Output.get().logInfo( msg ); +// break; +// } +// } +// catch ( Exception e ) { +// +// Output.get().logWarn( "PrisonNBTUtil.getNbtListValues: " +// + "nbt List key: " + key + " Error: " + +// e.getMessage() ); +// e.fillInStackTrace(); +// } +// +// } + public static void nbtDebugLog( ItemStack bukkitStack, String desc ) { if ( Output.get().isDebug() ) { @@ -329,6 +543,7 @@ public static String nbtDebugString( ItemStack bukkitStack ) { return nbtItem.toString(); } + public static String nbtDebugString() { ReadWriteNBT nbtItem = NBT.createNBTObject(); @@ -337,6 +552,49 @@ public static String nbtDebugString() { return nbtItem.toString(); } + /** + * Copies all custom NBT data from a source ItemStack to a target ItemStack. + * This will overwrite any custom NBT tags on the target item that have the same key + * as tags on the source item. + * + * @param sourceItem The ItemStack from which to copy NBT data. + * @param targetItem The ItemStack to which to copy NBT data. + * @return The modified target ItemStack. + */ + public static ItemStack copyCustomNBT(ItemStack sourceItem, ItemStack targetItem) { + if (sourceItem == null || sourceItem.getType() == Material.AIR) { + return targetItem; + } + if (targetItem == null || targetItem.getType() == Material.AIR) { + throw new IllegalArgumentException("Target ItemStack cannot be null or AIR for NBT copy."); + } + + // 1. Get the custom NBT from the source item as an SNBT string. + // The NBT.get() method for ItemStacks expects a Function. + // We cast the lambda explicitly to match this. + final String sourceNbtString = NBT.get(sourceItem, (Function) nbt -> nbt.toString()); + + // 2. Parse the SNBT string into a new, independent ReadWriteNBT compound. + // This is our deep copy of the source item's custom NBT. + ReadWriteNBT sourceCustomNBT = NBT.parseNBT(sourceNbtString); + + // If sourceItem had no custom NBT (e.g., empty string after toString), + // sourceCustomNBT.getKeys() will be empty. Handle this case. + if (sourceCustomNBT.getKeys().isEmpty()) { + return targetItem; // Nothing to copy + } + + // 3. Modify the target item to merge the copied NBT. + // NBT.modify() takes a Consumer for ItemStacks. + NBT.modify(targetItem, targetCustomNBT -> { + targetCustomNBT.mergeCompound(sourceCustomNBT); + }); + + // The targetItem is modified in place. + return targetItem; + } + + // public NBTItem getNBT( ItemStack bukkitStack ) { // NBTItem nbtItemStack = null; // 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 8289c092b..9933dbd44 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 @@ -22,6 +22,7 @@ import tech.mcprison.prison.bombs.MineBombCooldownException; import tech.mcprison.prison.bombs.MineBombData; import tech.mcprison.prison.bombs.MineBombs; +import tech.mcprison.prison.bombs.MineBombs.AnimationArmorStandItemLocation; import tech.mcprison.prison.mines.data.Mine; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.spigot.SpigotPrison; @@ -34,6 +35,7 @@ import tech.mcprison.prison.spigot.game.entity.SpigotArmorStand; import tech.mcprison.prison.spigot.nbt.PrisonNBTUtil; import tech.mcprison.prison.util.Location; +import tech.mcprison.prison.util.Text; /** *

This listener class handles the player's interaction with using a bomb. @@ -100,13 +102,15 @@ public void mineBombPlacementEvent( BlockPlaceEvent event ) { // MineBombData mineBomb = MineBombs.getInstance().findBombByName( sPlayer, bombName ); + String thrower = player.getUniqueId().toString(); + String owner = PrisonNBTUtil.getNBTString(iStack, MineBombs.MINE_BOMBS_NBT_OWNER_UUID); PrisonNBTUtil.setNBTString(iStack, MineBombs.MINE_BOMBS_NBT_KEY, bombName ); PrisonNBTUtil.setNBTString(iStack, MineBombs.MINE_BOMBS_NBT_THROWER_UUID, - player.getUniqueId().toString() ); + thrower ); Block targetBlock = event.getBlockAgainst(); @@ -120,7 +124,7 @@ public void mineBombPlacementEvent( BlockPlaceEvent event ) { EquipmentSlot hand = SpigotCompatibility.getInstance().getHand(event); boolean canceled = processBombTriggerEvent( player, mineBomb, - targetBlock, hand ); + targetBlock, hand, thrower, owner ); if ( canceled ) { event.setCancelled( canceled ); @@ -184,18 +188,26 @@ public void mineBombThrowEvent( PlayerInteractEvent event ) { EquipmentSlot hand = SpigotCompatibility.getInstance().getHand(event); + + + final String thrower = sPlayer.getName(); +// final String thrower = PrisonNBTUtil.getNBTString( iStack, MineBombs.MINE_BOMBS_NBT_THROWER_UUID ); + + final String owner = PrisonNBTUtil.getNBTString( iStack, MineBombs.MINE_BOMBS_NBT_OWNER_UUID); + + + + PrisonNBTUtil.setNBTString(iStack, MineBombs.MINE_BOMBS_NBT_KEY, bombName ); PrisonNBTUtil.setNBTString(iStack, MineBombs.MINE_BOMBS_NBT_THROWER_UUID, - player.getUniqueId().toString() ); + thrower ); SpigotLocation loc = new SpigotLocation( player.getEyeLocation().add( player.getLocation().getDirection() )); -// XMaterial xMat = XMaterial.matchXMaterial(iStack); - ArmorStand armorStand = player.getWorld().spawn( loc.getBukkitLocation(), @@ -206,9 +218,19 @@ public void mineBombThrowEvent( PlayerInteractEvent event ) { SpigotArmorStand sArmorStand = new SpigotArmorStand(armorStand); + sArmorStand.setNbtString( MineBombs.MINE_BOMBS_NBT_KEY, bombName ); - sArmorStand.setNbtString( MineBombs.MINE_BOMBS_NBT_THROWER_UUID, - player.getUniqueId().toString() ); + sArmorStand.setNbtString( MineBombs.MINE_BOMBS_NBT_THROWER_UUID, thrower ); + sArmorStand.setNbtString( MineBombs.MINE_BOMBS_NBT_OWNER_UUID, owner ); + + + if ( Output.get().isDebug() ) { + String nbtJson = Text.translateAmpColorCodes( + PrisonNBTUtil.getNBTData( + sArmorStand.getBukkitEntity() )); + Output.get().logInfo( "PrisonBombListener.mineBombThrowEvent ntb: %s", + nbtJson ); + } Vector velocity = player.getLocation().getDirection().multiply( @@ -320,7 +342,8 @@ public void run() { // player.getInventory().removeItem( iStack ); // } - processBombTriggerEvent( sPlayer, mine, mineBomb, targetBlock, hand ); + processBombTriggerEvent( sPlayer, mine, mineBomb, targetBlock, + hand, thrower, owner ); } } @@ -470,10 +493,14 @@ public void bombPlacementEvent( PlayerInteractEvent event ) { // } + String thrower = player.getUniqueId().toString(); + String owner = PrisonNBTUtil.getNBTString(iStack, MineBombs.MINE_BOMBS_NBT_OWNER_UUID); + + EquipmentSlot hand = SpigotCompatibility.getInstance().getHand(event); - processBombTriggerEvent( player, mineBomb, targetBlock, hand ); + processBombTriggerEvent( player, mineBomb, targetBlock, hand, thrower, owner ); } else { @@ -531,7 +558,9 @@ private String checkMineBombItemStack( ItemStack iStack ) { // } private boolean processBombTriggerEvent( Player player, MineBombData mineBomb, Block targetBlock, - EquipmentSlot hand ) { + EquipmentSlot hand, + String thrower, + String owner ) { SpigotPlayer sPlayer = new SpigotPlayer( player ); @@ -554,18 +583,21 @@ private boolean processBombTriggerEvent( Player player, Mine mine = getMine(sPlayer, mineBomb, sBlock ); - return mine == null ? false : processBombTriggerEvent( sPlayer, mine, mineBomb, sBlock, hand ); + return mine == null ? false : processBombTriggerEvent( sPlayer, mine, mineBomb, sBlock, + hand, thrower, owner ); } private boolean processBombTriggerEvent( SpigotPlayer sPlayer, Mine mine, MineBombData mineBomb, SpigotBlock sBlock, - EquipmentSlot hand ) { + EquipmentSlot hand, + String thrower, + String owner ) { boolean canceled = false; - if ( getPrisonUtilsMineBombs().setBombInHand( sPlayer, mine, mineBomb, sBlock, hand ) ) { + if ( getPrisonUtilsMineBombs().setBombInHand( sPlayer, mine, mineBomb, sBlock, hand, thrower, owner ) ) { // The item was a bomb and it was activated. // Cancel the event so the item will not be placed or processed farther. 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 13d2c6ebc..70067e3bb 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 @@ -197,6 +197,7 @@ public void utilsFindMineBombsArmorStands( CommandSender sender, int count = 0; for (Entity entity : entities) { SpigotEntity sEntity = (SpigotEntity) entity; + SpigotArmorStand sArmorStand = new SpigotArmorStand( entity ); String bombName = getBombName( sEntity, sArmorStand ); @@ -946,28 +947,53 @@ public void utilsMineBombsGive( CommandSender sender, if ( bomb != null ) { - ItemStack bombs = getItemStackBomb( bomb, player ); + SpigotItemStack bombs = getItemStackBomb( bomb, player, count ); - if ( bombs != null ) { - - SpigotItemStack sBombs = new SpigotItemStack( bombs ); - - bombs.setAmount( count ); - player.getInventory().addItem( sBombs ); -// player.getWrapper().getInventory().addItem( bombs ); - - player.getWrapper().updateInventory(); -// player.updateInventory(); - } - else { - - String message = "A mine bomb with the name of %s, has an invalid itemType value. " + - "'%s' does not exist in the XMaterial types. Contact Prison support for help " + - "in finding the correct values to use. Google: 'XSeries XMaterial'"; +// ItemStack bombs = getItemStackBomb( bomb, player ); + + String testBombName = PrisonNBTUtil.getNBTString( bombs.getBukkitStack(), MineBombs.MINE_BOMBS_NBT_KEY ); + + if ( testBombName == null || + testBombName.trim().length() == 0 ) { + String msg = "WARNING: The mine bomb give command failed to properly set the " + + "internal NBT data to identify this item as a mine bomb. This will " + + "fail to work. This is a failure of the NBT library that prison is using, " + + "and it may need to be updated."; + sender.sendMessage(msg); - sender.sendMessage( String.format( message, bombName, bomb.getItemType() ) ); + Output.get().logWarn( msg ); } + player.getInventory().addItem( bombs ); + player.updateInventory(); + +// else if ( bombs != null ) { +// +// bombs.setAmount( count ); +// player.getWrapper().getInventory().addItem( bombs ); +// player.getWrapper().updateInventory(); +// +// // NOTE: The following is not working... the NBTs are not +// // being copied over, so the mine bombs are losing their +// // NBT signatures. +//// SpigotItemStack sBombs = new SpigotItemStack( bombs ); +//// +//// sBombs.setAmount( count ); +//// player.getInventory().addItem( sBombs ); +////// player.getWrapper().getInventory().addItem( bombs ); +//// +//// player.getWrapper().updateInventory(); +////// player.updateInventory(); +// } +// else { +// +// String message = "A mine bomb with the name of %s, has an invalid itemType value. " + +// "'%s' does not exist in the XMaterial types. Contact Prison support for help " + +// "in finding the correct values to use. Google: 'XSeries XMaterial'"; +// +// sender.sendMessage( String.format( message, bombName, bomb.getItemType() ) ); +// } + // XMaterial xBomb = XMaterial.matchXMaterial( bomb.getItemType() ).orElse( null ); // // if ( xBomb != null ) { @@ -1048,20 +1074,30 @@ public void utilsMineBombsGive( CommandSender sender, } - public ItemStack getItemStackBomb( MineBombData bombData, SpigotPlayer player ) { - ItemStack sItemStack = null; + /** + *

This function will take the MineBombData and construct an SpigotItemStack for that + * bomb. + *

+ * + * @param bombData + * @param player + * @param count + * @return + */ + public SpigotItemStack getItemStackBomb( MineBombData bombData, SpigotPlayer player, int count ) { SpigotItemStack bombs = null; // NBTItem nbtItem = null; XMaterial xBomb = XMaterial.matchXMaterial( bombData.getItemType() ).orElse( null ); +// ItemStack sItemStack; if ( xBomb != null ) { try { // Create the spigot/bukkit ItemStack: - sItemStack = xBomb.parseItem(); + ItemStack sItemStack = xBomb.parseItem(); if ( sItemStack != null ) { @@ -1073,6 +1109,8 @@ public ItemStack getItemStackBomb( MineBombData bombData, SpigotPlayer player ) } if ( bombs != null ) { + + bombs.setAmount( count ); bombs.setDisplayName( bombData.getName() ); @@ -1087,40 +1125,107 @@ public ItemStack getItemStackBomb( MineBombData bombData, SpigotPlayer player ) // if ( bomb.isGlowing() ) { // bombs.addEnchantment( ); // } + - List lore = new ArrayList<>( bombData.getLore() ); + // Add lore to the mine bomb's SpigotItemStack: + bombs.setLore( bombData.getLore() ); - // lore.add( 0, bombData.getLoreBombItemId() ); +// if ( Output.get().isDebug() ) { +// List lore = new ArrayList<>(); +// +// lore.add( "## Lore from bombdata: " ); +// lore.addAll( bombData.getLore() ); +// +// lore.add( "## Lore from bomb ItemStack: " ); +// lore.addAll( bombs.getLore() ); +// +// for (String l : lore ) { +// +// Output.get().logInfo( "Bomb name: %s lore: " +// + "bombName: &7%s&r &3:: nbt: &r\\Q%s\\E", +// bombData.getNameTag(), +// l, l +// ); +// } +// } - bombs.setLore( lore ); - - // SpigotCompatibility.getInstance().setCustomModelData( bombs, bombData.getCustomModelData() ); - sItemStack = bombs.getBukkitStack(); - } - - if ( sItemStack != null ) { - // Set the NBT String key-value pair: - PrisonNBTUtil.setNBTString(sItemStack, MineBombs.MINE_BOMBS_NBT_KEY, bombData.getName() ); - PrisonNBTUtil.setNBTString(sItemStack, MineBombs.MINE_BOMBS_NBT_OWNER_UUID, player.getUUID().toString() ); +// List lore = new ArrayList<>( bombData.getLore() ); +// for (String bLore : bombData.getLore()) { +// bombs.getLore(); +// } + // lore.add( 0, bombData.getLoreBombItemId() ); -// nbtItem = new NBTItem( sItemStack, true ); -// nbtItem.setString( MineBombs.MINE_BOMBS_NBT_BOMB_KEY, bombData.getName() ); - + { +// List lore = bombs.getLore(); +// +// lore.add( MINE_BOMBS_LORE_1 ); +// lore.add( MINE_BOMBS_LORE_2_PREFIX + bombData.getName() ); +// lore.add( " " ); +// +// lore.add( "Size, Diameter: " + ( 1 + 2 * bomb.getRadius()) ); +// lore.add( "Shape: " + bomb.getExplosionShape() ); +// +// String[] desc = bomb.getDescription().split( " " ); +// StringBuilder sb = new StringBuilder(); +// +// for ( String d : desc ) { +// +// sb.append( d ).append( " " ); +// +// if ( sb.length() > 30 ) { +// sb.insert( 0, " " ); +// +// lore.add( sb.toString() ); +// sb.setLength( 0 ); +// } +// } +// if ( sb.length() > 0 ) { +// sb.insert( 0, " " ); +// +// lore.add( sb.toString() ); +// } +//// lore.add( " " + bomb.getDescription() ); +// +// lore.add( " " ); +// +// bombs.setLore( lore ); + } - // Set the customModelData on the bomb to allow for custom skins: - SpigotCompatibility.getInstance().setCustomModelData( sItemStack, bombData.getCustomModelData() ); +// bombs.setLore( lore ); + // SpigotCompatibility.getInstance().setCustomModelData( bombs, bombData.getCustomModelData() ); - if ( Output.get().isDebug() ) { - Output.get().logInfo( "getItemStackBombs ntb: %s", - Text.translateAmpColorCodes( PrisonNBTUtil.nbtDebugString(sItemStack) ) - ); +// sItemStack = bombs.getBukkitStack(); + + if ( bombs.getBukkitStack() != null ) { + + ItemStack sItemStack = bombs.getBukkitStack(); + + // Set the NBT String key-value pair: + PrisonNBTUtil.setNBTString(sItemStack, MineBombs.MINE_BOMBS_NBT_KEY, bombData.getName() ); + PrisonNBTUtil.setNBTString(sItemStack, MineBombs.MINE_BOMBS_NBT_OWNER_UUID, player.getUUID().toString() ); + + +// 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", + Text.translateAmpColorCodes( PrisonNBTUtil.nbtDebugString(sItemStack) ) + ); + } } } + } else { String message = String.format( @@ -1132,7 +1237,7 @@ public ItemStack getItemStackBomb( MineBombData bombData, SpigotPlayer player ) Output.get().logError( message ); } - return sItemStack; + return bombs; } @@ -1205,13 +1310,17 @@ public MineBombData getBombItem( Player player ) { * @param bomb * @param sBlock * @param hand + * @param owner + * @param thrower * @return */ public boolean setBombInHand( SpigotPlayer sPlayer, Mine mine, MineBombData bomb, SpigotBlock sBlock, - tech.mcprison.prison.spigot.compat.Compatibility.EquipmentSlot hand ) { + tech.mcprison.prison.spigot.compat.Compatibility.EquipmentSlot hand, + String thrower, + String owner ) { boolean isABomb = false; // MineBombData bomb = getBombItem( player ); @@ -1275,7 +1384,7 @@ else if ( bomb != null ) { // MineBombs.addPlayerCooldown( sPlayer, bomb.getCooldownTicks() ); SpigotItemStack bombs = new SpigotItemStack( - getItemStackBomb( bomb, sPlayer )); + getItemStackBomb( bomb, sPlayer, 1 )); if ( bombs != null ) { @@ -1424,7 +1533,11 @@ public void runDetonation() { // will submit the tasks, unless no animations are chosen. BombAnimationsTask animationsTask = new BombAnimationsTask(); - animationsTask.animatorFactory( bomb, bombBlock, itemInHand, detonateBomb ); + animationsTask.animatorFactory( bomb, bombBlock, itemInHand, + detonateBomb ); + +// animationsTask.animatorFactory( bomb, bombBlock, itemInHand, +// detonateBomb, thrower, owner ); From 3687e430e8f24020bdf25af3d94345393ce730e3 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 26 Jul 2025 01:40:29 -0400 Subject: [PATCH 290/323] Players: Bug fix. If unable to get a player's default rank, then return a null from the function. It was recording that an error happened, but it was returning a null, but continuing on with the processing as if it has a valid rank. --- docs/changelog_v3.3.x.md | 5 +++++ .../java/tech/mcprison/prison/ranks/data/RankPlayer.java | 1 + 2 files changed, 6 insertions(+) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index a26518771..bdc02dbd6 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.19i 2025-07-26 +* **Players: Bug fix. If unable to get a player's default rank, then return a null from the function.** + It was recording that an error happened, but it was returning a null, but continuing on with the processing as if it has a valid rank. This was not a commonly occurring bug, but was happening with edge case testing. + + + * **Mine bombs: Fixed an issue with the item stack not correctly duplicating itself when transitioning from an item in hand to being placed or thrown.** As such, lore and NBTs were being lost or removed, which resulted in the mine bombs not being recognized when going through the explosion processing. 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 8c9aea9f8..28157e75e 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 @@ -1805,6 +1805,7 @@ public PlayerRank getNextPlayerRank() { "Please try restarting the server to see if that fixes the problem before contacting " + "prison's support team. Thanks!" )); + return null; } Rank nRank = rankCurrent.getRank().getRankNext(); From 46f9c1321a92a3d3b56d8d6722613ad548540d00 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 26 Jul 2025 01:57:35 -0400 Subject: [PATCH 291/323] Players: Bug fix. If unable to get a player's default rank, then return a null from the function. It was recording that an error happened, but it was returning a null, but continuing on with the processing as if it has a valid rank. --- .../prison/spigot/block/SpigotItemStack.java | 85 +++++++++++-------- 1 file changed, 49 insertions(+), 36 deletions(-) diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/SpigotItemStack.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/SpigotItemStack.java index d02649c7e..42e48e357 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/SpigotItemStack.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/SpigotItemStack.java @@ -417,33 +417,43 @@ private ItemMeta getMeta() { @Override public void setDisplayName( String displayName ) { - ItemMeta meta = getMeta(); - if ( meta != null && displayName != null && displayName.trim().length() > 0 ) { + if ( getBukkitStack() != null ) { - meta.setDisplayName( Text.translateAmpColorCodes(displayName) ); + ItemMeta meta = getMeta(); + if ( meta != null && displayName != null && displayName.trim().length() > 0 ) { + + meta.setDisplayName( Text.translateAmpColorCodes(displayName) ); + + getBukkitStack().setItemMeta( meta ); + } } - - getBukkitStack().setItemMeta( meta ); super.setDisplayName( displayName ); } @Override public void setLore( List lores ) { - List updatedLores = new ArrayList<>(); - ItemMeta meta = getMeta(); - if ( meta != null && lores != null && lores.size() > 0 ) { + if ( getBukkitStack() != null ) { - for ( String lore : lores ) { - updatedLores.add( Text.translateAmpColorCodes(lore) ); + ItemMeta meta = getMeta(); + if ( meta != null && lores != null && lores.size() > 0 ) { + + List updatedLores = new ArrayList<>(); + + for ( String lore : lores ) { + updatedLores.add( Text.translateAmpColorCodes(lore) ); + } + + meta.setLore( updatedLores ); + + getBukkitStack().setItemMeta( meta ); + + getLore().addAll( updatedLores ); + } - - meta.setLore( updatedLores ); } - getBukkitStack().setItemMeta( meta ); - //super.setLore( updatedLores ); } @@ -548,31 +558,34 @@ public String getDebugInfo() { sb.append( getName() ); - ItemMeta meta = getMeta(); - if ( meta != null && - meta.getEnchants() != null && - meta.getEnchants().size() > 0 ) { - sb.append( " " ); + if ( getBukkitStack() != null ) { - StringBuilder sbE = new StringBuilder(); - Set keys = meta.getEnchants().keySet(); - for (Enchantment key : keys) { - if ( sbE.length() > 0 ) { - sbE.append(","); + ItemMeta meta = getMeta(); + if ( meta != null && + meta.getEnchants() != null && + meta.getEnchants().size() > 0 ) { + sb.append( " " ); + + StringBuilder sbE = new StringBuilder(); + Set keys = meta.getEnchants().keySet(); + for (Enchantment key : keys) { + if ( sbE.length() > 0 ) { + sbE.append(","); + } + String name = key.toString(); + name = name.substring(name.indexOf(" ") + 1, name.length() - 1); + + Integer level = meta.getEnchants().get(key); + sbE.append( name ); + sbE.append(":"); + sbE.append( level ); } - String name = key.toString(); - name = name.substring(name.indexOf(" ") + 1, name.length() - 1); - Integer level = meta.getEnchants().get(key); - sbE.append( name ); - sbE.append(":"); - sbE.append( level ); - } - - if ( sbE.length() > 0 ) { - sb.append("("); - sb.append( sbE ); - sb.append(")"); + if ( sbE.length() > 0 ) { + sb.append("("); + sb.append( sbE ); + sb.append(")"); + } } } From a9dc9dbb91ae22530422b1d1e5aeb18d1da1b4f3 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 3 Dec 2025 02:01:33 -0500 Subject: [PATCH 292/323] Fix a bug (2025-07-28) with inventory items being held in the off-hand. If I recall, this was a potential exploit under some circumstances. Added support for selling through the off-hand, and provided fallbacks for older versions of spigot, such as 1.9. --- docs/changelog_v3.3.x.md | 9 +- .../mcprison/prison/spigot/SpigotUtil.java | 85 ++++++++++++++----- .../prison/spigot/compat/Compatibility.java | 4 + .../prison/spigot/compat/Spigot_1_13.java | 18 ++++ .../prison/spigot/compat/Spigot_1_8.java | 18 ++++ .../prison/spigot/compat/Spigot_1_9.java | 17 ++++ .../prison/spigot/sellall/SellAllUtil.java | 44 +++++++++- 7 files changed, 174 insertions(+), 21 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index bdc02dbd6..3f154fbbd 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,9 +14,16 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.19i 2025-07-26 +# 3.3.0-alpha.19i 2025-12-03 +** 2025-07-28 ** + +* **Fix a bug with inventory items being held in the off-hand. If I recall, this was a potential exploit under some circumstances. Added support for selling through the off-hand, and provided fallbacks for older versions of spigot, such as 1.9. + + +** 2025-07-26 ** + * **Players: Bug fix. If unable to get a player's default rank, then return a null from the function.** It was recording that an error happened, but it was returning a null, but continuing on with the processing as if it has a valid rank. This was not a commonly occurring bug, but was happening with edge case testing. 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 11b84d96b..02d3d0257 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 @@ -54,6 +54,7 @@ import tech.mcprison.prison.spigot.game.SpigotWorld; import tech.mcprison.prison.spigot.integrations.IntegrationBackpackAPI; import tech.mcprison.prison.spigot.integrations.IntegrationMinepacksPlugin; +import tech.mcprison.prison.spigot.nbt.PrisonNBTUtil; import tech.mcprison.prison.util.Location; import tech.mcprison.prison.util.Text; import tech.mcprison.prison.util.Vector; @@ -1177,42 +1178,88 @@ public static SpigotItemStack bukkitItemStackToPrison( ItemStack bukkitStack) { return results; } + /** + *

This function will try to use the 'prisonStack' parameter, and then + * construct an org.bukkit.inventory.ItemStack object and return it. If + * the provided prisonStack already contains a bukkit ItemStack, then it + * will be returned from this function, otherwise it will have to construct + * one. + *

+ * + *

If it has to construct one, it will add the lore and custom name. + * It may have to also handle enchantments too. Not sure right now. + *

+ * + *

The idea is that hopefully the prisonStack will always have an + * included bukkit ItemStack so everything will faithfully copy over. + *

+ * + * @param prisonStack + * @return + */ public static ItemStack prisonItemStackToBukkit( tech.mcprison.prison.internal.ItemStack prisonStack) { + + ItemStack bukkitStack = null; + int amount = prisonStack.getAmount(); - ItemStack bukkitStack = getItemStack( prisonStack.getMaterial(), amount ); + if ( prisonStack instanceof SpigotItemStack ) { + + SpigotItemStack sItemStack = (SpigotItemStack) prisonStack; + + if ( sItemStack.getBukkitStack() != null ) { + bukkitStack = sItemStack.getBukkitStack(); + } + } + + if ( bukkitStack == null ) { + + bukkitStack = getItemStack( prisonStack.getMaterial(), amount ); + // MaterialData materialData = blockTypeToMaterial(prisonStack.getMaterial()); // // ItemStack bukkitStack = new ItemStack(materialData.getItemType(), amount); // bukkitStack.setData(materialData); - - ItemMeta meta; - if (bukkitStack.getItemMeta() == null || !bukkitStack.hasItemMeta()) { - meta = Bukkit.getItemFactory().getItemMeta(bukkitStack.getType()); - } else { - meta = bukkitStack.getItemMeta(); - } - - if (meta != null) { - if (prisonStack.getDisplayName() != null) { - meta.setDisplayName(Text.translateAmpColorCodes(prisonStack.getDisplayName())); + + ItemMeta meta; + if (bukkitStack.getItemMeta() == null || !bukkitStack.hasItemMeta()) { + meta = Bukkit.getItemFactory().getItemMeta(bukkitStack.getType()); + } else { + meta = bukkitStack.getItemMeta(); } - if (prisonStack.getLore() != null) { - List colored = new ArrayList<>(); - for (String uncolor : prisonStack.getLore()) { - colored.add(Text.translateAmpColorCodes(uncolor)); + + if (meta != null) { + if (prisonStack.getDisplayName() != null) { + meta.setDisplayName(Text.translateAmpColorCodes(prisonStack.getDisplayName())); + } + if (prisonStack.getLore() != null) { + List colored = new ArrayList<>(); + for (String uncolor : prisonStack.getLore()) { + colored.add(Text.translateAmpColorCodes(uncolor)); + } + meta.setLore(colored); } - meta.setLore(colored); + bukkitStack.setItemMeta(meta); } - bukkitStack.setItemMeta(meta); - } + + // Need to copy enchantments? + + // Need to copy lore: + // No, this does not make sense... if prisonStack has NBT data, then + // it would also have a getBukkitStack() entry, so this part of the + // code would never be reached. So if there is no bukkitStack in the + // prisonStack, then there would be no NBT data either. +// PrisonNBTUtil.copyCustomNBT(bukkitStack, bukkitStack) + } return bukkitStack; } + + /** *

Drops for lapis_ore is odd before the flattening (bukkit 1.8.x through 1.12.2) since it * drops as blue_dye, but when it makes it to the player's inventory, it is then converted to diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Compatibility.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Compatibility.java index b6666c83a..2f64f9fc8 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Compatibility.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Compatibility.java @@ -63,6 +63,8 @@ public interface Compatibility public ItemStack getItemInOffHand(PlayerInteractEvent e); public ItemStack getItemInOffHand(Player player); + + public ItemStack getItemInOffHandStrict(Player player); public ItemStack getItemInOffHand(PlayerInventory playerInventory); @@ -73,6 +75,8 @@ public interface Compatibility public void setItemInMainHand(SpigotPlayer p, ItemStack itemStack); public void setItemStackInOffHand( SpigotPlayerInventory inventory, SpigotItemStack itemStack ); + + public void setItemStackInOffHandStrict( Player player, ItemStack itemStack ); public void breakItemInMainHand(Player player); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_13.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_13.java index 599477d32..e331881ee 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_13.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_13.java @@ -91,6 +91,24 @@ public ItemStack getItemInOffHand(PlayerInventory playerInventory) { return playerInventory.getItemInOffHand(); } + /** + * 1.9 and higher supports off-hand: + */ + @Override + public ItemStack getItemInOffHandStrict(Player player) { + return getItemInOffHand(player.getInventory()); + } + + /** + * 1.9 and higher supports off-hand: + */ + @Override + public void setItemStackInOffHandStrict(Player player, ItemStack itemStack) { + + player.getInventory().setItemInOffHand(itemStack); + } + + @Override public void setItemStackInMainHand( SpigotPlayerInventory inventory, SpigotItemStack itemStack ) { diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_8.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_8.java index 86af647d4..ea673af2d 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_8.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_8.java @@ -101,10 +101,28 @@ public ItemStack getItemInOffHand(Player player ) { /** * This function does not exist in v1.8 so returns null. */ + @Override public ItemStack getItemInOffHand(PlayerInventory playerInventory) { return null; } + /** + * This function does not exist in v1.8 so returns null. + */ + @Override + public ItemStack getItemInOffHandStrict(Player player) { + return null; + } + + /** + * This function does not exist in v1.8 so do nothing. + */ + @Override + public void setItemStackInOffHandStrict(Player player, ItemStack itemStack) { + + } + + @SuppressWarnings( "deprecation" ) @Override public void setItemStackInMainHand( SpigotPlayerInventory inventory, SpigotItemStack itemStack ) { diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_9.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_9.java index 41c404697..d9b31ed5b 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_9.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_9.java @@ -114,6 +114,23 @@ public ItemStack getItemInOffHand(PlayerInventory playerInventory) { return playerInventory.getItemInOffHand(); } + /** + * 1.9 and higher supports off-hand: + */ + @Override + public ItemStack getItemInOffHandStrict(Player player) { + return getItemInOffHand(player.getInventory()); + } + + /** + * 1.9 and higher supports off-hand: + */ + @Override + public void setItemStackInOffHandStrict(Player player, ItemStack itemStack) { + + player.getInventory().setItemInOffHand(itemStack); + } + @Override public void setItemStackInMainHand( SpigotPlayerInventory inventory, SpigotItemStack itemStack ) { 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 16d30efa3..5cf73c06a 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 @@ -36,6 +36,7 @@ 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.SpigotCompatibility; //import tech.mcprison.prison.spigot.configs.MessagesConfig; import tech.mcprison.prison.spigot.game.SpigotCommandSender; import tech.mcprison.prison.spigot.game.SpigotPlayer; @@ -1089,9 +1090,50 @@ public List sellPlayerItems(Player p) { double multiplier = sPlayer.getSellAllMultiplier(); - SpigotPlayerInventory spInventory = sPlayer.getSpigotPlayerInventory(); + + // Remove player's off-hand and helmet slots since those don't always sell correctly: + boolean invDirty = false; + ItemStack offHandItemStack = SpigotCompatibility.getInstance().getItemInOffHandStrict( p ); + + if ( offHandItemStack != null ) { + // 1.8 will always be null, so it will never hit this. + ItemStack itemStack = null; + SpigotCompatibility.getInstance().setItemStackInOffHandStrict( p, itemStack ); + + invDirty = true; + } + + ItemStack helmetItemStack = p.getInventory().getHelmet(); + + if ( helmetItemStack != null ) { + p.getInventory().setHelmet( null ); + invDirty = true; + } + + + + SpigotPlayerInventory spInventory = sPlayer.getSpigotPlayerInventory(); + + List soldData = sellInventoryItems( spInventory, multiplier ); + + + + // Since the inventory is done being sold, add back the offHand and helmet: + if ( offHandItemStack != null ) { + // 1.8 will always be null, so it will never hit this. + SpigotCompatibility.getInstance().setItemStackInOffHandStrict( p, offHandItemStack ); + } + + if ( helmetItemStack != null ) { + p.getInventory().setHelmet( helmetItemStack ); + } + + if ( invDirty ) { + p.updateInventory(); + } + if ( isSellAllBackpackItemsEnabled && BackpacksUtil.getInstance().isEnabled() ) { BackpacksUtil bpUtil = BackpacksUtil.get(); From cd97e525909fcf68709bd57dce8389d91882f8b6 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 3 Dec 2025 02:07:56 -0500 Subject: [PATCH 293/323] Bug fix: Prevent an NPE when a sellallItem is null. Generally this should not happen, but there was another bug that caused that object to be null, so this fix is just an extra insurance. --- docs/changelog_v3.3.x.md | 5 +++-- .../spigot/commands/PrisonSpigotSellAllCommands.java | 7 +++++-- .../tech/mcprison/prison/spigot/game/SpigotPlayer.java | 3 +++ 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 3f154fbbd..855684f70 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,9 +17,10 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.19i 2025-12-03 -** 2025-07-28 ** +** 2025-07-26 ** **Bug fix: Prevent an NPE when a sellallItem is null.** Generally this should not happen, but there was another bug that caused that object to be null, so this fix is just an extra insurance. -* **Fix a bug with inventory items being held in the off-hand. If I recall, this was a potential exploit under some circumstances. Added support for selling through the off-hand, and provided fallbacks for older versions of spigot, such as 1.9. + +** 2025-07-28 ** **Fix a bug with inventory items being held in the off-hand.** If I recall, this was a potential exploit under some circumstances. Added support for selling through the off-hand, and provided fallbacks for older versions of spigot, such as 1.9. ** 2025-07-26 ** 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 3325dcc1e..1cb4c2e88 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 @@ -15,6 +15,7 @@ import tech.mcprison.prison.Prison; import tech.mcprison.prison.PrisonAPI; +import tech.mcprison.prison.bombs.MineBombs; import tech.mcprison.prison.commands.Arg; import tech.mcprison.prison.commands.Command; import tech.mcprison.prison.commands.Wildcard; @@ -33,6 +34,7 @@ import tech.mcprison.prison.spigot.configs.MessagesConfig; import tech.mcprison.prison.spigot.game.SpigotPlayer; import tech.mcprison.prison.spigot.game.SpigotPlayerUtil; +import tech.mcprison.prison.spigot.nbt.PrisonNBTUtil; import tech.mcprison.prison.spigot.sellall.SellAllBlockData; import tech.mcprison.prison.spigot.sellall.SellAllUtil; import tech.mcprison.prison.spigot.utils.tasks.PlayerAutoRankupTask; @@ -1094,9 +1096,10 @@ private void sellAllItemInspectCommand(CommandSender sender) { int amount = iStack.getAmount(); List lore = iStack.getLore(); + Map enchants = iStack.getEnchantments(); - String nbtInfo = iStack.getNBTItemStackInfo(); + String nbtInfo = iStack.getNBTItemStackInfo(); @@ -1105,7 +1108,7 @@ private void sellAllItemInspectCommand(CommandSender sender) { PrisonBlock sellallItem = sellAllUtil.getSellAllItems().get( nameSellall ); - boolean sellallItemAllowLore = sellallItem.isLoreAllowed(); + boolean sellallItemAllowLore = sellallItem != null && sellallItem.isLoreAllowed(); if ( sellallItem != null && iStackHasLore == sellallItemAllowLore ) { 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 d5988d3e3..c7c99176a 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 @@ -30,6 +30,7 @@ import org.bukkit.Statistic; import org.bukkit.block.Block; import org.bukkit.entity.ExperienceOrb; +import org.bukkit.inventory.meta.ItemMeta; import com.cryptomorin.xseries.XMaterial; @@ -37,6 +38,7 @@ import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; import tech.mcprison.prison.autofeatures.AutoFeaturesWrapper; import tech.mcprison.prison.autofeatures.PlayerMessaging.MessageType; +import tech.mcprison.prison.bombs.MineBombData; import tech.mcprison.prison.cache.PlayerCache; import tech.mcprison.prison.cache.PlayerCachePlayerData; import tech.mcprison.prison.file.JsonFileIO; @@ -61,6 +63,7 @@ import tech.mcprison.prison.spigot.utils.tasks.PlayerMessagingTask; import tech.mcprison.prison.util.Gamemode; import tech.mcprison.prison.util.Location; +import tech.mcprison.prison.util.Text; import tech.mcprison.prison.util.Vector; /** From 77c6a425248c3dfc6554ef891c2b5e5f8132deb9 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 3 Dec 2025 02:10:54 -0500 Subject: [PATCH 294/323] Premium Vanish: If a player is using Premium Vanish and they are vanished, then prison will reject all activity from that player and will cancel the block break event. This is to prevent a vanished player (admin) from accidentally breaking blocks in mines while vanished. --- docs/changelog_v3.3.x.md | 4 ++ .../spigot/block/OnBlockBreakMines.java | 39 +++++++++++++++++-- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 855684f70..c2382ef34 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.19i 2025-12-03 + +** 2025-09-14 ** **Premium Vanish: If a player is using Premium Vanish and they are vanished**, then prison will reject all activity from that player and will cancel the block break event. +This is to prevent a vanished player (admin) from accidentally breaking blocks in mines while vanished. + ** 2025-07-26 ** **Bug fix: Prevent an NPE when a sellallItem is null.** Generally this should not happen, but there was another bug that caused that object to be null, so this fix is just an extra insurance. 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 051beda84..e08fac72a 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 @@ -8,6 +8,7 @@ import org.bukkit.Location; import org.bukkit.block.Block; import org.bukkit.entity.Player; +import org.bukkit.metadata.MetadataValue; import tech.mcprison.prison.Prison; import tech.mcprison.prison.PrisonAPI; @@ -54,7 +55,9 @@ enum EventResultsReasons { results_passed__access_priority__player_has_access, cancel_event__access_priority__block_is_not_in_a_mine, - cancel_event__access_priority__player_has_no_access + cancel_event__access_priority__player_has_no_access, + + cancel_event__player_is_vanished ; } @@ -536,9 +539,18 @@ protected MinesEventResults ignoreMinesBlockBreakEvent( Player player, SpigotBlock sBlock = SpigotBlock.getSpigotBlock( block ); results.setSpigotBlock( sBlock ); - if ( block == null ) { + + // If player is vanished (ie PremiumVanish) then ignore all actions from player: + if ( isVanished( player ) ) { - results.setResultsReason( EventResultsReasons.cancel_event__block_is_null); + results.setResultsReason( EventResultsReasons.cancel_event__player_is_vanished ); + + results.setCancelEvent( true ); + results.setIgnoreEvent( true ); + } + else if ( block == null ) { + + results.setResultsReason( EventResultsReasons.cancel_event__block_is_null ); results.setCancelEvent( true ); results.setIgnoreEvent( true ); @@ -713,6 +725,27 @@ else if ( !ignoreBlockReuse && targetBlock.isCounted() ) { } + /** + *

Checks to see if a player is vanished when using PremiumVanish, SuperVanish, + * EssentialsX, VanishNoPacket and many more vanish plugins. + *

+ * + *

See the API for Devs section on their spigotmc.org page. + * + * Premium Vanish at spigotmc.org + * + *

+ * + * @param player + * @return + */ + private boolean isVanished(Player player) { + for (MetadataValue meta : player.getMetadata("vanished")) { + if (meta.asBoolean()) return true; + } + return false; +} + // /** // *

Warning... this is a temp copy of the real function and will be removed // * if PEExplosionEvent adds the interface Cancellable. From 7e86f0579bae0f2fb4fe093c558ed3e186256ece Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 3 Dec 2025 02:13:49 -0500 Subject: [PATCH 295/323] Mine bombs: Identify the name of the mine bomb in chat. I don't recall the significance of this addition, but there was an issue with not knowing what mine bomb was active? --- docs/changelog_v3.3.x.md | 4 ++++ .../commands/PrisonSpigotSellAllCommands.java | 20 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index c2382ef34..ea16e0781 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. +** 2025-07-26 ** **Mine bombs: Identify the name of the mine bomb in chat.** +I don't recall the significance of this addition, but there was an issue with not knowing what mine bomb was active? + + ** 2025-09-14 ** **Premium Vanish: If a player is using Premium Vanish and they are vanished**, then prison will reject all activity from that player and will cancel the block break event. This is to prevent a vanished player (admin) from accidentally breaking blocks in mines while vanished. 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 1cb4c2e88..d2791f64d 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 @@ -1205,6 +1205,26 @@ else if ( ench.getClass().getMethod( "getName" ) != null ) { } + + try { + String bombName = PrisonNBTUtil.getNBTString( iStack.getBukkitStack(), + MineBombs.MINE_BOMBS_NBT_KEY ); +// String ownerUUID = PrisonNBTUtil.getNBTString( iStack, MineBombs.MINE_BOMBS_NBT_OWNER_UUID ); + + if ( bombName != null && bombName.trim().length() == 0 ) { + bombName = null; + } + + if ( bombName != null ) { + chatDisplay.addText( " Mine Bomb Name: %s", bombName ); + + } + } + catch (Exception | Error e) { + // Ignore... not a mine bomb. + } + + if ( nbtInfo == null || nbtInfo.trim().length() == 0 ) { chatDisplay.addText( " No NBT." ); From 3f794c795300e0300873d4a048654b1370b5043e Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 3 Dec 2025 02:18:25 -0500 Subject: [PATCH 296/323] Placeholders: Bug fix (2025-04-13). When trying to access information through placeholders for an offline player, it was throwing an NPE because prison was not able to get that player object from bukkit. This bug was from a major change to try to get away from using so many calls to bukkit for a specific offline player since it's a very expensive operation because bukkit reads every player setting file until it finds the correct one. So on servers with over a few thousand players, it can contribute to a lot of lag with a few player requests. --- docs/changelog_v3.3.x.md | 5 ++++ .../PlaceHolderAPIIntegrationWrapper.java | 24 +++++++++++++++---- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index ea16e0781..bf357eaad 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -18,6 +18,11 @@ These change logs represent the work that has been going on within prison. +** 2025-04-13 ** **Placeholders: Bug fix. When trying to access information through placeholders for an offline player**, it was throwing an NPE because prison was not able to get that player object from bukkit. +This bug was from a major change to try to get away from using so many calls to bukkit for a specific offline player since it's a very expensive operation because bukkit reads every player setting file until it finds the correct one. So on servers with over a few thousand players, it can contribute to a lot of lag with a few player requests. + + + ** 2025-07-26 ** **Mine bombs: Identify the name of the mine bomb in chat.** I don't recall the significance of this addition, but there was an issue with not knowing what mine bomb was active? diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/PlaceHolderAPIIntegrationWrapper.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/PlaceHolderAPIIntegrationWrapper.java index 8c3d1a6b4..48593a814 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/PlaceHolderAPIIntegrationWrapper.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/PlaceHolderAPIIntegrationWrapper.java @@ -7,6 +7,7 @@ import me.clip.placeholderapi.expansion.PlaceholderExpansion; import tech.mcprison.prison.Prison; import tech.mcprison.prison.PrisonAPI; +import tech.mcprison.prison.output.Output; import tech.mcprison.prison.placeholders.PlaceholderManager; import tech.mcprison.prison.util.ChatColor; @@ -76,15 +77,30 @@ public String getVersion(){ */ @Override public String onRequest(OfflinePlayer player, String identifier) { + String results = null; // if ( !identifier.toLowerCase().startsWith( PlaceholderManager.PRISON_PLACEHOLDER_PREFIX_EXTENDED ) ) { // identifier = PlaceholderManager.PRISON_PLACEHOLDER_PREFIX_EXTENDED + identifier; // } - UUID playerUuid = player == null ? null : player.getUniqueId(); - String results = Prison.get().getPlatform().getPlaceholders() - .placeholderTranslate( playerUuid, player.getName(), identifier ); + if( player != null ) { + + UUID playerUuid = player.getUniqueId(); + results = Prison.get().getPlatform().getPlaceholders() + .placeholderTranslate( playerUuid, player.getName(), identifier ); + + results = ChatColor.translateAlternateColorCodes( '&', results); + } + else if ( Output.get().isDebug() ) { + String msg = String.format( + "PlacefolderAPIIntegrationWrapper.onRequest: OfflinePlayer is null. Prison is " + + "receving a null value for the OfflinePlayer from PAI for the following " + + "placeholder: [\\Q%s\\E]", + identifier + ); + Output.get().logInfo( msg ); + } - return ChatColor.translateAlternateColorCodes( '&', results); + return results; } } From 1c7f7216559a2b2fa4af65f4a7810c3cd9ca52bd Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 3 Dec 2025 02:27:34 -0500 Subject: [PATCH 297/323] Spigot 1.21.10 support added. The addition of this new version has resulted in new blocks that are not recognized by the version of XSeries that prison is using. Could not upgrade Xseries about 6+ months ago due to breaking changes that were causing failures with spigot 1.8 and a few other old releases. These changes just ignores the unknown blocks, since prison would not be able to use them anyway. Not sure how to deal with XSeries, but may have to split the builds. There were also issues with building the sub-project prison-misc so that sub project was disabled since it's not directly being used. The issue is that there is a resource in that project that is depending upon a specific library which is part of the bukkit 1.13.2 build, but it's using the repo from spigotmc. Will address this later, when needed. --- .gitignore | 1 + docs/changelog_v3.3.x.md | 6 +++ gradle/libs.versions.toml | 4 +- prison-misc/build.gradle | 21 +++++----- .../spigot/compat/Spigot_1_13_Blocks.java | 42 ++++++++++++------- settings.gradle | 3 +- 6 files changed, 49 insertions(+), 28 deletions(-) diff --git a/.gitignore b/.gitignore index 57cc6bdb7..f8bdf1c19 100644 --- a/.gitignore +++ b/.gitignore @@ -138,3 +138,4 @@ gradle-app.setting build.gradle.deploy prison-spigot/lib/old/ +prison-spigot/lib/disabled/ diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index bf357eaad..543e246d4 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.19i 2025-12-03 +**Spigot 1.21.10 support added. The addition of this new version has resulted in new blocks that are not recognized by the version of XSeries that prison is using.** +Could not upgrade Xseries about 6+ months ago due to breaking changes that were causing failures with spigot 1.8 and a few other old releases. These changes just ignores the unknown blocks, since prison would not be able to use them anyway. +Not sure how to deal with XSeries, but may have to split the builds. +There were also issues with building the sub-project prison-misc so that sub project was disabled since it's not directly being used. The issue is that there is a resource in that project that is depending upon a specific library which is part of the bukkit 1.13.2 build, but it's using the repo from spigotmc. Will address this later, when needed. + + ** 2025-04-13 ** **Placeholders: Bug fix. When trying to access information through placeholders for an offline player**, it was throwing an NPE because prison was not able to get that player object from bukkit. This bug was from a major change to try to get away from using so many calls to bukkit for a specific offline player since it's a very expensive operation because bukkit reads every player setting file until it finds the correct one. So on servers with over a few thousand players, it can contribute to a lot of lag with a few player requests. diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 8df8568ea..ace9260be 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -39,7 +39,9 @@ junit = "4.12" guava = "31.1-jre" spigotApi = "1.13.2-R0.1-SNAPSHOT" -nbtApi = "2.14.1" +nbtApi = "2.15.3" +#nbtApi = "2.15.0" +#nbtApi = "2.14.1" papi = "2.11.6" vault = "1.7.1" diff --git a/prison-misc/build.gradle b/prison-misc/build.gradle index af3456755..0cecdc7b7 100644 --- a/prison-misc/build.gradle +++ b/prison-misc/build.gradle @@ -41,16 +41,16 @@ java { repositories { - maven { - url = 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/' +// 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' - } - } +// content { +// includeGroup 'org.bukkit' +// includeGroup 'org.spigotmc' +// } +// } /* @@ -62,8 +62,8 @@ repositories { 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' } + //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 { @@ -89,7 +89,8 @@ dependencies { implementation 'org.jetbrains:annotations:24.0.1' - compileOnly 'org.spigotmc:spigot-api:1.13.2-R0.1-SNAPSHOT' +// compileOnly 'org.spigotmc:spigot-api:1.13.2-R0.1-SNAPSHOT' + compileOnly( libs.spigotApi ) testImplementation group: 'junit', name: 'junit', version: '4.12' diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_13_Blocks.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_13_Blocks.java index d47d1c1ee..ad88f4723 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_13_Blocks.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_13_Blocks.java @@ -96,25 +96,35 @@ public XMaterial getXMaterial( Block spigotBlock ) { results = getCachedXMaterial( spigotBlock, NO_DATA_VALUE ); if ( results == null ) { - results = XMaterial.matchXMaterial( spigotBlock.getType() ); - - if ( results == null ) { - results = XMaterial.matchXMaterial( spigotBlock.getType().name() ).orElse( null ); - } - - if ( results == null ) { + try { + results = XMaterial.matchXMaterial( spigotBlock.getType() ); - Output.get().logWarn( "Spigot113Blocks.getXMaterial() : " + - "Spigot block cannot be mapped to a XMaterial : " + - spigotBlock.getType().name() + - " SpigotBlock = " + ( spigotBlock == null ? "null" : - spigotBlock.getType().name())); - } + if ( results == null ) { + results = XMaterial.matchXMaterial( spigotBlock.getType().name() ).orElse( null ); + } + + if ( results == null ) { + + Output.get().logWarn( "Spigot113Blocks.getXMaterial() : " + + "Spigot block cannot be mapped to a XMaterial : " + + spigotBlock.getType().name() + + " SpigotBlock = " + ( spigotBlock == null ? "null" : + spigotBlock.getType().name())); + } - - if ( results != null ) { - putCachedXMaterial( spigotBlock, NO_DATA_VALUE, results ); + if ( results != null ) { + + putCachedXMaterial( spigotBlock, NO_DATA_VALUE, results ); + } + } + catch ( IllegalArgumentException e) { + // xMaterial does not support this material type. + + // Add this bad spigotBlock to the cache with a NULL_TOKEN + // so it will not try to map it again: + + putCachedXMaterial( spigotBlock, NO_DATA_VALUE, NULL_TOKEN ); } } } diff --git a/settings.gradle b/settings.gradle index 2a3209af7..4c04b99d2 100644 --- a/settings.gradle +++ b/settings.gradle @@ -41,6 +41,7 @@ dependencyResolutionManagement { content { includeGroup 'org.spigotmc' includeGroup 'org.bukkit' + includeGroup 'net.md-5' } } @@ -88,7 +89,7 @@ include 'prison-mines' include 'prison-ranks' include 'prison-sellall' -include 'prison-misc' +//include 'prison-misc' include 'prison-worldguard6' include 'prison-worldguard7' From 31ebbefe0967041265f5f550c1698c481ba342bb Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 24 Feb 2026 23:21:48 -0500 Subject: [PATCH 298/323] 2026-02-23 Upgrade item-nbt-api to v2.15.5 so it can support spigot 1.21.11. --- docs/changelog_v3.3.x.md | 9 ++++++++- gradle/libs.versions.toml | 3 ++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 543e246d4..1d7f60dd9 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.19i 2025-12-03 +# 3.3.0-alpha.19j 2026-02-24 + + + + + +* **2026-02-23 Upgrade item-nbt-api to v2.15.5 so it can support spigot 1.21.11.** + **Spigot 1.21.10 support added. The addition of this new version has resulted in new blocks that are not recognized by the version of XSeries that prison is using.** diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ace9260be..0dab929fd 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -39,7 +39,8 @@ junit = "4.12" guava = "31.1-jre" spigotApi = "1.13.2-R0.1-SNAPSHOT" -nbtApi = "2.15.3" +nbtApi = "2.15.5" +#nbtApi = "2.15.3" #nbtApi = "2.15.0" #nbtApi = "2.14.1" papi = "2.11.6" From a2a73512a66d631197c3db8a23c5c38fe6be4b24 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 24 Feb 2026 23:25:50 -0500 Subject: [PATCH 299/323] ug fixes: There were some issues with a mine existing in the world that has not been reset, and as such, it had block types that XSeries did not recognize when running spigot 1.21.11. These fixes prevents prison from crashing and is able to perform a mine reset so they can be replaced with known blocks. Better logging messages when something goes wrong with the air-counts. Also, prevent an error in one mine from being displayed for all remaining mines. --- docs/changelog_v3.3.x.md | 17 +++++++ .../tech/mcprison/prison/util/Location.java | 50 ++++++++++++++----- .../mcprison/prison/mines/data/MineReset.java | 38 ++++++++++---- ...StartupRefreshBlockBreakCountSyncTask.java | 37 ++++++++++++-- .../spigot/compat/Spigot_1_8_Blocks.java | 49 ++++++++++++++++-- 5 files changed, 160 insertions(+), 31 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 1d7f60dd9..c59e7010d 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -18,6 +18,23 @@ These change logs represent the work that has been going on within prison. + +2026-02-23 Upgrade item-nbt-api to v2.15.5 so it can support spigot 1.21.11. +v3.3.0-alpha.19j 2025-12-10 + +* **Bug fixes: There were some issues with a mine existing in the world that has not been reset, and as such, it had block types that XSeries did not recognize when running spigot 1.21.11.** These fixes prevents prison from crashing and is able to perform a mine reset so they can be replaced with known blocks. + + +* **Better logging messages when something goes wrong with the air-counts.** Also, prevent an error in one mine from being displayed for all remaining mines. + + +* **2026-02-24 Major cross roads: Spigot 1.21.11 requires XSeries v13.6.0, but prison is stuck at v11.3.0 due to support for spigot 1.8.** + - To move forward, I'm going to split prison in to a legacy build and a modern build. So the build will create two artifacts. The source code will remain the same for both, but it will be different java versions it will be compiled with, and different versions of libraries. Java 1.8's builds will be locked in to some plugin versions that cannot change, such as XSeries v11.3.0. Others will be able to be upgraded and use the latest. + - XSeries (block control within prison) will have to be spit... Spigot 1.8 cannot use any version newer than v11.3.0. + - Java: The legacy build will continue to be built with java 1.8. But the modern build may use java 21. I will have to figure out what is ideal, and what other libraries are using. + - Since the source will be identical, legacy builds should still get bug fixes and new enhancements. + - Along with this change, I'm wanting to retire the v3.x.x and release v4.0.0. There are a few core things that will change with the v4.0.0 release. + * **2026-02-23 Upgrade item-nbt-api to v2.15.5 so it can support spigot 1.21.11.** 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 31e3911be..31b9c2138 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 @@ -325,7 +325,12 @@ public String toString() { } /** - * Returns the values in coordinate (x, y, z) format. + *

Returns the values in coordinate '(x, y, z)' format. + * Uses doubles with no rounding. Has spaces after the commas. + *

+ * + *

Example: (-15.1, 35.666667, 124.000325) + *

* * @return The {@link String} containing coordinates. */ @@ -333,24 +338,45 @@ public String toCoordinates() { return "(" + x + ", " + y + ", " + z + ")"; } - + /** + *

Returns the values in coordinate '(worldName, x, y, z)' format. + * Uses only the integer part of the doubles with no rounding. Has spaces after the commas. + *

+ * + *

Example: (PrisonWorld, -15, 35, 124) + *

+ * @return + */ public String toWorldCoordinates() { - return "(" + world.getName() + "," + ((int) x) + "," + ((int) y) + "," + ((int) z) + ")"; + return "(" + world.getName() + "," + ((int) x) + "," + ((int) y) + "," + ((int) z) + ")"; } + /** + *

Using a String value of the WorldCoordinates, decodes the string value + * to a Location object. + *

+ * + * @param worldCoordinats such as '(PrisonWorld, -15, 35, 124)' + * @return + */ public static Location decodeWorldCoordinates( String worldCoordinats ) { - Location results = null; - String[] d = worldCoordinats.replaceAll( "\\(|\\)", "" ).split( "," ); - - if ( d != null && d.length == 4 ) { - results = new Location( d[0], Integer.parseInt( d[1] ), Integer.parseInt( d[2] ), Integer.parseInt( d[3] ) ); - } - return results; + Location results = null; + String[] d = worldCoordinats.replaceAll( "\\(|\\)", "" ).split( "," ); + + if ( d != null && d.length == 4 ) { + results = new Location( d[0], Integer.parseInt( d[1] ), Integer.parseInt( d[2] ), Integer.parseInt( d[3] ) ); + } + return results; } /** - * Returns the values in coordinate (x, y, z) format, to the nearest block (i.e. no decimals). - * + *

Returns the values in coordinate '(x, y, z)' format, to the nearest + * block (i.e. no decimals, rounded, spaces after commas). + *

+ * + *

Example: (-15, 35, 124) + *

+ * * @return The {@link String} containing coordinates. */ public String toBlockCoordinates() { 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 94c963411..d021e15b1 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 @@ -91,8 +91,9 @@ public abstract class MineReset public static final long MINE_RESET__PAGE_TIMEOUT_CHECK__BLOCK_COUNT = 250; - public static final long MINE_RESET__AIR_COUNT_BASE_DELAY_TICKS = 6 * 20L; // 6 seconds - public static final long MINE_RESET__AIR_COUNT_SUBMIT_GAP_TICKS = 5; // 0.25 second + // NOTE: Longer delay on air counts will not prevent the "server is running behind" messages. + public static final long MINE_RESET__AIR_COUNT_BASE_DELAY_TICKS = 10 * 20L; // 10 seconds + public static final long MINE_RESET__AIR_COUNT_SUBMIT_GAP_TICKS = 10; // 10 ticks == 0.5 second private transient List mineTargetPrisonBlocks = null; @@ -1746,6 +1747,8 @@ public void refreshAirCountSyncTaskSetLocation( Location targetLocation, } } catch ( Exception e ) { + String msg = e.getMessage(); + stats.incrementErrorCount(); // Updates to the "world" should never be ran async. Upon review of the above @@ -1754,19 +1757,36 @@ public void refreshAirCountSyncTaskSetLocation( Location targetLocation, // java.lang.IllegalStateException: Asynchronous entity world add! // If there are no entities, it will be fine, but they could cause issues with async // access of unloaded chunks. - String coords = String.format( "%d.%d.%d ", - targetLocation.getBlockX(), targetLocation.getBlockY(), targetLocation.getBlockZ() ); +// String coords = String.format( "%d.%d.%d ", +// targetLocation.getBlockX(), targetLocation.getBlockY(), targetLocation.getBlockZ() ); + + String coords = targetLocation.toBlockCoordinates(); + + if ( stats.getExceptionError() == null ) { + + stats.setExceptionError( msg ); + + StackTraceElement[] stackTrace = e.getStackTrace(); + + // print only the first 6 lines of the stack trace: + for (int i = 0; i < stackTrace.length && i <= 9; i++) { + StackTraceElement stEle = stackTrace[i]; + Output.get().logWarn( "*#* " + stEle.toString()); + } + } if ( stats.getErrorCount() == 0 ) { + // Error count is 0, so setup the messages: String message = String.format( "MineReset.refreshAirCountAsyncTask: Error counting air blocks: " + - "Mine=%s coords=%s Error: %s ", getName(), coords, e.getMessage() ); + "Mine=%s coords=%s Error: [%s] ", getName(), coords, msg ); - if ( e.getMessage() != null && e.getMessage().contains( "Asynchronous entity world add" )) { - Output.get().logWarn( message, e ); - } else { + if ( msg != null && msg.contains( "Asynchronous entity world add" )) { Output.get().logWarn( message, e ); - } + } +// else { +// Output.get().logWarn( message, e ); +// } } else if ( stats.getErrorCount() <= 10 ) { diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/OnStartupRefreshBlockBreakCountSyncTask.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/OnStartupRefreshBlockBreakCountSyncTask.java index 81e6cdb30..c9f048390 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/OnStartupRefreshBlockBreakCountSyncTask.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/OnStartupRefreshBlockBreakCountSyncTask.java @@ -34,6 +34,7 @@ public class OnStartupRefreshBlockBreakCountSyncTask private int errorCount = 0; private StringBuilder sbErrors = new StringBuilder(); + private String exceptionError; private List processedMines; @@ -96,6 +97,11 @@ private Mine getNextMine() { countTotalMines = mines.size(); } + // When the server starts, all mines will have a resetCount of zero. + // So to get the "nextMine", just need to go through the list of all mines + // and grab the first one that is zero. Then set the resetCount on the + // selected mine to 1 so it will not be chosen again. And then return + // the selected mine. for (Mine m : mines ) { // Check to see if we can even submit the job: @@ -120,6 +126,9 @@ private Mine getNextMine() { } } + // If no mine has been selected, then that means all mines were + // processed, so perform the ending tasks of printing out the + // list of mines that could not be processed and the totals message. if ( mine == null ) { // done processing: @@ -262,13 +271,14 @@ public void run() { mine.setAirCountElapsedTimeMs( (long) elapsedMs ); mine.setAirCountTimestamp( System.currentTimeMillis() ); - if ( Output.get().isDebug() ) { +// if ( Output.get().isDebug() ) + { DecimalFormat dFmt = Prison.get().getDecimalFormatDouble(); DecimalFormat iFmt = Prison.get().getDecimalFormatInt(); String message = String.format( "MineReset startup air-count: Mine [%3d of %3d]: %-10s " + - " blocks: %10s pages: [%3s: %3s] [%9s: %9s ms]", + " blocks: %10s pages: [%3s: %3s] [%9s: %9s ms] <%b>", countCurrentMine, countTotalMines, mine.getName(), @@ -276,7 +286,8 @@ public void run() { iFmt.format( pages - pagesStart ), iFmt.format( pages ), dFmt.format(elapsedMs), - dFmt.format(elapsedMsTotal) + dFmt.format(elapsedMsTotal), + Output.get().isDebug() ); Output.get().logInfo( message ); @@ -286,11 +297,20 @@ public void run() { if ( getErrorCount() > 0 ) { String message = String.format( "MineReset.refreshAirCountAsyncTask: Error counting air blocks: Mine=%s: " + - "errorCount=%d blocks: %s : %s", mine.getName(), getErrorCount(), + "errorCount=%d blocks: %s : %s ExcptError: [%s]", + mine.getName(), getErrorCount(), (getErrorCount() > 20 ? "(first 20)" : ""), - getSbErrors().toString() ); + getSbErrors().toString(), + (getExceptionError() == null ? "" : getExceptionError()) + ); Output.get().logWarn( message ); + + + // Since the error has beep logged, reset it. + setExceptionError( null ); + getSbErrors().setLength( 0 ); + setErrorCount( 0 ); } // Finalize by setting mine and locations to null so it will reset properly the next time: @@ -350,4 +370,11 @@ public StringBuilder getSbErrors() { public void setSbErrors( StringBuilder sbErrors ) { this.sbErrors = sbErrors; } + + protected String getExceptionError() { + return exceptionError; + } + protected void setExceptionError(String exceptionError) { + this.exceptionError = exceptionError; + } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_8_Blocks.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_8_Blocks.java index fd9532537..9b5854229 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_8_Blocks.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_8_Blocks.java @@ -205,6 +205,25 @@ public SpigotBlock getSpigotBlock( Block bukkitBlock ) { // return xMat; // } + /** + *

This will take a given block and return the XMaterial object for it. + *

+ * + *

But please keep in mind that just because the block is in a mine, that the + * blocks may not belong in the mine. Matter of fact, this may be the situation + * when creating a new mine in a new world, or moving a mine. I mention this + * fact, because even though the list of blocks for a mine may be very constrained + * ( 'mines block list f') that it may actually contain blocks outside of that + * list. This actually becomes a problem when older versions of XSeries does + * not support that block (ie... updated to new spigot or paper version) and + * therefore XSeries cannot match to one of it's block types. + * This may not be a problem, because the mine may not have been reset yet. + * Resetting the mine will purge those unknown block types. + * Or at least, we can just ignore them since they are not blocks we are + * trying to track. + *

+ * + */ @SuppressWarnings( "deprecation" ) @Override public XMaterial getXMaterial( Block spigotBlock ) { @@ -228,18 +247,38 @@ public XMaterial getXMaterial( Block spigotBlock ) { if ( results == null ) { // Last chance: try to match by id: - int id = spigotBlock.getType().getId(); - - results = matchXMaterial( id, data ); + // WARNING: This will not work with "modern material". So if this + // throws an exception when trying to get the ID, then just + // ignore it since results will be null and it will try to + // match by MaterialType and then by name. + try { + int id = spigotBlock.getType().getId(); + + results = matchXMaterial( id, data ); // results = XMaterial.matchXMaterial( id, data ).orElse( null ); + } + catch (Exception e) { + // Ignore this exception and allow it to find a match by + // other means... + } } if ( results == null ) { - results = XMaterial.matchXMaterial(spigotBlock.getType()); + try { + results = XMaterial.matchXMaterial(spigotBlock.getType()); + } + catch (Exception e) { + // Ignore and let next test try it... + } } if ( results == null ) { - results = XMaterial.matchXMaterial( spigotBlock.getType().name() ).orElse( null ); + try { + results = XMaterial.matchXMaterial( spigotBlock.getType().name() ).orElse( null ); + } + catch (Exception e) { + // Ignore and let the next test try it... + } } if ( results == null ) { From 5ca76dd09ad19b2db20515e090794a719b212a23 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 24 Feb 2026 23:26:50 -0500 Subject: [PATCH 300/323] 2026-02-23 Upgrade item-nbt-api to v2.15.5 so it can support spigot 1.21.11. v3.3.0-alpha.19j 2025-12-10 --- docs/changelog_v3.3.x.md | 5 +++-- gradle.properties | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index c59e7010d..4f1542ca0 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -18,9 +18,10 @@ These change logs represent the work that has been going on within prison. +** v3.3.0-alpha.19j 2025-12-10** + + -2026-02-23 Upgrade item-nbt-api to v2.15.5 so it can support spigot 1.21.11. -v3.3.0-alpha.19j 2025-12-10 * **Bug fixes: There were some issues with a mine existing in the world that has not been reset, and as such, it had block types that XSeries did not recognize when running spigot 1.21.11.** These fixes prevents prison from crashing and is able to perform a mine reset so they can be replaced with known blocks. diff --git a/gradle.properties b/gradle.properties index c0c1bc1d1..8b1dee0e6 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.19i +version=3.3.0-alpha.19j From 9b2a8b1add3dd2b4d6f227a751c07618b8fdf182 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 4 Mar 2026 20:49:48 -0500 Subject: [PATCH 301/323] General cleanup: these are works in progress (wip) that have not been finalized. If it's source, its been moved to a package with .wip.in the name. These may be deleted in the future or they could be used. --- PrisonSpigotMC/index.html | 79 ++ docs/changelog_v3.3.x.md | 6 +- .../module_conf/mines/mineBombsConfig.json | 1253 +++++++++++++++++ .../wip/internal/heads/MinecraftHeadData.java | 76 + .../internal/heads/MinecraftHeadsCache.java | 196 +++ .../discord/PrisonSupportFileLinkageTest.java | 53 + .../wip/tasks/PrisonCommandTaskDataTest.java | 70 + .../mines/wip/data/MineBlockConstraints.java | 5 + .../prison/mines/wip/data/MineQuestData.java | 33 + .../sellall/wip/data/SellallItemData.java | 39 + .../prison/sellall/wip/data/ShopData.java | 63 + .../prison/sellall/wip/data/ShopItemData.java | 36 + .../prison/spigot/tasks/SampleTask.java | 58 + .../src/main/resources/config_sample.yml | 115 ++ .../tech/mcprison/prison/spigot/Test.java | 35 + .../spigot/block/SpigotItemStackTest.java | 42 + 16 files changed, 2158 insertions(+), 1 deletion(-) create mode 100644 PrisonSpigotMC/index.html create mode 100644 prison-core/module_conf/mines/mineBombsConfig.json create mode 100644 prison-core/src/main/java/tech/mcprison/prison/wip/internal/heads/MinecraftHeadData.java create mode 100644 prison-core/src/main/java/tech/mcprison/prison/wip/internal/heads/MinecraftHeadsCache.java create mode 100644 prison-core/src/test/java/tech/mcprison/prison/wip/discord/PrisonSupportFileLinkageTest.java create mode 100644 prison-core/src/test/java/tech/mcprison/prison/wip/tasks/PrisonCommandTaskDataTest.java create mode 100644 prison-mines/src/main/java/tech/mcprison/prison/mines/wip/data/MineBlockConstraints.java create mode 100644 prison-mines/src/main/java/tech/mcprison/prison/mines/wip/data/MineQuestData.java create mode 100644 prison-sellall/src/main/java/tech/mcprison/prison/sellall/wip/data/SellallItemData.java create mode 100644 prison-sellall/src/main/java/tech/mcprison/prison/sellall/wip/data/ShopData.java create mode 100644 prison-sellall/src/main/java/tech/mcprison/prison/sellall/wip/data/ShopItemData.java create mode 100644 prison-spigot/src/main/java/tech/mcprison/prison/spigot/tasks/SampleTask.java create mode 100644 prison-spigot/src/main/resources/config_sample.yml create mode 100644 prison-spigot/src/test/java/tech/mcprison/prison/spigot/Test.java create mode 100644 prison-spigot/src/test/java/tech/mcprison/prison/spigot/block/SpigotItemStackTest.java diff --git a/PrisonSpigotMC/index.html b/PrisonSpigotMC/index.html new file mode 100644 index 000000000..c23eaf0a6 --- /dev/null +++ b/PrisonSpigotMC/index.html @@ -0,0 +1,79 @@ + + + + + + + Prison - Test Document Titles + + + + + +
+ + + + + PRISON + + + +
+ +
+ +
+
+ +
+ + \ No newline at end of file diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 4f1542ca0..63c9eed43 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.19j 2026-02-24 +# 3.3.0-alpha.19j 2026-03-04 + + + +* **General cleanup: these are works in progress (wip) that have not been finalized.** If it's source, its been moved to a package with .wip.in the name. These may be deleted in the future or they could be used. diff --git a/prison-core/module_conf/mines/mineBombsConfig.json b/prison-core/module_conf/mines/mineBombsConfig.json new file mode 100644 index 000000000..166b714fb --- /dev/null +++ b/prison-core/module_conf/mines/mineBombsConfig.json @@ -0,0 +1,1253 @@ +{ + "dataFormatVersion": 3, + "bombs": { + "bouncebomb": { + "name": "BounceBomb", + "description": "This old bomb is a dud.&r", + "lore": [ + "This is a bomb?&r" + ], + "nameTag": "&a-=- &4{countdown} &5-=- &7{name} &5-=- &4{countdown} &a-=-&r", + "itemName": "&c-= &7{name}&c =-", + "itemType": "IRON_INGOT", + "radius": 2, + "radiusInner": 0, + "height": 0, + "placementAdjustmentY": 0, + "removalChance": 50.0, + "explosionShape": "sphere", + "toolInHandName": "STONE_PICKAXE", + "toolInHandFortuneLevel": 1, + "toolInHandDurabilityLevel": 0, + "toolInHandDigSpeedLevel": 0, + "fuseDelayTicks": 300, + "cooldownTicks": 20, + "itemRemovalDelayTicks": 5, + "animationPattern": "bounce", + "animationOffset": 0.0, + "animationSpeed": 10.0, + "animationRadius": 1.0, + "animationRadiusDelta": 0.0, + "animationAlternateDirections": false, + "animationSpinSpeed": -35.0, + "animationArmorStandItemLocation": "hand", + "throwVelocityLow": 0.25, + "throwVelocityHigh": 1.5, + "glowing": false, + "gravity": true, + "autosell": false, + "customModelData": 0, + "allowedMines": [], + "preventedMines": [], + "applyToPlayersBlockCount": true, + "small": false, + "soundEffects": [ + { + "effectType": "sounds", + "effectName": "ENTITY_CREEPER_PRIMED", + "effectState": "placed", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "sounds", + "effectName": "CAT_HISS", + "effectState": "placed", + "offsetTicks": 30, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "sounds", + "effectName": "ENTITY_GENERIC_EXPLODE", + "effectState": "explode", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + } + ], + "visualEffects": [ + { + "effectType": "visuals", + "effectName": "FLAME", + "effectState": "placed", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "visuals", + "effectName": "BUBBLE_COLUMN_UP", + "effectState": "placed", + "offsetTicks": 30, + "volumne": 1.0, + "pitch": 1.0 + } + ] + }, + "cubebomb": { + "name": "CubeBomb", + "description": "The most anti-round bomb you will ever be able to find. It's totally cubic.&r", + "lore": [ + "A Cubic Bomb&r" + ], + "nameTag": "&a-=- &7{name}&a -=--&r", + "itemName": "&c-= &7{name}&c =-", + "itemType": "SLIME_BALL", + "radius": 2, + "radiusInner": 0, + "height": 0, + "placementAdjustmentY": 0, + "removalChance": 100.0, + "explosionShape": "cube", + "toolInHandName": "DIAMOND_PICKAXE", + "toolInHandFortuneLevel": 7, + "toolInHandDurabilityLevel": 0, + "toolInHandDigSpeedLevel": 0, + "fuseDelayTicks": 300, + "cooldownTicks": 20, + "itemRemovalDelayTicks": 5, + "animationPattern": "orbital", + "animationOffset": 0.0, + "animationSpeed": 10.0, + "animationRadius": 1.0, + "animationRadiusDelta": 0.0, + "animationAlternateDirections": false, + "animationSpinSpeed": -35.0, + "animationArmorStandItemLocation": "head", + "throwVelocityLow": 1.5, + "throwVelocityHigh": 3.0, + "glowing": true, + "gravity": true, + "autosell": false, + "customModelData": 0, + "allowedMines": [], + "preventedMines": [], + "applyToPlayersBlockCount": true, + "small": false, + "soundEffects": [ + { + "effectType": "sounds", + "effectName": "ENTITY_CREEPER_PRIMED", + "effectState": "placed", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "sounds", + "effectName": "CAT_HISS", + "effectState": "placed", + "offsetTicks": 30, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "sounds", + "effectName": "ENTITY_GENERIC_EXPLODE", + "effectState": "explode", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + } + ], + "visualEffects": [ + { + "effectType": "visuals", + "effectName": "FLAME", + "effectState": "placed", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "visuals", + "effectName": "BUBBLE_COLUMN_UP", + "effectState": "placed", + "offsetTicks": 30, + "volumne": 1.0, + "pitch": 1.0 + } + ] + }, + "largebomb": { + "name": "LargeBomb", + "description": "A large mine bomb made from TNT with some strange parts that maybe be described as alien technology.&r", + "lore": [ + "Large Mine Bomb" + ], + "nameTag": "&a-=- &7{name}&a -=--&r", + "itemName": "&c-= &7{name}&c =-", + "itemType": "tnt", + "radius": 12, + "radiusInner": 3, + "height": 0, + "placementAdjustmentY": 0, + "removalChance": 100.0, + "explosionShape": "sphereHollow", + "toolInHandName": "DIAMOND_PICKAXE", + "toolInHandFortuneLevel": 3, + "toolInHandDurabilityLevel": 0, + "toolInHandDigSpeedLevel": 0, + "fuseDelayTicks": 100, + "cooldownTicks": 60, + "itemRemovalDelayTicks": 5, + "animationPattern": "infinity", + "animationOffset": 0.0, + "animationSpeed": 10.0, + "animationRadius": 1.0, + "animationRadiusDelta": 0.0, + "animationAlternateDirections": false, + "animationSpinSpeed": -35.0, + "animationArmorStandItemLocation": "hand", + "throwVelocityLow": 1.5, + "throwVelocityHigh": 3.0, + "glowing": false, + "gravity": true, + "autosell": false, + "customModelData": 0, + "allowedMines": [], + "preventedMines": [], + "applyToPlayersBlockCount": true, + "small": false, + "soundEffects": [ + { + "effectType": "sounds", + "effectName": "ENTITY_CREEPER_PRIMED", + "effectState": "placed", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "sounds", + "effectName": "CAT_HISS", + "effectState": "placed", + "offsetTicks": 30, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "sounds", + "effectName": "ENTITY_GENERIC_EXPLODE", + "effectState": "explode", + "offsetTicks": 0, + "volumne": 2.0, + "pitch": 1.0 + } + ], + "visualEffects": [ + { + "effectType": "visuals", + "effectName": "FLAME", + "effectState": "placed", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "visuals", + "effectName": "SMOKE", + "effectState": "placed", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "visuals", + "effectName": "SMOKE_NORMAL", + "effectState": "placed", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "visuals", + "effectName": "ENCHANTMENT_TABLE", + "effectState": "placed", + "offsetTicks": 30, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "visuals", + "effectName": "EXPLOSION_NORMAL", + "effectState": "explode", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + } + ] + }, + "mediumbomb": { + "name": "MediumBomb", + "description": "A medium mine bomb made from leftover fireworks, &rbut supercharged with a strange green glowing liquid.&r", + "lore": [ + "Medium Mine Bomb&r" + ], + "nameTag": "&6&k1 23 456&r&a-=- &7{name}&a -=-&6&k654 32 1&r", + "itemName": "&c-= &7{name}&c =-", + "itemType": "firework_rocket", + "radius": 5, + "radiusInner": 0, + "height": 0, + "placementAdjustmentY": 0, + "removalChance": 100.0, + "explosionShape": "sphere", + "toolInHandName": "DIAMOND_PICKAXE", + "toolInHandFortuneLevel": 3, + "toolInHandDurabilityLevel": 0, + "toolInHandDigSpeedLevel": 0, + "fuseDelayTicks": 100, + "cooldownTicks": 60, + "itemRemovalDelayTicks": 5, + "animationPattern": "infinity", + "animationOffset": 0.0, + "animationSpeed": 10.0, + "animationRadius": 1.0, + "animationRadiusDelta": 0.0, + "animationAlternateDirections": false, + "animationSpinSpeed": -35.0, + "animationArmorStandItemLocation": "hand", + "throwVelocityLow": 1.5, + "throwVelocityHigh": 3.0, + "glowing": false, + "gravity": true, + "autosell": false, + "customModelData": 0, + "allowedMines": [], + "preventedMines": [], + "applyToPlayersBlockCount": true, + "small": false, + "soundEffects": [ + { + "effectType": "sounds", + "effectName": "ENTITY_CREEPER_PRIMED", + "effectState": "placed", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "sounds", + "effectName": "CAT_HISS", + "effectState": "placed", + "offsetTicks": 30, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "sounds", + "effectName": "ENTITY_GENERIC_EXPLODE", + "effectState": "explode", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + } + ], + "visualEffects": [ + { + "effectType": "visuals", + "effectName": "FLAME", + "effectState": "placed", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "visuals", + "effectName": "SMOKE_NORMAL", + "effectState": "placed", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "visuals", + "effectName": "ENCHANTMENT_TABLE", + "effectState": "placed", + "offsetTicks": 30, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "visuals", + "effectName": "EXPLOSION_NORMAL", + "effectState": "explode", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + } + ] + }, + "nonebomb": { + "name": "NoneBomb", + "description": "This old bomb is a dud.&r", + "lore": [ + "This is a bomb?&r" + ], + "nameTag": "&a-=- &4{countdown} &5-=- &7{name} &5-=- &4{countdown} &a-=-&r", + "itemName": "&c-= &7{name}&c =-", + "itemType": "COAL", + "radius": 2, + "radiusInner": 0, + "height": 0, + "placementAdjustmentY": 0, + "removalChance": 25.0, + "explosionShape": "sphere", + "toolInHandName": "STONE_PICKAXE", + "toolInHandFortuneLevel": 1, + "toolInHandDurabilityLevel": 0, + "toolInHandDigSpeedLevel": 0, + "fuseDelayTicks": 300, + "cooldownTicks": 20, + "itemRemovalDelayTicks": 5, + "animationPattern": "none", + "animationOffset": 0.0, + "animationSpeed": 10.0, + "animationRadius": 1.0, + "animationRadiusDelta": 0.0, + "animationAlternateDirections": false, + "animationSpinSpeed": -35.0, + "animationArmorStandItemLocation": "hand", + "throwVelocityLow": 0.25, + "throwVelocityHigh": 3.5, + "glowing": false, + "gravity": true, + "autosell": false, + "customModelData": 0, + "allowedMines": [], + "preventedMines": [], + "applyToPlayersBlockCount": true, + "small": false, + "soundEffects": [ + { + "effectType": "sounds", + "effectName": "ENTITY_CREEPER_PRIMED", + "effectState": "placed", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "sounds", + "effectName": "CAT_HISS", + "effectState": "placed", + "offsetTicks": 30, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "sounds", + "effectName": "ENTITY_GENERIC_EXPLODE", + "effectState": "explode", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + } + ], + "visualEffects": [ + { + "effectType": "visuals", + "effectName": "FLAME", + "effectState": "placed", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "visuals", + "effectName": "BUBBLE_COLUMN_UP", + "effectState": "placed", + "offsetTicks": 30, + "volumne": 1.0, + "pitch": 1.0 + } + ] + }, + "oofbomb": { + "name": "OofBomb", + "description": "An oof-ably large mine bomb made with a minecart heaping with TNT. Unlike the large mine bomb, this one obviously is built with alien technology.&r", + "lore": [ + "Oof Mine Bomb&r" + ], + "nameTag": "&c&k1&6&k23&e&k456&r&a-=- &4{countdown} &5-=- &7{name} &5-=- &4{countdown} &a-=-&e&k654&6&k32&c&k1&r", + "itemName": "&c-= &7{name}&c =-", + "itemType": "tnt_minecart", + "radius": 21, + "radiusInner": 3, + "height": 0, + "placementAdjustmentY": 0, + "removalChance": 100.0, + "explosionShape": "sphereHollow", + "toolInHandName": "GOLDEN_PICKAXE", + "toolInHandFortuneLevel": 13, + "toolInHandDurabilityLevel": 0, + "toolInHandDigSpeedLevel": 0, + "fuseDelayTicks": 260, + "cooldownTicks": 60, + "itemRemovalDelayTicks": 5, + "animationPattern": "infinity", + "animationOffset": 0.0, + "animationSpeed": 10.0, + "animationRadius": 1.0, + "animationRadiusDelta": 0.0, + "animationAlternateDirections": false, + "animationSpinSpeed": -35.0, + "animationArmorStandItemLocation": "hand", + "throwVelocityLow": 1.5, + "throwVelocityHigh": 3.0, + "glowing": true, + "gravity": true, + "autosell": true, + "customModelData": 0, + "allowedMines": [], + "preventedMines": [], + "applyToPlayersBlockCount": true, + "small": false, + "soundEffects": [ + { + "effectType": "sounds", + "effectName": "ENTITY_CREEPER_PRIMED", + "effectState": "placed", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "sounds", + "effectName": "CAT_HISS", + "effectState": "placed", + "offsetTicks": 10, + "volumne": 0.25, + "pitch": 0.25 + }, + { + "effectType": "sounds", + "effectName": "CAT_HISS", + "effectState": "placed", + "offsetTicks": 20, + "volumne": 0.5, + "pitch": 0.5 + }, + { + "effectType": "sounds", + "effectName": "CAT_HISS", + "effectState": "placed", + "offsetTicks": 30, + "volumne": 1.0, + "pitch": 0.75 + }, + { + "effectType": "sounds", + "effectName": "CAT_HISS", + "effectState": "placed", + "offsetTicks": 40, + "volumne": 2.0, + "pitch": 1.5 + }, + { + "effectType": "sounds", + "effectName": "CAT_HISS", + "effectState": "placed", + "offsetTicks": 50, + "volumne": 5.0, + "pitch": 2.5 + }, + { + "effectType": "sounds", + "effectName": "ENTITY_GENERIC_EXPLODE", + "effectState": "explode", + "offsetTicks": 0, + "volumne": 3.0, + "pitch": 1.0 + }, + { + "effectType": "sounds", + "effectName": "ENTITY_DRAGON_FIREBALL_EXPLODE", + "effectState": "explode", + "offsetTicks": 5, + "volumne": 1.5, + "pitch": 1.0 + }, + { + "effectType": "sounds", + "effectName": "ENTITY_GENERIC_EXPLODE", + "effectState": "explode", + "offsetTicks": 10, + "volumne": 2.5, + "pitch": 1.0 + }, + { + "effectType": "sounds", + "effectName": "ENTITY_DRAGON_FIREBALL_EXPLODE", + "effectState": "explode", + "offsetTicks": 15, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "sounds", + "effectName": "ENTITY_GENERIC_EXPLODE", + "effectState": "explode", + "offsetTicks": 20, + "volumne": 2.0, + "pitch": 1.0 + }, + { + "effectType": "sounds", + "effectName": "ENTITY_DRAGON_FIREBALL_EXPLODE", + "effectState": "explode", + "offsetTicks": 25, + "volumne": 0.75, + "pitch": 1.0 + }, + { + "effectType": "sounds", + "effectName": "ENTITY_GENERIC_EXPLODE", + "effectState": "explode", + "offsetTicks": 30, + "volumne": 1.5, + "pitch": 1.0 + }, + { + "effectType": "sounds", + "effectName": "ENTITY_DRAGON_FIREBALL_EXPLODE", + "effectState": "explode", + "offsetTicks": 35, + "volumne": 0.55, + "pitch": 1.0 + }, + { + "effectType": "sounds", + "effectName": "ENTITY_GENERIC_EXPLODE", + "effectState": "explode", + "offsetTicks": 40, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "sounds", + "effectName": "ENTITY_DRAGON_FIREBALL_EXPLODE", + "effectState": "explode", + "offsetTicks": 45, + "volumne": 0.25, + "pitch": 1.0 + }, + { + "effectType": "sounds", + "effectName": "ENTITY_GENERIC_EXPLODE", + "effectState": "explode", + "offsetTicks": 50, + "volumne": 0.5, + "pitch": 1.0 + }, + { + "effectType": "sounds", + "effectName": "ENTITY_DRAGON_FIREBALL_EXPLODE", + "effectState": "explode", + "offsetTicks": 55, + "volumne": 0.15, + "pitch": 1.0 + } + ], + "visualEffects": [ + { + "effectType": "visuals", + "effectName": "ENCHANTMENT_TABLE", + "effectState": "placed", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "visuals", + "effectName": "SMOKE", + "effectState": "placed", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "visuals", + "effectName": "SMOKE_NORMAL", + "effectState": "placed", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "visuals", + "effectName": "SMOKE_NORMAL", + "effectState": "placed", + "offsetTicks": 20, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "visuals", + "effectName": "SMOKE_LARGE", + "effectState": "placed", + "offsetTicks": 60, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "visuals", + "effectName": "DRAGON_BREATH", + "effectState": "placed", + "offsetTicks": 90, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "visuals", + "effectName": "EXPLOSION_HUGE", + "effectState": "explode", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "visuals", + "effectName": "EXPLOSION_NORMAL", + "effectState": "explode", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "visuals", + "effectName": "EXPLOSION_HUGE", + "effectState": "explode", + "offsetTicks": 30, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "visuals", + "effectName": "EXPLOSION_HUGE", + "effectState": "explode", + "offsetTicks": 60, + "volumne": 1.0, + "pitch": 1.0 + } + ] + }, + "orbital8bomb": { + "name": "Orbital8Bomb", + "description": "This old bomb is a dud.&r", + "lore": [ + "This is a bomb?&r", + "&7Hex Colors: &#e81416Red&#ffa500Orange&#faeb36YellowOc314Greenǧde7Blueb369dIndigo𑋡dViolet" + ], + "nameTag": "&a-=- &4{countdown} &5-=- &7{name} &5-=- &4{countdown} &a-=-&r", + "itemName": "&c-= &7{name}&c =-", + "itemType": "DIAMOND", + "radius": 2, + "radiusInner": 0, + "height": 0, + "placementAdjustmentY": 0, + "removalChance": 50.0, + "explosionShape": "sphere", + "toolInHandName": "STONE_PICKAXE", + "toolInHandFortuneLevel": 1, + "toolInHandDurabilityLevel": 0, + "toolInHandDigSpeedLevel": 0, + "fuseDelayTicks": 300, + "cooldownTicks": 20, + "itemRemovalDelayTicks": 5, + "animationPattern": "orbitalEight", + "animationOffset": 0.0, + "animationSpeed": 10.0, + "animationRadius": 1.0, + "animationRadiusDelta": 0.0, + "animationAlternateDirections": false, + "animationSpinSpeed": -35.0, + "animationArmorStandItemLocation": "head", + "throwVelocityLow": 0.25, + "throwVelocityHigh": 1.5, + "glowing": false, + "gravity": true, + "autosell": false, + "customModelData": 0, + "allowedMines": [], + "preventedMines": [], + "applyToPlayersBlockCount": true, + "small": false, + "soundEffects": [ + { + "effectType": "sounds", + "effectName": "ENTITY_CREEPER_PRIMED", + "effectState": "placed", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "sounds", + "effectName": "CAT_HISS", + "effectState": "placed", + "offsetTicks": 30, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "sounds", + "effectName": "ENTITY_GENERIC_EXPLODE", + "effectState": "explode", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + } + ], + "visualEffects": [ + { + "effectType": "visuals", + "effectName": "FLAME", + "effectState": "placed", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "visuals", + "effectName": "BUBBLE_COLUMN_UP", + "effectState": "placed", + "offsetTicks": 30, + "volumne": 1.0, + "pitch": 1.0 + } + ] + }, + "orbitalbomb": { + "name": "OrbitalBomb", + "description": "This old bomb is a dud.&r", + "lore": [ + "This is a bomb?&r" + ], + "nameTag": "&a-=- &4{countdown} &5-=- &7{name} &5-=- &4{countdown} &a-=-&r", + "itemName": "&c-= &7{name}&c =-", + "itemType": "GOLD_INGOT", + "radius": 2, + "radiusInner": 0, + "height": 0, + "placementAdjustmentY": 0, + "removalChance": 50.0, + "explosionShape": "sphere", + "toolInHandName": "STONE_PICKAXE", + "toolInHandFortuneLevel": 1, + "toolInHandDurabilityLevel": 0, + "toolInHandDigSpeedLevel": 0, + "fuseDelayTicks": 300, + "cooldownTicks": 20, + "itemRemovalDelayTicks": 5, + "animationPattern": "orbital", + "animationOffset": 0.0, + "animationSpeed": 10.0, + "animationRadius": 1.0, + "animationRadiusDelta": 0.0, + "animationAlternateDirections": false, + "animationSpinSpeed": -35.0, + "animationArmorStandItemLocation": "head", + "throwVelocityLow": 0.25, + "throwVelocityHigh": 1.5, + "glowing": false, + "gravity": true, + "autosell": false, + "customModelData": 0, + "allowedMines": [], + "preventedMines": [], + "applyToPlayersBlockCount": true, + "small": false, + "soundEffects": [ + { + "effectType": "sounds", + "effectName": "ENTITY_CREEPER_PRIMED", + "effectState": "placed", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "sounds", + "effectName": "CAT_HISS", + "effectState": "placed", + "offsetTicks": 30, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "sounds", + "effectName": "ENTITY_GENERIC_EXPLODE", + "effectState": "explode", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + } + ], + "visualEffects": [ + { + "effectType": "visuals", + "effectName": "FLAME", + "effectState": "placed", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "visuals", + "effectName": "BUBBLE_COLUMN_UP", + "effectState": "placed", + "offsetTicks": 30, + "volumne": 1.0, + "pitch": 1.0 + } + ] + }, + "smallbomb": { + "name": "SmallBomb", + "description": "A small mine bomb made with some chemicals and a brewing stand.&r", + "lore": [ + "&dSmall &6Mine &eBomb &3(lore line 1)&r", + "&4Lore line 2&r", + "&aLore line &73&r" + ], + "nameTag": "&6&kABC&r&c-= &7{name}&c =-&6&kCBA&r", + "itemName": "&c-= &7{name}&c =-", + "itemType": "brewing_stand", + "radius": 2, + "radiusInner": 0, + "height": 0, + "placementAdjustmentY": 0, + "removalChance": 100.0, + "explosionShape": "sphere", + "toolInHandName": "DIAMOND_PICKAXE", + "toolInHandFortuneLevel": 0, + "toolInHandDurabilityLevel": 0, + "toolInHandDigSpeedLevel": 0, + "fuseDelayTicks": 100, + "cooldownTicks": 10, + "itemRemovalDelayTicks": 5, + "animationPattern": "infinity", + "animationOffset": 0.0, + "animationSpeed": 10.0, + "animationRadius": 1.0, + "animationRadiusDelta": 0.0, + "animationAlternateDirections": false, + "animationSpinSpeed": -35.0, + "animationArmorStandItemLocation": "hand", + "throwVelocityLow": 1.5, + "throwVelocityHigh": 3.0, + "glowing": false, + "gravity": true, + "autosell": false, + "customModelData": 0, + "allowedMines": [], + "preventedMines": [], + "applyToPlayersBlockCount": true, + "small": false, + "soundEffects": [ + { + "effectType": "sounds", + "effectName": "ENTITY_CREEPER_PRIMED", + "effectState": "placed", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "sounds", + "effectName": "CAT_HISS", + "effectState": "placed", + "offsetTicks": 30, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "sounds", + "effectName": "ENTITY_GENERIC_EXPLODE", + "effectState": "explode", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + } + ], + "visualEffects": [ + { + "effectType": "visuals", + "effectName": "FLAME", + "effectState": "placed", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "visuals", + "effectName": "SMOKE", + "effectState": "placed", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "visuals", + "effectName": "SMOKE_NORMAL", + "effectState": "placed", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "visuals", + "effectName": "ENCHANTMENT_TABLE", + "effectState": "placed", + "offsetTicks": 30, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "visuals", + "effectName": "EXPLOSION_NORMAL", + "effectState": "explode", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + } + ] + }, + "starburstbomb": { + "name": "starburstBomb", + "description": "This old bomb is a star!r", + "lore": [ + "This is a bomb?&r", + "&7Hex Colors: &#e81416Red&#ffa500Orange&#faeb36YellowOc314Greenǧde7Blueb369dIndigo𑋡dViolet" + ], + "nameTag": "&a-=- &4{countdown} &5-=- &7{name} &5-=- &4{countdown} &a-=-&r", + "itemName": "&c-= &7{name}&c =-", + "itemType": "WHEAT", + "radius": 2, + "radiusInner": 0, + "height": 0, + "placementAdjustmentY": 0, + "removalChance": 50.0, + "explosionShape": "sphere", + "toolInHandName": "STONE_PICKAXE", + "toolInHandFortuneLevel": 1, + "toolInHandDurabilityLevel": 0, + "toolInHandDigSpeedLevel": 0, + "fuseDelayTicks": 300, + "cooldownTicks": 20, + "itemRemovalDelayTicks": 5, + "animationPattern": "starburst", + "animationOffset": 0.0, + "animationSpeed": 9.0, + "animationRadius": 1.5, + "animationRadiusDelta": 0.75, + "animationAlternateDirections": true, + "animationSpinSpeed": -35.0, + "animationArmorStandItemLocation": "hand", + "throwVelocityLow": 0.25, + "throwVelocityHigh": 1.5, + "glowing": false, + "gravity": true, + "autosell": false, + "customModelData": 0, + "allowedMines": [], + "preventedMines": [], + "applyToPlayersBlockCount": true, + "small": false, + "soundEffects": [ + { + "effectType": "sounds", + "effectName": "ENTITY_CREEPER_PRIMED", + "effectState": "placed", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "sounds", + "effectName": "CAT_HISS", + "effectState": "placed", + "offsetTicks": 30, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "sounds", + "effectName": "ENTITY_GENERIC_EXPLODE", + "effectState": "explode", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + } + ], + "visualEffects": [ + { + "effectType": "visuals", + "effectName": "FLAME", + "effectState": "placed", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "visuals", + "effectName": "BUBBLE_COLUMN_UP", + "effectState": "placed", + "offsetTicks": 30, + "volumne": 1.0, + "pitch": 1.0 + } + ] + }, + "wimpybomb": { + "name": "WimpyBomb", + "description": "A whimpy bomb made with gunpowder and packs the punch of a dull wooden pickaxe. For some reason, it only has a 30 percent chance of removing a block.&r", + "lore": [ + "A Wimpy Mine Bomb&r", + "&r", + "A whimpy bomb made with gunpowder and packs the punch &r", + "of a dull wooden pickaxe. For some reason, it only &r", + "has a 40% chance of removing a block.&r", + "&r", + "Not labeled for retail sale.&r" + ], + "nameTag": "&7A &2Wimpy &cBomb&r", + "itemName": "&c-= &7{name}&c =-", + "itemType": "GUNPOWDER", + "radius": 2, + "radiusInner": 1, + "height": 0, + "placementAdjustmentY": 0, + "removalChance": 30.0, + "explosionShape": "sphere", + "toolInHandName": "WOODEN_PICKAXE", + "toolInHandFortuneLevel": 0, + "toolInHandDurabilityLevel": 0, + "toolInHandDigSpeedLevel": 0, + "fuseDelayTicks": 300, + "cooldownTicks": 5, + "itemRemovalDelayTicks": 5, + "animationPattern": "infinityEight", + "animationOffset": 0.0, + "animationSpeed": 10.0, + "animationRadius": 1.0, + "animationRadiusDelta": 0.0, + "animationAlternateDirections": false, + "animationSpinSpeed": -35.0, + "animationArmorStandItemLocation": "hand", + "throwVelocityLow": 0.25, + "throwVelocityHigh": 1.25, + "glowing": true, + "gravity": false, + "autosell": false, + "customModelData": 0, + "allowedMines": [ + "a", + "b", + "c" + ], + "preventedMines": [ + "d", + "e" + ], + "applyToPlayersBlockCount": true, + "small": false, + "soundEffects": [ + { + "effectType": "sounds", + "effectName": "ENTITY_CREEPER_PRIMED", + "effectState": "placed", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "sounds", + "effectName": "CAT_HISS", + "effectState": "placed", + "offsetTicks": 30, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "sounds", + "effectName": "ENTITY_GENERIC_EXPLODE", + "effectState": "explode", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + } + ], + "visualEffects": [ + { + "effectType": "visuals", + "effectName": "FIREWORKS_SPARK", + "effectState": "placed", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "visuals", + "effectName": "FLAME", + "effectState": "placed", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "visuals", + "effectName": "SMOKE", + "effectState": "placed", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "visuals", + "effectName": "SMOKE_NORMAL", + "effectState": "placed", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "visuals", + "effectName": "ENCHANTMENT_TABLE", + "effectState": "placed", + "offsetTicks": 10, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "visuals", + "effectName": "BUBBLE_COLUMN_UP", + "effectState": "placed", + "offsetTicks": 30, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "visuals", + "effectName": "EXPLOSION_NORMAL", + "effectState": "explode", + "offsetTicks": 0, + "volumne": 1.0, + "pitch": 1.0 + }, + { + "effectType": "visuals", + "effectName": "EXPLOSION_LARGE", + "effectState": "explode", + "offsetTicks": 5, + "volumne": 1.0, + "pitch": 1.0 + } + ] + } + } +} diff --git a/prison-core/src/main/java/tech/mcprison/prison/wip/internal/heads/MinecraftHeadData.java b/prison-core/src/main/java/tech/mcprison/prison/wip/internal/heads/MinecraftHeadData.java new file mode 100644 index 000000000..277131951 --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/wip/internal/heads/MinecraftHeadData.java @@ -0,0 +1,76 @@ +package tech.mcprison.prison.wip.internal.heads; + +import java.util.ArrayList; +import java.util.List; + +import tech.mcprison.prison.wip.internal.heads.MinecraftHeadsCache.MinecraftHeadsCategory; + +public class MinecraftHeadData { + + private MinecraftHeadsCategory category; + private String name; + private String uuid; + private String value; + private String tags; + + private boolean used; + + private transient List tagList; + + public MinecraftHeadData() { + super(); + + this.used = false; + + this.tagList = new ArrayList<>(); + } + + public MinecraftHeadsCategory getCategory() { + return category; + } + public void setCategory(MinecraftHeadsCategory category) { + this.category = category; + } + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + public String getUuid() { + return uuid; + } + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getValue() { + return value; + } + public void setValue(String value) { + this.value = value; + } + + public String getTags() { + return tags; + } + public void setTags(String tags) { + this.tags = tags; + } + + public List getTagList() { + return tagList; + } + public void setTagList(List tagList) { + this.tagList = tagList; + } + + public boolean isUsed() { + return used; + } + public void setUsed(boolean used) { + this.used = used; + } +} diff --git a/prison-core/src/main/java/tech/mcprison/prison/wip/internal/heads/MinecraftHeadsCache.java b/prison-core/src/main/java/tech/mcprison/prison/wip/internal/heads/MinecraftHeadsCache.java new file mode 100644 index 000000000..c62cff466 --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/wip/internal/heads/MinecraftHeadsCache.java @@ -0,0 +1,196 @@ +package tech.mcprison.prison.wip.internal.heads; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.TreeMap; +import java.util.TreeSet; + +public class MinecraftHeadsCache { + + private static MinecraftHeadsCache instance; + + private Date headDataDownloadDate; + + private transient TreeSet tags; + + private List headData; + + private transient TreeMap> headDataByCategory; + + private transient TreeMap headDataByUuid; + + private transient TreeMap> headDataByTags; + + public enum MinecraftHeadsCategory { + alphabet, + animals, + blocks, + decoration, + fooddrink("food-drinks"), + humans, + humanoid, + miscellaneous, + monsters, + plants; + + private final String value; + private MinecraftHeadsCategory() { + this.value = this.name(); + } + private MinecraftHeadsCategory( String value ) { + this.value = value; + } + + public String getValue() { + return value; + } + } + + private MinecraftHeadsCache() { + super(); + + this.headDataDownloadDate = null; + + this.tags = new TreeSet<>(); + + this.headData = new ArrayList<>(); + + this.headDataByUuid = new TreeMap<>(); + + this.headDataByTags = new TreeMap<>(); + } + + public static MinecraftHeadsCache getInstance() { + if ( instance == null ) { + + synchronized ( MinecraftHeadsCache.class ) { + if ( instance == null ) { + instance = new MinecraftHeadsCache(); + } + } + } + + return instance; + } + + + /** + *

After the headData is loaded from the file system, this function will build + * the associated indexes to allow the heads to be accessed in various ways. + *

+ * + */ + public void parseHeadData( boolean purgeUnused ) { + List purge = new ArrayList<>(); + + for (MinecraftHeadData head : this.headData ) { + + if ( purgeUnused && !head.isUsed() ) { + purge.add( head ); + } + + else { + + // Build the category index: + if ( !getHeadDataByCategory().containsKey( head.getCategory() ) ) { + getHeadDataByCategory().put( head.getCategory(), new ArrayList<>() ); + } + getHeadDataByCategory().get( head.getCategory() ).add( head ); + + // build uuid index: + if ( !getHeadDataByUuid().containsKey( head.getUuid() ) ) { + getHeadDataByUuid().put( head.getUuid(), head ); + } + + // Extract tags: + if ( head.getTags() != null ) { + List tagz = Arrays.asList( + head.getTags().toLowerCase().split(",") ); + // Extract "tags" in the name field that are within parenthesis: + getTagFromName( head.getName(), tagz ); + + for ( String tag : tagz ) { + + // Add to tag collection: + if ( !getTags().contains( tag ) ) { + getTags().add( tag ); + } + + if ( !getHeadDataByTags().containsKey( tag ) ) { + getHeadDataByTags().put( tag, new ArrayList<>() ); + } + getHeadDataByTags().get( tag ).add( head ); + + } + + } + } + + } + + + if ( purgeUnused && purge.size() > 0 ) { + getHeadData().removeAll( purge ); + } + } + + private void getTagFromName(String name, List tagz) { + + int b = name.indexOf('('); + int e = name.indexOf(')'); + + if ( b != -1 && e != -1 && b < e ) { + String tag = name.substring( b + 1, e ).toLowerCase(); + tagz.add( tag ); + } + } + + public Date getHeadDataDownloadDate() { + return headDataDownloadDate; + } + public void setHeadDataDownloadDate(Date headDataDownloadDate) { + this.headDataDownloadDate = headDataDownloadDate; + } + + public TreeSet getTags() { + return tags; + } + + public void setTags(TreeSet tags) { + this.tags = tags; + } + + public List getHeadData() { + return headData; + } + + public void setHeadData(List headData) { + this.headData = headData; + } + + public TreeMap> getHeadDataByCategory() { + return headDataByCategory; + } + + public void setHeadDataByCategory(TreeMap> headDataByCategory) { + this.headDataByCategory = headDataByCategory; + } + + public TreeMap getHeadDataByUuid() { + return headDataByUuid; + } + + public void setHeadDataByUuid(TreeMap headDataByUuid) { + this.headDataByUuid = headDataByUuid; + } + + public TreeMap> getHeadDataByTags() { + return headDataByTags; + } + + public void setHeadDataByTags(TreeMap> headDataByTags) { + this.headDataByTags = headDataByTags; + } +} diff --git a/prison-core/src/test/java/tech/mcprison/prison/wip/discord/PrisonSupportFileLinkageTest.java b/prison-core/src/test/java/tech/mcprison/prison/wip/discord/PrisonSupportFileLinkageTest.java new file mode 100644 index 000000000..d243a879b --- /dev/null +++ b/prison-core/src/test/java/tech/mcprison/prison/wip/discord/PrisonSupportFileLinkageTest.java @@ -0,0 +1,53 @@ +package tech.mcprison.prison.wip.discord; + +import static org.junit.Assert.*; + +import org.junit.Test; + +import tech.mcprison.prison.discord.PrisonSupportFileLinkage; +import tech.mcprison.prison.discord.PrisonSupportFileLinkage.PrimaryLinkages; + +public class PrisonSupportFileLinkageTest extends PrisonSupportFileLinkage { + + @Test + public void test() { + + PrisonSupportFileLinkage psfl = new PrisonSupportFileLinkage(); + + String test1 = "||Ladder default||"; + String test2 = "Some regular text"; + String test3 = "||Ladder cats||"; + String test4 = "||Invalid Primary||"; + + + // This should be ignored since it's not a linkage: + psfl.addLinkage(test2); + + assertEquals( 0, psfl.getPrimaries().size() ); + + + + // This should be rejected because the primary is not a valid one: + psfl.addLinkage(test4); + + assertEquals( 0, psfl.getPrimaries().size() ); + + + + // This should result in the first one being added: + psfl.addLinkage(test1); + + assertEquals( 1, psfl.getPrimaries().size() ); + assertEquals( 1, psfl.getPrimaries().get( PrimaryLinkages.Ladder ).size() ); + + + // + psfl.addLinkage(test3); + + assertEquals( 1, psfl.getPrimaries().size() ); + assertEquals( 2, psfl.getPrimaries().get( PrimaryLinkages.Ladder ).size() ); + + + } + +} diff --git a/prison-core/src/test/java/tech/mcprison/prison/wip/tasks/PrisonCommandTaskDataTest.java b/prison-core/src/test/java/tech/mcprison/prison/wip/tasks/PrisonCommandTaskDataTest.java new file mode 100644 index 000000000..81b78157b --- /dev/null +++ b/prison-core/src/test/java/tech/mcprison/prison/wip/tasks/PrisonCommandTaskDataTest.java @@ -0,0 +1,70 @@ +package tech.mcprison.prison.wip.tasks; + +import static org.junit.Assert.*; + +import org.junit.Test; + +import tech.mcprison.prison.tasks.PrisonCommandTaskData; + +public class PrisonCommandTaskDataTest + extends PrisonCommandTaskData { + + public PrisonCommandTaskDataTest() { + super( "junit-test", "junit tests" ); + } + @Test + public void test() { + + { + String orig = "{range: 1 1}"; + String result = taskInsertRange( orig ); + + assertEquals( "1", result); + System.out.println( "Test 1: orig: " + orig + " result: " + result); + } + { + String orig = "{range: 1 3}"; + String result = taskInsertRange( orig ); + + boolean success = "1".equals(result) || + "2".equals(result) || + "3".equals(result); + assertTrue( success ); + System.out.println( "Test 2: orig: " + orig + " result: " + result); + } + { + String orig = "{range: 6 7}"; + String result = taskInsertRange( orig ); + + boolean success = "6".equals(result) || + "7".equals(result); + assertTrue( success ); + System.out.println( "Test 3: orig: " + orig + " result: " + result); + } + { + String orig = "{range: 0 2}"; + String result = taskInsertRange( orig ); + + boolean success = "0".equals(result) || + "1".equals(result) | + "2".equals(result); + assertTrue( success ); + System.out.println( "Test 4: orig: " + orig + " result: " + result); + } + { + String orig = "{range: -1 2}"; + String result = taskInsertRange( orig ); + + boolean success = "0".equals(result) || + "-1".equals(result) | + "1".equals(result) | + "2".equals(result); + assertTrue( success ); + System.out.println( "Test 5: orig: " + orig + " result: " + result); + } + + +// fail("Not yet implemented"); + } + +} diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/wip/data/MineBlockConstraints.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/wip/data/MineBlockConstraints.java new file mode 100644 index 000000000..ae0b4602b --- /dev/null +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/wip/data/MineBlockConstraints.java @@ -0,0 +1,5 @@ +package tech.mcprison.prison.mines.wip.data; + +public class MineBlockConstraints { + +} diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/wip/data/MineQuestData.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/wip/data/MineQuestData.java new file mode 100644 index 000000000..d2f81310a --- /dev/null +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/wip/data/MineQuestData.java @@ -0,0 +1,33 @@ +package tech.mcprison.prison.mines.wip.data; + +public class MineQuestData { + + private String questName; + + private MineQuestType questType; + + private boolean completed = false; + + + + public enum MineQuestSource { + byMine, + byBlockType + ; + } + + public enum MineQuestType { + money, + token, + block, + time + ; + } + + public MineQuestData() { + super(); + + + } + +} diff --git a/prison-sellall/src/main/java/tech/mcprison/prison/sellall/wip/data/SellallItemData.java b/prison-sellall/src/main/java/tech/mcprison/prison/sellall/wip/data/SellallItemData.java new file mode 100644 index 000000000..e181b8449 --- /dev/null +++ b/prison-sellall/src/main/java/tech/mcprison/prison/sellall/wip/data/SellallItemData.java @@ -0,0 +1,39 @@ +package tech.mcprison.prison.sellall.wip.data; + +public class SellallItemData { + + private String name; + private double price; + private int amount; + + public SellallItemData( String name, double price ) { + super(); + + this.name = name; + this.price = price; + + this.amount = 0; + } + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + public double getPrice() { + return price; + } + public void setPrice(double price) { + this.price = price; + } + + public int getAmount() { + return amount; + } + public void setAmount(int amount) { + this.amount = amount; + } + +} diff --git a/prison-sellall/src/main/java/tech/mcprison/prison/sellall/wip/data/ShopData.java b/prison-sellall/src/main/java/tech/mcprison/prison/sellall/wip/data/ShopData.java new file mode 100644 index 000000000..076e8ecdf --- /dev/null +++ b/prison-sellall/src/main/java/tech/mcprison/prison/sellall/wip/data/ShopData.java @@ -0,0 +1,63 @@ +package tech.mcprison.prison.sellall.wip.data; + +import java.util.List; + +public class ShopData { + + private String name; + + private int priority; + + // Connection identifies how this shop is tied to something, such + // as a rank, mine, or a perm. + private String connection; + private ConnectionType connectionType; + + private String parentName; + private transient ShopData parent; + private double parentMultiplier; +// private boolean includeParentItems; // if false, then makes no sense to have a parent + + + /** + * Added items is the "raw" list of items that should be added to this shop. + * Removed items are applied only to inherited items from the parents. + */ + private List itemsAdd; + private List itemsRemove; + + /* + * Items is the "calculated" set of items, which includes items from the parents, + * with the adjustments made to the prices. + */ + private transient List items; + + public enum ConnectionType { + RANK, + MINE, + PERM; + } + + /** + *

The default value will be ADD, which indicates that the specified + * ShopItemData should be "added" to the shop. The REMOVE value indicates + * that this item should be removed from the current shop, as all of the + * items are pulled from the parents. It's a way to remove items from a shop + * when inheriting from parents. + *

+ * + */ + public enum ShopItemAction { + ADD, + REMOVE, + + ; + } + + public ShopData() { + super(); + + boolean a = !!true; + boolean b = !!!!!!a; + } +} diff --git a/prison-sellall/src/main/java/tech/mcprison/prison/sellall/wip/data/ShopItemData.java b/prison-sellall/src/main/java/tech/mcprison/prison/sellall/wip/data/ShopItemData.java new file mode 100644 index 000000000..a32feaa8d --- /dev/null +++ b/prison-sellall/src/main/java/tech/mcprison/prison/sellall/wip/data/ShopItemData.java @@ -0,0 +1,36 @@ +package tech.mcprison.prison.sellall.wip.data; + +import tech.mcprison.prison.internal.block.PrisonBlock; +import tech.mcprison.prison.sellall.wip.data.ShopData.ShopItemAction; + +public class ShopItemData { + + private String name; + private String description; + + + // ItemId is the text representation of the block or item. Generally it is + // an xseries name, but could also be a custom block name too, following + // prison's qualified naming convention. + private String itemId; + private double cost; + + private ShopItemAction action; + + private transient PrisonBlock prisonBlock; + + public ShopItemData() { + super(); + } + + public ShopItemData( String name, String description, String itemId, double cost ) { + super(); + + this.name = name; + this.description = description; + this.itemId = itemId; + this.cost = cost; + } + + +} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/tasks/SampleTask.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/tasks/SampleTask.java new file mode 100644 index 000000000..c1f7794eb --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/tasks/SampleTask.java @@ -0,0 +1,58 @@ +package tech.mcprison.prison.spigot.tasks; + +import org.bukkit.plugin.Plugin; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitTask; + +public class SampleTask + extends BukkitRunnable +{ + private final Plugin plugin; + private BukkitTask bukkitTask; + + public SampleTask(Plugin plugin) { + super(); + this.plugin = plugin; + } + + /** + * Run a task every 1 second. + * + * @param plugin + * @return + */ + public static SampleTask submit( Plugin plugin ) { + return submit( plugin, 20 ); + } + public static SampleTask submit( Plugin plugin, long delay ) { + + SampleTask task = new SampleTask(plugin); + + BukkitTask bTask = task.runTaskTimer( plugin, delay, delay ); + + task.setBukkitTask( bTask ); + + return task; + } + + public void run() { + boolean finished = false; + + // code: do something then let it exit: + + if ( finished ) { + getBukkitTask().cancel(); + } + } + + public Plugin getPlugin() { + return plugin; + } + + public BukkitTask getBukkitTask() { + return bukkitTask; + } + public void setBukkitTask( BukkitTask bukkitTask ) { + this.bukkitTask = bukkitTask; + } +} diff --git a/prison-spigot/src/main/resources/config_sample.yml b/prison-spigot/src/main/resources/config_sample.yml new file mode 100644 index 000000000..79e323d67 --- /dev/null +++ b/prison-spigot/src/main/resources/config_sample.yml @@ -0,0 +1,115 @@ + + +# ladder-features helps define the server's environment for both ladders and their ranks. +# +# The ladder name is defined by: 'ladder-features.' +# +# - active: [true false] Only active ladders will be generated via command `/ranks autoConfigure` +# - extendable: [true false] If enabled, more ranks can be added from in-game command at any time: `/ranks addRanks `. +# If using `rank-name-details.name-list` then this has to be false since there is no pattern to generate more ranks. +# - ladder-commands: An array of Strings that represents one or more commands to run when a player ranks up on this ladder +# For a list of placeholders, see command: `/ranks ladder command add placeholders` +# - rank-name-details: There are a few ways you can define names or the ranks. You can only use one method per ladder. +# - method-pattern: +# - range-low: required. Def [A]. The first rank of the ladder. Must be single digit (A Java char). +# - range-high: Optional if range-count is used. Def [Z]. The last rank name. Must be a single digit (A Java char). +# - range-count: Optional if range-high is used. Number of ranks. This is the starting number of ranks that will be generated +# with the `/ranks autoConfigure` command. In game extensions will exceed this value, so do not use this to guess how many +# ranks are on a ladder. If a letter range is less than the intended extended range, then the letter range will be +# repeated with using the pass-count number as a unique identifier. See example in next item. +# - suppress-first-pass-number: Optional. [true false] If the method-pattern contains a placeholder {number}, then a +# value of true will not include the number on the first pass of ranks. Ignored if `replace-first-pass-number` is used. +# Ex: A, B, C, ... Z, A2, B2, C2, ... Z2. +# - replace-first-pass-number: Optional. String value. Def [+]. If specified then it will suppress the +# first range value as if: `suppress-first-pass-number: true` +# - name-list: An array of Rank names to be used. They will be added in the order list, with the first becoming +# the default rank for the ladder. If using this name-list, then the other modifiers are ignored and are invalid. +# - rank-tag-pattern: Required. Used to generate the rank tag. Color placeholders appearing multiple times in the pattern +# will be the same color. Color placeholders ending with "-pass" will have the same color for the +# whole pass through the ranks. Random colors will chosen fresh each time ranks are generated so +# use carefully with the "-pass" colors (generate a full pass on each occurance). +# Valid placeholders: {rank-name}{rnd-color}{seq-color}{rnd-color-pass}{seq-color-pass} +# - +# - +# +ladder-features: + default: + active: true + extendable: false + ladder-commands: + - {msg}Congratulations on your new prestige rank {targetRankTag};{broadcast}{player} just prestiged to {targetRankTag}!! + - mines tp {player} + rank-commands: + A: + - {firstJoin}{actionBar}Welcome to Prison!;{msg}Start your adventure by going to your first mine with the command: /mine tp a;{msg}Use the command /rankup to climb the ladder and reach higher ranks! + Z: + - {msg}Congratulations! You made it to the top rank Z!;{msg}Now the race is on to prestige! When you've ready use the command: /prestige + rank-name-details: + method-pattern: "{rank}{number}" + range-low: 'A' + range-high: 'Z' + range-count: 26 + suppress-first-pass-number: true + rank-tag-pattern: "&7[{rnd-color}{rank-name}&7]" + rank-cost: + enable-rankup: true + enable-rankupmax: true + initial: 0 + per-rank: 50000 + multiplier: 1.5 + multiplier-method: compound + decimal-pattern: 0 + rank-cost-multiplier: + percent: 0 + apply-to-this-ladder: true + create-and-link-mines: true + prestiges: + active: true + extendable: true + ladder-commands: + rank-commands: + P+: + - {actionBar}Congrats on your first prestige! + rank-name-details: + method-pattern: "p{number}" + range-count: 20 + replace-first-pass-number: "+" + rank-name-pattern: "p{number}" + rank-tag-pattern: "&7[{random-color}{rank-name}&7]" + rank-cost:y + enable-rankup: true + enable-rankupmax: true + initial: 2500000000 + per-rank: 2500000000 + multiplier: 2 + multiplier-method: linear + decimal-pattern: 0 + rank-cost-multiplier: + percent: 0.1000 + apply-to-this-ladder: false + create-and-link-mines: false + donors: + active: true + extendable: false + rank-name-details: + name-list: + - "Vip" + - "Premium" + - "Supreme" + - "Tourist" + - "Royalty" + rank-tag-pattern: "&7[{random-color}{rank-name}&7]" + rank-cost: + enable-rankup: false + enable-rankupmax: false + initial: 0 + per-rank: 0 + multiplier: 0 + multiplier-method: "none" + decimal-pattern: 0 + rank-cost-multiplier: + percent: 0 + apply-to-this-ladder: false + create-and-link-mines: false + + diff --git a/prison-spigot/src/test/java/tech/mcprison/prison/spigot/Test.java b/prison-spigot/src/test/java/tech/mcprison/prison/spigot/Test.java new file mode 100644 index 000000000..4fab92583 --- /dev/null +++ b/prison-spigot/src/test/java/tech/mcprison/prison/spigot/Test.java @@ -0,0 +1,35 @@ +package tech.mcprison.prison.spigot; + +public class Test { + +// public int getCustomEnchlvl(Player p, String enchantment, ItemStack item) { +// int result = 0; +// +// if (item != null && item.hasItemMeta()) { +// +// ItemMeta meta = item.getItemMeta(); +// +// if (meta.hasLore()) { +// +// List lores = meta.getLore(); +// +// for (int i = 0; i < lores.size(); i++) { +// String lore = lores.get(i); +// +// if (lore.contains(enchantment)) { +// String val = lore.substring(enchantment.length() + 3); +// try { +// result = Integer.parseInt(val); +// break; +// } +// catch (NumberFormatException e) { +// // Not a number, so ignore; +// } +// } +// } +// } +// } +// +// return result; +// } +} diff --git a/prison-spigot/src/test/java/tech/mcprison/prison/spigot/block/SpigotItemStackTest.java b/prison-spigot/src/test/java/tech/mcprison/prison/spigot/block/SpigotItemStackTest.java new file mode 100644 index 000000000..ab23e03c7 --- /dev/null +++ b/prison-spigot/src/test/java/tech/mcprison/prison/spigot/block/SpigotItemStackTest.java @@ -0,0 +1,42 @@ +package tech.mcprison.prison.spigot.block; + +import org.junit.Test; + +public class SpigotItemStackTest +//extends SpigotItemStack +{ + +// public SpigotItemStackTest() { +// super( 2, PrisonBlock.PINK_STAINED_GLASS ); +// +// } + + + +// public void setNbtString( ItemStack bItemStack, String key, String value ) { +// NBTItem nbt = new NBTItem( bItemStack, true ); +// nbt.setString( key, value ); +// nbt.applyNBT( bItemStack ); +// } +// +// public String getNbtValue( ItemStack bItemStack, String key ) { +// NBTItem nbt = new NBTItem( bItemStack ); +// return nbt.getString( key ); +// } + + + @Test + public void test() { + + +// ItemStack bItemStack = new ItemStack( Material.BREWING_STAND, 1 ); +// +// setNbtString( bItemStack, "testKey", "SomeValue" ); +// +// String value = getNbtValue( bItemStack, "testKey" ); +// +// assertEquals( "someValue", value ); + + } + +} From f76ec2fc8a15f88e6ec9d62a453dc167e4677298 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 5 Mar 2026 00:09:59 -0500 Subject: [PATCH 302/323] Prison Cleanup: Mines: Removed obsolete and unneeded comments and fix indentation where needed. --- docs/changelog_v3.3.x.md | 4 + .../prison/mines/MinesChatHandler.java | 40 +- .../prison/mines/MinesConversionAgent.java | 127 +- .../mcprison/prison/mines/MinesListener.java | 156 +- .../mcprison/prison/mines/PrisonMines.java | 76 +- .../mines/commands/MinesBlockCommands.java | 625 +- .../prison/mines/commands/MinesCommands.java | 5526 ++++++++--------- .../mines/commands/MinesImportCommands.java | 58 +- .../tech/mcprison/prison/mines/data/Mine.java | 362 +- .../mcprison/prison/mines/data/MineData.java | 735 +-- .../mines/data/MineLevelBlockListData.java | 5 - .../mcprison/prison/mines/data/MineReset.java | 1766 ++---- .../prison/mines/data/MineScheduler.java | 172 +- .../prison/mines/data/MineSweeperTask.java | 2 - .../mcprison/prison/mines/data/MineTasks.java | 385 +- .../prison/mines/data/MinesConfig.java | 23 - ...StartupRefreshBlockBreakCountSyncTask.java | 23 +- .../prison/mines/features/MineBlockEvent.java | 95 - .../mines/features/MineLinerBuilder.java | 81 - .../mines/features/MineTracerBuilder.java | 92 +- .../prison/mines/managers/MineManager.java | 518 +- .../mines/tasks/MinePagedResetAsyncTask.java | 4 - .../mines/data/PrisonSortableMinesTest.java | 7 - .../mines/managers/MineManagerTest.java | 9 - 24 files changed, 4139 insertions(+), 6752 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 63c9eed43..89012a7af 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. + +* **Prison Cleanup: Mines: Removed obsolete and unneeded comments and fix indentation where needed.** + + * **General cleanup: these are works in progress (wip) that have not been finalized.** If it's source, its been moved to a package with .wip.in the name. These may be deleted in the future or they could be used. diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/MinesChatHandler.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/MinesChatHandler.java index 21c561ba7..deb1ee1a0 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/MinesChatHandler.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/MinesChatHandler.java @@ -15,34 +15,16 @@ public MinesChatHandler() { @Subscribe public void onPlayerChat(PlayerChatEvent e) { -// String message = e.getMessage(); - String newFormat = e.getFormat(); - - Player player = e.getPlayer(); - - // Now translates - - String translated = Prison.get().getPlatform().getPlaceholders() - .placeholderTranslateText( player.getUUID(), player.getName(), newFormat ); - - -// String translated = Prison.get().getPlatform().getPlaceholders() -// .placeholderTranslateText( newFormat ); - - e.setFormat( translated ); - -// MineManager mm = PrisonMines.getInstance().getMineManager(); -// -// List placeholderKeys = mm.getTranslatedPlaceHolderKeys(); -// -// for ( PlaceHolderKey placeHolderKey : placeholderKeys ) { -// String key = "{" + placeHolderKey.getKey() + "}"; -// if ( newFormat.contains( key )) { -// newFormat = newFormat.replace(key, Text.translateAmpColorCodes( -// mm.getTranslateMinesPlaceHolder( placeHolderKey ) )); -// } -// } -// -// e.setFormat(newFormat); + String newFormat = e.getFormat(); + + Player player = e.getPlayer(); + + // Now translates + + String translated = Prison.get().getPlatform().getPlaceholders() + .placeholderTranslateText( player.getUUID(), player.getName(), newFormat ); + + e.setFormat( translated ); + } } diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/MinesConversionAgent.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/MinesConversionAgent.java index 3fdc4f550..f90120934 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/MinesConversionAgent.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/MinesConversionAgent.java @@ -14,112 +14,27 @@ public class MinesConversionAgent @Override public ConversionResult convert() { - Output.get().logWarn( "&7This version of prison is unable to convert older versions " + - "to this release. Please upgrade first to Prision v3.1.1, then " + - "Prison v3.2.1, then Prison v3.2.11. Once prison is upgraded to " + - "version v3.2.11 then it should be able to convert automatically to " + - "Prison v3.3.0. When upgrading to all of these versions, all that is needed " + - "is to just install the newer Prison jar file, and then start the server. " + - "The configs will be converted for you. Then 'stop' the server and " + - "continue to the next version. You may be able to skip v3.2.1, but it " + - "may be safest to run that version for the incremental adjustments. " + - "It also would not be a bad idea to may a copy of the prison plugin " + - "directory betwen version upgrades: plugins/Prison/. " ); - - Output.get().logWarn( "&7NOTE: This version of prison cannot process the older block types that " + - "were used in the older versions of prison." ); - -// File oldFolder = new File(PrisonAPI.getPluginDirectory().getParent(), "Prison.old"); -// File minesFolder = new File(oldFolder, "mines"); -// -// File alreadyConverted = new File(minesFolder, ".converted"); -// if (alreadyConverted.exists()) { -// return ConversionResult.failure(getName(), -// "Already converted. Delete the '/plugins/Prison.old/mines' folder."); -// } -// -// String[] jsonFiles = minesFolder.list((dir, name) -> name.endsWith(".json")); -// -// try { -// -// // ----------- -// // JSON -// // ----------- -// -// if (jsonFiles != null) { -// for (String jsonFile : jsonFiles) { -// File jsonFileObj = new File(minesFolder, jsonFile); -// String json = new String(Files.readAllBytes(jsonFileObj.toPath())); -// JsonObject obj = (JsonObject) JsonParser.parseString(json); -// -// String name = obj.getAsJsonPrimitive("name").getAsString(); -// String world = obj.getAsJsonPrimitive("world").getAsString(); -// double minX = obj.getAsJsonPrimitive("minX").getAsInt(); -// double minY = obj.getAsJsonPrimitive("minY").getAsInt(); -// double minZ = obj.getAsJsonPrimitive("minZ").getAsInt(); -// double maxX = obj.getAsJsonPrimitive("maxX").getAsInt(); -// double maxY = obj.getAsJsonPrimitive("maxY").getAsInt(); -// double maxZ = obj.getAsJsonPrimitive("maxZ").getAsInt(); -// -// Optional prisonWorld = -// Prison.get().getPlatform().getWorld(world); -// if (!prisonWorld.isPresent()) { -// Output.get().logWarn(String.format( -// "Can't convert mine %s because its world %s doesn't exist anymore.", -// name, world)); -// break; // Skip it, its world didn't exist. -// } -// -// Bounds bounds = new Bounds(new Location(prisonWorld.get(), minX, minY, minZ), -// new Location(prisonWorld.get(), maxX, maxY, maxZ)); -// -// HashMap blocks = new HashMap<>(); -// for (Map.Entry blockEntry : obj.getAsJsonObject("blocks") -// .entrySet()) { -// String[] blockParts = blockEntry.getKey().split(":"); -// BlockType type = BlockType.getBlock(Integer.parseInt(blockParts[0]), -// Short.parseShort(blockParts[1])); -// -// // Prison 2 stores chances in values < 1, whereas Prison 3 does it < 100 -// int chance = (int) ((blockEntry.getValue().getAsDouble()) * 100); -// -// blocks.put(type, chance); -// } -// -// Mine ourMine = new Mine(); -// ourMine.setName(name); -// ourMine.setBounds(bounds); -// ourMine.setBlocks(blocks); -// -// if (PrisonMines.getInstance().getMines().contains(ourMine)) { -// break; -// } -// -// PrisonMines.getInstance().getMines().add(ourMine); -// } -// -// PrisonMines.getInstance().getMineManager().saveMines(); -// alreadyConverted.createNewFile(); -// return new ConversionResult(getName(), ConversionResult.Status.Success, -// "Converted " + jsonFiles.length + " mines."); -// } else { -// alreadyConverted.createNewFile(); -// return new ConversionResult(getName(), ConversionResult.Status.Success, -// "Converted 0 mines."); -// } -// } catch (IOException e) { -// PrisonMines.getInstance().getErrorManager().throwError( -// new Error("Encountered an error while converting mines.") -// .appendStackTrace("while loading mines", e)); -// return new ConversionResult(getName(), ConversionResult.Status.Failure, -// "IOException, check console for details"); -// } - - return ConversionResult.failure(getName(), - "This version of prison cannot perform conversion upgrades. It skips too " + - "many versions. See WARNING in console, and install the suggested older " + - "versions of Prison to ensure all of the old data is updated correctly, " + - "with no losses."); + Output.get().logWarn( "&7This version of prison is unable to convert older versions " + + "to this release. Please upgrade first to Prision v3.1.1, then " + + "Prison v3.2.1, then Prison v3.2.11. Once prison is upgraded to " + + "version v3.2.11 then it should be able to convert automatically to " + + "Prison v3.3.0. When upgrading to all of these versions, all that is needed " + + "is to just install the newer Prison jar file, and then start the server. " + + "The configs will be converted for you. Then 'stop' the server and " + + "continue to the next version. You may be able to skip v3.2.1, but it " + + "may be safest to run that version for the incremental adjustments. " + + "It also would not be a bad idea to may a copy of the prison plugin " + + "directory betwen version upgrades: plugins/Prison/. " ); + + Output.get().logWarn( "&7NOTE: This version of prison cannot process the older block types that " + + "were used in the older versions of prison." ); + + + return ConversionResult.failure(getName(), + "This version of prison cannot perform conversion upgrades. It skips too " + + "many versions. See WARNING in console, and install the suggested older " + + "versions of Prison to ensure all of the old data is updated correctly, " + + "with no losses."); } @Override diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/MinesListener.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/MinesListener.java index 4058eab05..dd9d10fe7 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/MinesListener.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/MinesListener.java @@ -28,10 +28,10 @@ public void onSelectionComplete(SelectionCompletedEvent e) { @Subscribe public void onWorldLoadListener( PrisonWorldLoadEvent e ) { - - String worldName = e.getWorldName(); - PrisonMines.getInstance().getMineManager().assignAvailableWorld( worldName ); - + + String worldName = e.getWorldName(); + PrisonMines.getInstance().getMineManager().assignAvailableWorld( worldName ); + } @@ -45,132 +45,38 @@ public void onWorldLoadListener( PrisonWorldLoadEvent e ) { @Subscribe public void onPlayerSuffocationListener( PlayerSuffocationEvent e ) { - Player player = e.getPlayer(); - Mine mine = PrisonMines.getInstance().findMineLocation( player ); - - if ( mine != null ) { - - // If players can't be suffocated in mines, then cancel the suffocation event: - if ( !Prison.get().getPlatform().getConfigBooleanFalse( "prison-mines.enable-suffocation-in-mines" ) ) { - - e.setCanceled( true ); - } - + Player player = e.getPlayer(); + Mine mine = PrisonMines.getInstance().findMineLocation( player ); + + if ( mine != null ) { + + // If players can't be suffocated in mines, then cancel the suffocation event: + if ( !Prison.get().getPlatform().getConfigBooleanFalse( "prison-mines.enable-suffocation-in-mines" ) ) { + + e.setCanceled( true ); + } - if ( Prison.get().getPlatform().getConfigBooleanTrue( "prison-mines.tp-to-spawn-on-mine-resets" ) ) { + + if ( Prison.get().getPlatform().getConfigBooleanTrue( "prison-mines.tp-to-spawn-on-mine-resets" ) ) { + + // Submit the teleport task to run in 3 ticks. This will allow the suffocation + // event to be canceled. If the player moves then they don't need to be teleported + // so it will be canceled. + MineTeleportWarmUpTask mineTeleportWarmUp = new MineTeleportWarmUpTask( + player, mine, "spawn", 0.5 ); + mineTeleportWarmUp.setMessageSuccess( + "&7You have been teleported out of the mine to prevent suffocating." ); + mineTeleportWarmUp.setMessageFailed( null ); + + PrisonTaskSubmitter.runTaskLater( mineTeleportWarmUp, 3 ); + } - // Submit the teleport task to run in 3 ticks. This will allow the suffocation - // event to be canceled. If the player moves then they don't need to be teleported - // so it will be canceled. - MineTeleportWarmUpTask mineTeleportWarmUp = new MineTeleportWarmUpTask( - player, mine, "spawn", 0.5 ); - mineTeleportWarmUp.setMessageSuccess( - "&7You have been teleported out of the mine to prevent suffocating." ); - mineTeleportWarmUp.setMessageFailed( null ); + } + else { + player.sendMessage( "&7You cannot be teleported to safety. Good luck." ); - PrisonTaskSubmitter.runTaskLater( mineTeleportWarmUp, 3 ); -// mine.teleportPlayerOut( player ); } - -// -// -// // To "move" the player out of the mine, they are elevated by one block above the surface -// // so need to remove the glass block if one is spawned under them. If there is no glass -// // block, then it will do nothing. -// mine.submitTeleportGlassBlockRemoval(); - -// player.sendMessage( "&7You have been teleported out of the mine to prevent suffocating." ); - } - else { - player.sendMessage( "&7You cannot be teleported to safety. Good luck." ); - - } } - -// /** -// * Powertool helper -// */ -// @Subscribe -// public void onBlockBreak(BlockBreakEvent e) { -// if (PrisonMines.getInstance().getPlayerManager().hasAutosmelt(e.getPlayer())) { -// smelt(e.getBlockLocation().getBlockAt() -// .getDrops(((PlayerInventory) e.getPlayer().getInventory()).getItemInRightHand())); -// } -// if (PrisonMines.getInstance().getPlayerManager().hasAutopickup(e.getPlayer())) { -// e.getPlayer().getInventory() -// .addItem(e.getBlockLocation().getBlockAt().getDrops().toArray(new ItemStack[]{})); -// e.getBlockLocation().getBlockAt().setType(BlockType.AIR); -// e.setCanceled(true); -// } -// if (PrisonMines.getInstance().getPlayerManager().hasAutoblock(e.getPlayer())) { -// block(e.getPlayer()); -// } -// } - -// private void smelt(List drops) { -// drops.replaceAll(x -> { -// if (x.getMaterial() == BlockType.GOLD_ORE) { -// return new ItemStack(x.getAmount(), BlockType.GOLD_INGOT); -// } else if (x.getMaterial() == BlockType.IRON_ORE) { -// return new ItemStack(x.getAmount(), BlockType.IRON_INGOT); -// } else { -// return x; -// } -// }); -// } - -// private void block(Player player) { -// List itemList = Arrays.asList(player.getInventory().getItems()); -// List giveBack = new ArrayList<>(); -// itemList.replaceAll(x -> { -// if (x != null) { -// if (x.getMaterial() == BlockType.DIAMOND) { -// if (x.getAmount() % 9 > 0) { -// giveBack.add(new ItemStack(x.getAmount() % 9, x.getMaterial())); -// } -// return new ItemStack(x.getAmount() / 9, BlockType.DIAMOND_BLOCK); -// } else if (x.getMaterial() == BlockType.EMERALD) { -// if (x.getAmount() % 9 > 0) { -// giveBack.add(new ItemStack(x.getAmount() % 9, x.getMaterial())); -// } -// return new ItemStack(x.getAmount() / 9, BlockType.EMERALD_BLOCK); -// } else if (x.getMaterial() == BlockType.IRON_INGOT) { -// if (x.getAmount() % 9 > 0) { -// giveBack.add(new ItemStack(x.getAmount() % 9, x.getMaterial())); -// } -// return new ItemStack(x.getAmount() / 9, BlockType.IRON_BLOCK); -// } else if (x.getMaterial() == BlockType.GLOWSTONE_DUST) { -// if (x.getAmount() % 4 > 0) { -// giveBack.add(new ItemStack(x.getAmount() % 9, x.getMaterial())); -// } -// return new ItemStack(x.getAmount() / 4, BlockType.GLOWSTONE); -// } else if (x.getMaterial() == BlockType.GOLD_INGOT) { -// if (x.getAmount() % 9 > 0) { -// giveBack.add(new ItemStack(x.getAmount() % 9, x.getMaterial())); -// } -// return new ItemStack(x.getAmount() / 9, BlockType.GOLD_BLOCK); -// } else if (x.getMaterial() == BlockType.COAL) { -// if (x.getAmount() % 9 > 0) { -// giveBack.add(new ItemStack(x.getAmount() % 9, x.getMaterial())); -// } -// return new ItemStack(x.getAmount() / 9, BlockType.BLOCK_OF_COAL); -// } else if (x.getMaterial() == BlockType.REDSTONE) { -// if (x.getAmount() % 9 > 0) { -// giveBack.add(new ItemStack(x.getAmount() % 9, x.getMaterial())); -// } -// return new ItemStack(x.getAmount() / 9, BlockType.REDSTONE_BLOCK); -// } else if (x.getMaterial() == BlockType.LAPIS_LAZULI) { -// return new ItemStack(x.getAmount() / 9, BlockType.LAPIS_LAZULI_BLOCK); -// } else { -// return x; -// } -// } else { -// return x; -// } -// }); -// player.getInventory().setItems(itemList); -// player.getInventory().addItem((ItemStack[]) giveBack.toArray()); -// } } 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 21223d8e4..4574439a2 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 @@ -52,11 +52,9 @@ public class PrisonMines extends Module { 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; -// private List worlds; private LocaleManager localeManager; private Database db; private ErrorManager errorManager; @@ -64,7 +62,6 @@ public class PrisonMines extends Module { private JsonFileIO jsonFileIO; private MineManager mineManager; -// private PlayerManager player; private MinesCommands minesCommands; @@ -89,17 +86,17 @@ public PrisonMines(String version) { } public static PrisonMines getInstance() { - if ( i == null ) { - PrisonMines temp = new PrisonMines("(not loaded yet)"); - temp.setEnabled(false); - return temp; - } + if ( i == null ) { + PrisonMines temp = new PrisonMines("(not loaded yet)"); + temp.setEnabled(false); + return temp; + } return i; } @Override public String getBaseCommands() { - return "/mines"; + return "/mines"; } @Override @@ -113,25 +110,13 @@ public void enable() { initConfig(); this.localeManager = new LocaleManager(this, "lang/mines"); -// initWorlds(); - this.mineManager = new MineManager(); -// getMineManager().loadFromDbCollection(this); - - // Player manager for mines is not used. -// this.player = new PlayerManager(); -// initMines(); PrisonAPI.getEventBus().register(new MinesListener()); setMinesCommands( new MinesCommands() ); Prison.get().getCommandHandler().registerCommands( getMinesCommands() ); - //Prison.get().getCommandHandler().registerCommands(new PowertoolCommands()); - - - // This is obsolete and was part of converting from pre-v3.0: - // ConversionManager.getInstance().registerConversionAgent(new MinesConversionAgent()); } @@ -142,8 +127,8 @@ public void enable() { */ @Override public void deferredStartup() { - // Load the mines at this time. - getMineManager().loadFromDbCollection(this); + // Load the mines at this time. + getMineManager().loadFromDbCollection(this); } @@ -160,8 +145,8 @@ public void deferredStartup() { @Override public void disable() { - // Shutdown the mines by saving any unsaved block stats: - getMineManager().saveMinesIfUnsavedBlockCounts(); + // Shutdown the mines by saving any unsaved block stats: + getMineManager().saveMinesIfUnsavedBlockCounts(); } @@ -190,14 +175,12 @@ private void initConfig() { File configFile = new File(getModuleDataFolder(), "config.json"); if (!configFile.exists()) { - getJsonFileIO().saveJsonFile( configFile, config ); - } else { - config = (MinesConfig) getJsonFileIO().readJsonFile( configFile, config ); + getJsonFileIO().saveJsonFile( configFile, config ); + } else { + config = (MinesConfig) getJsonFileIO().readJsonFile( configFile, config ); } } - - /** @@ -238,11 +221,8 @@ public Mine findMineLocation( Player player ) { String uuid = player.getUUID().toString(); -// Long playerUUIDLSB = Long.valueOf( player.getUUID().getLeastSignificantBits() ); - // Get the cached mine, if it exists: Mine mine = getPlayerCache().get( uuid ); -// Mine mine = getPlayerCache().get( playerUUIDLSB ); if ( mine != null && mine.isInMineIncludeTopBottomOfMine( player.getLocation() )) { results = mine; @@ -277,12 +257,6 @@ public Mine findMineLocation( Location blockLocation ) { return results; } -// private void initMines() { -//// mines = MineManager.fromDb(); -//// player = new PlayerManager(); -//// Prison.get().getPlatform().getScheduler().runTaskTimer(mines.getTimerTask(), 20, 20); -// } - /** *

Submit all mines to reset. This should only be called once since @@ -328,13 +302,13 @@ public void cancelResetAllMines() { * @return */ public int getElementCount() { - int results = isEnabled() ? 0 : -1; - - if ( isEnabled() ) { - results = getMines().size(); - } - - return results; + int results = isEnabled() ? 0 : -1; + + if ( isEnabled() ) { + results = getMines().size(); + } + + return results; } @@ -343,7 +317,6 @@ public JsonFileIO getJsonFileIO() return jsonFileIO; } - public MinesConfig getConfig() { return config; } @@ -372,14 +345,6 @@ public LocaleManager getMinesMessages() { return localeManager; } -// public List getWorlds() { -// return worlds; -// } - -// public PlayerManager getPlayerManager() { -// return player; -// } - public MinesCommands getMinesCommands() { return minesCommands; } @@ -387,5 +352,4 @@ public void setMinesCommands( MinesCommands minesCommands ) { this.minesCommands = minesCommands; } - } 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 1448f02cc..e70313179 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 @@ -43,13 +43,6 @@ public void addBlockCommand(CommandSender sender, Mine m = pMines.getMine(mineName); - // should be able manage blocks even if disabled or virtual: -// if ( !m.isEnabled() ) { -// sender.sendMessage( "&cMine is disabled&7. Use &a/mines info &7for possible cause." ); -// return; -// } - - block = block == null ? null : block.trim().toLowerCase(); PrisonBlock prisonBlock = null; @@ -57,45 +50,32 @@ public void addBlockCommand(CommandSender sender, PrisonBlockTypes prisonBlockTypes = Prison.get().getPlatform().getPrisonBlockTypes(); if ( block != null ) { - prisonBlock = prisonBlockTypes.getBlockTypesByName( block ); + prisonBlock = prisonBlockTypes.getBlockTypesByName( block ); } -// if ( block != null && prisonBlockTypes.getBlockTypesByName().containsKey( block ) ) { -// prisonBlock = prisonBlockTypes.getBlockTypesByName( block ); -// prisonBlock = prisonBlockTypes.getBlockTypesByName().get( block ); -// } if ( prisonBlock == null ) { - pMines.getMinesMessages().getLocalizable("not_a_block"). - withReplacements(block).sendTo(sender); - return; + pMines.getMinesMessages().getLocalizable("not_a_block"). + withReplacements(block).sendTo(sender); + return; } if ( prisonBlock.isSellallOnly() ) { - pMines.getMinesMessages().getLocalizable("not_a_block_sellall"). - withReplacements(block).sendTo(sender); - return; + pMines.getMinesMessages().getLocalizable("not_a_block_sellall"). + withReplacements(block).sendTo(sender); + return; } if ( !prisonBlock.isBlock() ) { - pMines.getMinesMessages().getLocalizable("not_a_block"). - withReplacements(block).sendTo(sender); - return; + pMines.getMinesMessages().getLocalizable("not_a_block"). + withReplacements(block).sendTo(sender); + return; } - -// if (m.isInMine(prisonBlock)) { -// pMines.getMinesMessages().getLocalizable("block_already_added"). -// sendTo(sender); -// return; -// } -// updateMinePrisonBlock( sender, m, prisonBlock, chance, pMines ); - getBlocksList(m, null, true ).send(sender); - //pMines.getMineManager().clearCache(); } private void updateMinePrisonBlock( CommandSender sender, Mine m, PrisonBlock prisonBlock, @@ -108,9 +88,9 @@ private void updateMinePrisonBlock( CommandSender sender, Mine m, PrisonBlock pr sender.sendMessage( "The percent chance must have a value greater than zero." ); } else { - - // Check if one of the blocks is effected by gravity, and if so, set that indicator. - m.checkGravityAffectedBlocks(); + + // Check if one of the blocks is effected by gravity, and if so, set that indicator. + m.checkGravityAffectedBlocks(); // Delete the block since it exists and the chance was set to zero: @@ -280,10 +260,6 @@ private void addBlockStats( Mine mine, PrisonBlockStatusData block, row.addFancy( msg4 ); } -// FancyMessage msg4 = new FancyMessage( String.format( (totals ? "&b%-9s" : " &3S: &7%-9s"), -// PlaceholdersUtil.formattedKmbtSISize( 1.0d * block.getBlockCountTotal(), dFmt, "" ) ) ) -// .tooltip( "&7Blocks of this type that have been mined since the server was &3S&7tarted." ); -// row.addFancy( msg4 ); builder.add( row ); @@ -341,12 +317,6 @@ public void setBlockCommand(CommandSender sender, PrisonMines pMines = PrisonMines.getInstance(); Mine m = pMines.getMine(mineName); - // you should be able to configure virtual and disabled mines -// if ( !m.isEnabled() ) { -// sender.sendMessage( "&cMine is disabled&7. Use &a/mines info &7for possible cause." ); -// return; -// } - block = block == null ? null : block.trim().toLowerCase(); @@ -355,86 +325,65 @@ public void setBlockCommand(CommandSender sender, PrisonBlockTypes prisonBlockTypes = Prison.get().getPlatform().getPrisonBlockTypes(); if ( block != null ) { - prisonBlock = prisonBlockTypes.getBlockTypesByName( block ); + prisonBlock = prisonBlockTypes.getBlockTypesByName( block ); } if ( block == null || prisonBlock == null ) { - sender.sendMessage( - String.format( "Invalid blockk name: [%s]", block ) ); - return; + 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)) { - addBlockCommand( sender, mineName, block, chance ); -// pMines.getMinesMessages().getLocalizable("block_not_removed") -// .sendTo(sender); - return; + addBlockCommand( sender, mineName, block, chance ); + return; } updateMinePrisonBlock( sender, m, prisonBlock, chance, pMines ); - getBlocksList(m, null, true ).send(sender); - //pMines.getMineManager().clearCache(); - } -// private BlockPercentTotal calculatePercentage( double chance, BlockType blockType, Mine m ) { -// BlockPercentTotal results = new BlockPercentTotal(); -// results.addChance( chance ); -// -// for ( BlockOld block : m.getBlocks() ) { -// if ( block.getType() == blockType ) { -// // do not replace the block's chance since this may fail -// results.setOldBlock( block ); -// } -// else { -// results.addChance( block.getChance() ); -// } -// } -// -// return results; -// } private BlockPercentTotal calculatePercentage( double chance, PrisonBlock prisonBlock, Mine m ) { - BlockPercentTotal results = new BlockPercentTotal(); - results.addChance( chance ); - - for ( PrisonBlock block : m.getPrisonBlocks() ) { - - // Only check the block's name: - if ( block.equals( prisonBlock ) ) { - // do not replace the block's chance since this may fail - results.setPrisonBlock( block ); - } - else { - results.addChance( block.getChance() ); - } - } - - if ( results.getPrisonBlock() == null ) { - prisonBlock.setChance( chance ); - results.setPrisonBlock( prisonBlock ); - } - return results; + BlockPercentTotal results = new BlockPercentTotal(); + results.addChance( chance ); + + for ( PrisonBlock block : m.getPrisonBlocks() ) { + + // Only check the block's name: + if ( block.equals( prisonBlock ) ) { + // do not replace the block's chance since this may fail + results.setPrisonBlock( block ); + } + else { + results.addChance( block.getChance() ); + } + } + + if ( results.getPrisonBlock() == null ) { + prisonBlock.setChance( chance ); + results.setPrisonBlock( prisonBlock ); + } + return results; } protected class BlockPercentTotal { - private double totalChance = 0d; -// private BlockOld oldBlock = null; - private PrisonBlock prisonBlock = null; - - public BlockPercentTotal() { - } - - public void addChance( double chance ) { - this.totalChance += chance; - } + private double totalChance = 0d; + + private PrisonBlock prisonBlock = null; + + public BlockPercentTotal() { + } + + public void addChance( double chance ) { + this.totalChance += chance; + } public double getTotalChance() { return totalChance; } @@ -442,14 +391,6 @@ public void setTotalChance( double totalChance ) { this.totalChance = totalChance; } - // Obsolete... the old block model: -// public BlockOld getOldBlock() { -// return oldBlock; -// } -// public void setOldBlock( BlockOld oldBlock ) { -// this.oldBlock = oldBlock; -// } - public PrisonBlock getPrisonBlock() { return prisonBlock; } @@ -474,7 +415,6 @@ public void delBlockCommand(CommandSender sender, Mine m = pMines.getMine(mineName); - block = block == null ? null : block.trim().toLowerCase(); PrisonBlock prisonBlock = null; @@ -482,29 +422,24 @@ public void delBlockCommand(CommandSender sender, PrisonBlockTypes prisonBlockTypes = Prison.get().getPlatform().getPrisonBlockTypes(); if ( block != null ) { - prisonBlock = prisonBlockTypes.getBlockTypesByName( block ); + prisonBlock = prisonBlockTypes.getBlockTypesByName( block ); } - // Cannot delete a block if it does not exist: -// if (!m.isInMine(prisonBlock)) { -// return; -// } // make sure the deleteBlock is deleting the actual block stored in the mine: PrisonBlock preexistingPrisonBlock = m.getPrisonBlock( prisonBlock ); if ( preexistingPrisonBlock != null ) { - - deleteBlock( sender, pMines, m, preexistingPrisonBlock ); + + deleteBlock( sender, pMines, m, preexistingPrisonBlock ); } else { - - pMines.getMinesMessages().getLocalizable("block_not_removed") - .sendTo(sender); - return; + + pMines.getMinesMessages().getLocalizable("block_not_removed") + .sendTo(sender); + return; } - getBlocksList(m, null, true).send(sender); } @@ -519,8 +454,8 @@ public void delBlockCommand(CommandSender sender, private void deleteBlock( CommandSender sender, PrisonMines pMines, Mine m, PrisonBlock prisonBlock ) { if ( m.removePrisonBlock( prisonBlock ) ) { - // Check if one of the blocks is effected by gravity, and if so, set that indicator. - m.checkGravityAffectedBlocks(); + // Check if one of the blocks is effected by gravity, and if so, set that indicator. + m.checkGravityAffectedBlocks(); pMines.getMineManager().saveMine( m ); @@ -530,81 +465,50 @@ private void deleteBlock( CommandSender sender, PrisonMines pMines, Mine m, Pris } -// /** -// * Delete only the first occurrence of a block with the given BlockType. -// * -// * @param sender -// * @param pMines -// * @param m -// * @param blockType -// */ -// private void deleteBlock( CommandSender sender, PrisonMines pMines, Mine m, BlockType blockType ) -// { -// BlockOld rBlock = null; -// for ( BlockOld block : m.getBlocks() ) { -// if ( block.getType() == blockType ) { -// rBlock = block; -// break; -// } -// } -// if ( m.getBlocks().remove( rBlock )) { -// -// // Check if one of the blocks is effected by gravity, and if so, set that indicator. -// m.checkGravityAffectedBlocks(); -// -// pMines.getMineManager().saveMine( m ); -// -// pMines.getMinesMessages().getLocalizable("block_deleted") -// .withReplacements(blockType.name(), m.getTag()).sendTo(sender); -// } -// } - public void searchBlockCommand(CommandSender sender, - String search, - String page, - String blockSeachCommand, - String commandBlockAdd, - String targetText ) { - - PrisonMines pMines = PrisonMines.getInstance(); - if (search == null) - { - pMines.getMinesMessages().getLocalizable("block_search_blank").sendTo(sender); - } - - ChatDisplay display = null; - - display = prisonBlockSearchBuilder(search, page, true, - blockSeachCommand, commandBlockAdd, targetText, - !sender.isPlayer() ); + String search, + String page, + String blockSeachCommand, + String commandBlockAdd, + String targetText ) { + + PrisonMines pMines = PrisonMines.getInstance(); + if (search == null) + { + pMines.getMinesMessages().getLocalizable("block_search_blank").sendTo(sender); + } + + ChatDisplay display = null; + + display = prisonBlockSearchBuilder(search, page, true, + blockSeachCommand, commandBlockAdd, targetText, + !sender.isPlayer() ); display.send(sender); - //pMines.getMineManager().clearCache(); } public void searchBlockAllCommand(CommandSender sender, - String search, - String page, - String blockSeachCommand, - String commandBlockAdd, - String targetText ) { - - PrisonMines pMines = PrisonMines.getInstance(); - if (search == null) - { - pMines.getMinesMessages().getLocalizable("block_search_blank").sendTo(sender); - } + String search, + String page, + String blockSeachCommand, + String commandBlockAdd, + String targetText ) { - ChatDisplay display = null; + PrisonMines pMines = PrisonMines.getInstance(); + if (search == null) + { + pMines.getMinesMessages().getLocalizable("block_search_blank").sendTo(sender); + } + + ChatDisplay display = null; + + display = prisonBlockSearchBuilder(search, page, false, + blockSeachCommand, commandBlockAdd, targetText, + !sender.isPlayer() ); + + display.send(sender); - display = prisonBlockSearchBuilder(search, page, false, - blockSeachCommand, commandBlockAdd, targetText, - !sender.isPlayer() ); - - display.send(sender); - - //pMines.getMineManager().clearCache(); } private ChatDisplay prisonBlockSearchBuilder(String search, String page, @@ -615,64 +519,44 @@ private ChatDisplay prisonBlockSearchBuilder(String search, String page, boolean console ) { - PrisonBlockTypes prisonBlockTypes = Prison.get().getPlatform().getPrisonBlockTypes(); - List blocks = prisonBlockTypes.getBlockTypes( search, restrictToBlocks ); - - CommandPagedData cmdPageData = new CommandPagedData( - "/" + commandBlockSearch + " " + search, blocks.size(), - 0, page ); - - // Same page logic as in mines info -// int curPage = 1; -// int pageSize = 10; -// int pages = (blocks.size() / pageSize) + 1; -// try -// { -// curPage = Integer.parseInt(page); -// } -// catch ( NumberFormatException e ) -// { -// // Ignore: Not an integer, will use the default value. -// } -// curPage = ( curPage < 1 ? 1 : (curPage > pages ? pages : curPage )); -// int pageStart = (curPage - 1) * pageSize; -// int pageEnd = ((pageStart + pageSize) > blocks.size() ? blocks.size() : pageStart + pageSize); - - - ChatDisplay display = new ChatDisplay("Block Search (" + blocks.size() + ")"); - display.addText("&8Click a block to add it to a " + targetText + "."); - - BulletedListComponent.BulletedListBuilder builder = - new BulletedListComponent.BulletedListBuilder(); - - int start = console ? 0 : cmdPageData.getPageStart(); - int end = console ? blocks.size() : cmdPageData.getPageEnd(); - for ( int i = start; i < end; i++ ) - { - PrisonBlock block = blocks.get(i); - FancyMessage msg = - new FancyMessage( - String.format("&7%s %s (%s)", - Integer.toString(i), block.getBlockNameSearch(), - (block.isBlock() ? "block" : "item") -// block.getAltName(), - )) - .suggest("/" + commandBlockAdd + " " + getLastMineReferenced() + - " " + block.getBlockNameSearch() + " %") - .tooltip("&7Click to add block to a " + targetText + "."); - builder.add(msg); - } - display.addComponent(builder.build()); - - // This command plus parameters used: -// String pageCmd = "/mines block search " + search; - - if ( !console ) { - - cmdPageData.generatePagedCommandFooter( display ); - } - - return display; + PrisonBlockTypes prisonBlockTypes = Prison.get().getPlatform().getPrisonBlockTypes(); + List blocks = prisonBlockTypes.getBlockTypes( search, restrictToBlocks ); + + CommandPagedData cmdPageData = new CommandPagedData( + "/" + commandBlockSearch + " " + search, blocks.size(), + 0, page ); + + + ChatDisplay display = new ChatDisplay("Block Search (" + blocks.size() + ")"); + display.addText("&8Click a block to add it to a " + targetText + "."); + + BulletedListComponent.BulletedListBuilder builder = + new BulletedListComponent.BulletedListBuilder(); + + int start = console ? 0 : cmdPageData.getPageStart(); + int end = console ? blocks.size() : cmdPageData.getPageEnd(); + for ( int i = start; i < end; i++ ) + { + PrisonBlock block = blocks.get(i); + FancyMessage msg = + new FancyMessage( + String.format("&7%s %s (%s)", + Integer.toString(i), block.getBlockNameSearch(), + (block.isBlock() ? "block" : "item") + )) + .suggest("/" + commandBlockAdd + " " + getLastMineReferenced() + + " " + block.getBlockNameSearch() + " %") + .tooltip("&7Click to add block to a " + targetText + "."); + builder.add(msg); + } + display.addComponent(builder.build()); + + if ( !console ) { + + cmdPageData.generatePagedCommandFooter( display ); + } + + return display; } @@ -686,8 +570,8 @@ public void listBlockCommand(CommandSender sender, Mine m = pMines.getMine(mineName); if ( m == null ) { - sender.sendMessage( "Invalid mine name." ); - return; + sender.sendMessage( "Invalid mine name." ); + return; } DecimalFormat dFmt = Prison.get().getDecimalFormatInt(); @@ -721,8 +605,8 @@ public void listBlockCommand(CommandSender sender, if ( blockSize == 0 ) { - String message = blockSize != 0 ? null : " &cNo Blocks Defined"; - chatDisplay.addText( message ); + String message = blockSize != 0 ? null : " &cNo Blocks Defined"; + chatDisplay.addText( message ); } chatDisplay.send(sender); @@ -743,124 +627,123 @@ public void constraintsBlockCommand(CommandSender sender, Mine m = pMines.getMine(mineName); if ( m == null ) { - sender.sendMessage( - String.format( "&7The specified mine named &3%s &7 does not exist. " + - "Please try again.", - (mineName == null ? "null" : mineName) )); - return; + sender.sendMessage( + String.format( "&7The specified mine named &3%s &7 does not exist. " + + "Please try again.", + (mineName == null ? "null" : mineName) )); + return; } if ( constraint == null || !"max".equalsIgnoreCase( constraint ) && !"min".equalsIgnoreCase( constraint ) && !"excludeTop".equalsIgnoreCase( constraint ) && !"excludeBottom".equalsIgnoreCase( constraint ) ) { - sender.sendMessage( - String.format( "Valid contraint values are [min max excludeTop excludeBottom]. " + - "ExcludeTop and ExcludeBottom are expressed in the number of layers. " + - "Was [%s]", - (constraint == null ? "null" : constraint) )); - listBlockCommand(sender, m.getTag() ); - return; + sender.sendMessage( + String.format( "Valid contraint values are [min max excludeTop excludeBottom]. " + + "ExcludeTop and ExcludeBottom are expressed in the number of layers. " + + "Was [%s]", + (constraint == null ? "null" : constraint) )); + listBlockCommand(sender, m.getTag() ); + return; } if ( blockName == null || !m.hasBlock( blockName ) ) { - sender.sendMessage( - String.format( "&7The block name &3%s &7 does not exist in the specified mine. " + - "Please try again.", - (blockName == null ? "null" : blockName) )); - listBlockCommand(sender, m.getTag() ); - return; + sender.sendMessage( + String.format( "&7The block name &3%s &7 does not exist in the specified mine. " + + "Please try again.", + (blockName == null ? "null" : blockName) )); + listBlockCommand(sender, m.getTag() ); + return; } if ( value < 0 ) { - sender.sendMessage( - String.format( "&7The specified value cannot be less than zero. [%s] " + - "Please try again.", - Integer.toString( value ) )); - listBlockCommand(sender, m.getTag() ); - return; + sender.sendMessage( + String.format( "&7The specified value cannot be less than zero. [%s] " + + "Please try again.", + Integer.toString( value ) )); + listBlockCommand(sender, m.getTag() ); + return; } if ( m.getBounds() != null && value > m.getBounds().getTotalBlockCount() ) { - sender.sendMessage( - String.format( "&7The specified value cannot be more than the total number " + - "of blocks in the mine. value = [%s] total blocks = [%s] " + - "Please try again.", - Integer.toString( value ), - Integer.toString( m.getBounds().getTotalBlockCount() ) )); - listBlockCommand(sender, m.getTag() ); - return; + sender.sendMessage( + String.format( "&7The specified value cannot be more than the total number " + + "of blocks in the mine. value = [%s] total blocks = [%s] " + + "Please try again.", + Integer.toString( value ), + Integer.toString( m.getBounds().getTotalBlockCount() ) )); + listBlockCommand(sender, m.getTag() ); + return; } - - PrisonBlockStatusData block = null; - - block = m.getPrisonBlock( blockName ); - - - - if ( "min".equalsIgnoreCase( constraint ) ) { - if ( block.getConstraintMax() != 0 && value > block.getConstraintMax() ) { - sender.sendMessage( - String.format( "&7The specified value for the min constraint cannot " + - "be more than the max constraint value. value = [%s] max= %s " + - "Please try again.", - Integer.toString( value ), - Integer.toString( block.getConstraintMax() ) )); - listBlockCommand(sender, m.getTag() ); - return; - - } - block.setConstraintMin( value ); - } - if ( "max".equalsIgnoreCase( constraint ) ) { - if ( block.getConstraintMin() != 0 && value < block.getConstraintMin() ) { - sender.sendMessage( - String.format( "&7The specified value for the max constraint cannot " + - "be less than the min constraint value. value = [%s] min= %s " + - "Please try again.", - Integer.toString( value ), - Integer.toString( block.getConstraintMin() ) )); - listBlockCommand(sender, m.getTag() ); - return; - - } - block.setConstraintMax( value ); - } - if ( "excludeTop".equalsIgnoreCase( constraint ) ) { - if ( block.getConstraintExcludeBottomLayers() != 0 && - value > block.getConstraintExcludeBottomLayers() ) { - sender.sendMessage( - String.format( "&7The specified value for the ExcludeTop layers constraint cannot " + - "be more than the ExcludeBottom layers constraint value. " + - "value = [%s] ExcludeBottom layers= %s " + - "Please try again.", - Integer.toString( value ), - Integer.toString( block.getConstraintExcludeBottomLayers() ) )); - listBlockCommand(sender, m.getTag() ); - return; - - } - block.setConstraintExcludeTopLayers( value ); - } - if ( "excludeBottom".equalsIgnoreCase( constraint ) ) { - if ( block.getConstraintExcludeTopLayers() != 0 && - value < block.getConstraintExcludeTopLayers() ) { - sender.sendMessage( - String.format( "&7The specified value for the ExcludeBottom layers constraint cannot " + - "be less than the ExcludeTop layers constraint value. " + - "value = [%s] ExcludeTop layers= %s " + - "Please try again.", - Integer.toString( value ), - Integer.toString( block.getConstraintExcludeTopLayers() ) )); - listBlockCommand(sender, m.getTag() ); - return; - - } - block.setConstraintExcludeBottomLayers( value ); - } - - + + PrisonBlockStatusData block = null; + + block = m.getPrisonBlock( blockName ); + + + + if ( "min".equalsIgnoreCase( constraint ) ) { + if ( block.getConstraintMax() != 0 && value > block.getConstraintMax() ) { + sender.sendMessage( + String.format( "&7The specified value for the min constraint cannot " + + "be more than the max constraint value. value = [%s] max= %s " + + "Please try again.", + Integer.toString( value ), + Integer.toString( block.getConstraintMax() ) )); + listBlockCommand(sender, m.getTag() ); + return; + + } + block.setConstraintMin( value ); + } + if ( "max".equalsIgnoreCase( constraint ) ) { + if ( block.getConstraintMin() != 0 && value < block.getConstraintMin() ) { + sender.sendMessage( + String.format( "&7The specified value for the max constraint cannot " + + "be less than the min constraint value. value = [%s] min= %s " + + "Please try again.", + Integer.toString( value ), + Integer.toString( block.getConstraintMin() ) )); + listBlockCommand(sender, m.getTag() ); + return; + + } + block.setConstraintMax( value ); + } + if ( "excludeTop".equalsIgnoreCase( constraint ) ) { + if ( block.getConstraintExcludeBottomLayers() != 0 && + value > block.getConstraintExcludeBottomLayers() ) { + sender.sendMessage( + String.format( "&7The specified value for the ExcludeTop layers constraint cannot " + + "be more than the ExcludeBottom layers constraint value. " + + "value = [%s] ExcludeBottom layers= %s " + + "Please try again.", + Integer.toString( value ), + Integer.toString( block.getConstraintExcludeBottomLayers() ) )); + listBlockCommand(sender, m.getTag() ); + return; + + } + block.setConstraintExcludeTopLayers( value ); + } + if ( "excludeBottom".equalsIgnoreCase( constraint ) ) { + if ( block.getConstraintExcludeTopLayers() != 0 && + value < block.getConstraintExcludeTopLayers() ) { + sender.sendMessage( + String.format( "&7The specified value for the ExcludeBottom layers constraint cannot " + + "be less than the ExcludeTop layers constraint value. " + + "value = [%s] ExcludeTop layers= %s " + + "Please try again.", + Integer.toString( value ), + Integer.toString( block.getConstraintExcludeTopLayers() ) )); + listBlockCommand(sender, m.getTag() ); + return; + + } + block.setConstraintExcludeBottomLayers( value ); + } + pMines.getMineManager().saveMine( m ); @@ -869,10 +752,8 @@ public void constraintsBlockCommand(CommandSender sender, m.getTag(), constraint, (value == 0 ? "disabled" : Integer.toString( value ) )); - sender.sendMessage( message ); - } @@ -890,30 +771,30 @@ public void preventDropsBlockCommand(CommandSender sender, String mineName, Stri boolean isPreventDrops = false; if ( m == null ) { - sender.sendMessage( - String.format( "&7The specified mine named &3%s &7 does not exist. " + - "Please try again.", - (mineName == null ? "null" : mineName) )); - return; + sender.sendMessage( + String.format( "&7The specified mine named &3%s &7 does not exist. " + + "Please try again.", + (mineName == null ? "null" : mineName) )); + return; } if ( blockName == null || !m.hasBlock( blockName ) ) { - sender.sendMessage( - String.format( "&7The block name &3%s &7 does not exist in the specified mine. " + - "Please try again.", - (blockName == null ? "null" : blockName) )); - listBlockCommand(sender, m.getTag() ); - return; + sender.sendMessage( + String.format( "&7The block name &3%s &7 does not exist in the specified mine. " + + "Please try again.", + (blockName == null ? "null" : blockName) )); + listBlockCommand(sender, m.getTag() ); + return; } if ( preventDrops == null || !preventDrops.equalsIgnoreCase("true") && !preventDrops.equalsIgnoreCase("false") ) { - sender.sendMessage( - String.format( "&7The parameter 'preventDrops' must be boolean: 'true' or 'false'. " - + "Found: [%s]", - (preventDrops == null ? "null" : preventDrops) )); - listBlockCommand(sender, m.getTag() ); - return; + sender.sendMessage( + String.format( "&7The parameter 'preventDrops' must be boolean: 'true' or 'false'. " + + "Found: [%s]", + (preventDrops == null ? "null" : preventDrops) )); + listBlockCommand(sender, m.getTag() ); + return; } @@ -968,7 +849,5 @@ public void listBlockLayerStatsCommand( CommandSender sender, String mineName ) } } - - } 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 2080e0824..e8e19ed5f 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 @@ -85,26 +85,26 @@ public MinesCommands() { @Command(identifier = "mines command", onlyPlayers = false, permissions = "prison.commands") public void mineCommandSubcommands(CommandSender sender) { - sender.dispatchCommand( "mines command help" ); + sender.dispatchCommand( "mines command help" ); } @Command(identifier = "mines set", onlyPlayers = false, permissions = "prison.commands") public void minesSetSubcommands(CommandSender sender) { - sender.dispatchCommand( "mines set help" ); + sender.dispatchCommand( "mines set help" ); } /* * NOTE: The mines import commands are from the class MinesImportCommands. - * The command handler setups is here, but the code is within that class. + * The command handler setups are here, but the code is within that class. */ @Command(identifier = "mines import", onlyPlayers = false, permissions = "prison.commands") public void mineImport(CommandSender sender) { - sender.dispatchCommand( "mines import help" ); + sender.dispatchCommand( "mines import help" ); } @Command(identifier = "mines import jetsPrisonMines", @@ -132,7 +132,7 @@ public void minesImportJetsPrisonMines( CommandSender sender, + "'save' must be specified or the imported mines will not be saved.") String options ) { - super.importJetsPrisonMines(sender, options); + super.importJetsPrisonMines(sender, options); } @@ -146,13 +146,13 @@ public void minesImportJetsPrisonMines( CommandSender sender, @Command(identifier = "mines block", onlyPlayers = false, permissions = "prison.commands") public void mineBlockSubcommands(CommandSender sender) { - sender.dispatchCommand( "mines block help" ); + sender.dispatchCommand( "mines block help" ); } @Command(identifier = "mines blockEvent", onlyPlayers = false, permissions = "prison.commands") public void mineBlockEventSubcommands(CommandSender sender) { - sender.dispatchCommand( "mines blockEvent help" ); + sender.dispatchCommand( "mines blockEvent help" ); } @Override @@ -166,7 +166,7 @@ public void addBlockCommand(CommandSender sender, @Arg(name = "chance", description = "The percent chance (out of 100) that this block will occur.") double chance) { - super.addBlockCommand( sender, mineName, block, chance ); + super.addBlockCommand( sender, mineName, block, chance ); } @@ -183,7 +183,7 @@ public void setBlockCommand(CommandSender sender, @Arg(name = "chance", description = "The percent chance (out of 100) that this block will occur.") double chance) { - super.setBlockCommand( sender, mineName, block, chance ); + super.setBlockCommand( sender, mineName, block, chance ); } @Override @@ -193,7 +193,7 @@ public void delBlockCommand(CommandSender sender, @Arg(name = "mineName", description = "The name of the mine to edit.") String mineName, @Arg(name = "block", def = "AIR", description = "The block's name") String block) { - super.delBlockCommand( sender, mineName, block ); + super.delBlockCommand( sender, mineName, block ); } @Command(identifier = "mines block search", permissions = "mines.block", @@ -208,7 +208,7 @@ public void searchBlockCommand(CommandSender sender, @Arg(name = "page", def = "1", description = "Page of search results (optional)") String page ) { - super.searchBlockCommand( sender, search, page, + super.searchBlockCommand( sender, search, page, "mines block search", "mines block add", "mine" ); @@ -220,7 +220,7 @@ public void searchBlockAllCommand(CommandSender sender, @Arg(name = "search", def = " ", description = "Any part of the block's, or item's name.") String search, @Arg(name = "page", def = "1", description = "Page of search results (optional)") String page ) { - super.searchBlockAllCommand( sender, search, page, + super.searchBlockAllCommand( sender, search, page, "mines block searchAll", "mines block add", "mine" ); @@ -233,7 +233,7 @@ public void listBlockLayerStatsCommand( CommandSender sender, @Arg(name = "mineName", description = "The name of the mine to generate block layer stats for.") String mineName ) { - super.listBlockLayerStatsCommand( sender, mineName ); + super.listBlockLayerStatsCommand( sender, mineName ); } @@ -243,7 +243,7 @@ public void listBlockLayerStatsCommand( CommandSender sender, public void listBlockCommand(CommandSender sender, @Arg(name = "mineName", description = "The name of the mine to view.") String mineName ) { - super.listBlockCommand( sender, mineName ); + super.listBlockCommand( sender, mineName ); } @Override @@ -263,7 +263,7 @@ public void constraintsBlockCommand(CommandSender sender, @Arg(name = "value", description = "The value to assign to this constraint. " + "A value of 0 will remove the constraint.") int value ) { - super.constraintsBlockCommand( sender, mineName, blockName, constraint, value ); + super.constraintsBlockCommand( sender, mineName, blockName, constraint, value ); } @@ -282,7 +282,7 @@ public void preventDropsBlockCommand(CommandSender sender, "[true false]", def = "false") String preventDrops ) { - super.preventDropsBlockCommand( sender, mineName, blockName, preventDrops ); + super.preventDropsBlockCommand( sender, mineName, blockName, preventDrops ); } @@ -309,61 +309,61 @@ public void createCommand(CommandSender sender, "you want to create. " + "[virtual noPlaceholderUpdate]") String options ) { - options = options == null ? "" : options.trim(); - - boolean virtual = mineName.toLowerCase().contains( "virtual" ); - if ( virtual && !options.isEmpty() ) { - // The option virtual was used in the mineName. Swap fields. - mineName = options.contains( " " ) ? options.split( " " )[0] : options; - } - else { - virtual = options.toLowerCase().contains( "virtual" ); - } - boolean updatePlaceholders = !options.toLowerCase().contains( "noplaceholderupdate" ); - - if ( mineName == null || mineName.contains( " " ) || mineName.trim().length() == 0 ) { - sendMessage( sender, "&3Names cannot contain spaces or be empty. &b[&d" + mineName + "&b]" ); - return; - } - mineName = mineName.trim(); - - Player player = sender.getPlatformPlayer(); - - if ( !virtual && (player == null || !player.isOnline())) { - sendMessage( sender, "&3You must be a player in the game to run this command. " + - "You also need to have selected an area with the `/mines wand` tool. " ); - return; - } - - PrisonMines pMines = PrisonMines.getInstance(); - - if (PrisonMines.getInstance().getMine(mineName) != null) { - pMines.getMinesMessages().getLocalizable("mine_exists") - .sendTo(sender, LogLevel.ERROR); - return; - } - - Selection selection = null; - - // virtual mine will skip the setting of the boundaries, but it will make - // the mine unusable. - if ( !virtual ) { - - selection = Prison.get().getSelectionManager().getSelection(player); - if (!selection.isComplete()) { - pMines.getMinesMessages().getLocalizable("select_bounds") - .sendTo(sender, LogLevel.ERROR); - return; - } - - if (!selection.getMin().getWorld().getName() - .equalsIgnoreCase(selection.getMax().getWorld().getName())) { - pMines.getMinesMessages().getLocalizable("world_diff") - .sendTo(sender, LogLevel.ERROR); - return; - } - } - + options = options == null ? "" : options.trim(); + + boolean virtual = mineName.toLowerCase().contains( "virtual" ); + if ( virtual && !options.isEmpty() ) { + // The option virtual was used in the mineName. Swap fields. + mineName = options.contains( " " ) ? options.split( " " )[0] : options; + } + else { + virtual = options.toLowerCase().contains( "virtual" ); + } + boolean updatePlaceholders = !options.toLowerCase().contains( "noplaceholderupdate" ); + + if ( mineName == null || mineName.contains( " " ) || mineName.trim().length() == 0 ) { + sendMessage( sender, "&3Names cannot contain spaces or be empty. &b[&d" + mineName + "&b]" ); + return; + } + mineName = mineName.trim(); + + Player player = sender.getPlatformPlayer(); + + if ( !virtual && (player == null || !player.isOnline())) { + sendMessage( sender, "&3You must be a player in the game to run this command. " + + "You also need to have selected an area with the `/mines wand` tool. " ); + return; + } + + PrisonMines pMines = PrisonMines.getInstance(); + + if (PrisonMines.getInstance().getMine(mineName) != null) { + pMines.getMinesMessages().getLocalizable("mine_exists") + .sendTo(sender, LogLevel.ERROR); + return; + } + + Selection selection = null; + + // virtual mine will skip the setting of the boundaries, but it will make + // the mine unusable. + if ( !virtual ) { + + selection = Prison.get().getSelectionManager().getSelection(player); + if (!selection.isComplete()) { + pMines.getMinesMessages().getLocalizable("select_bounds") + .sendTo(sender, LogLevel.ERROR); + return; + } + + if (!selection.getMin().getWorld().getName() + .equalsIgnoreCase(selection.getMax().getWorld().getName())) { + pMines.getMinesMessages().getLocalizable("world_diff") + .sendTo(sender, LogLevel.ERROR); + return; + } + } + setLastMineReferenced(mineName); @@ -376,27 +376,27 @@ public void createCommand(CommandSender sender, } if ( mine.isVirtual() ) { - sendMessage( sender, "&3Virtual mine created: use command " + - "&7'/mines set area help'&3 set an area within a world to " + - "enable as a normal mine." ); + sendMessage( sender, "&3Virtual mine created: use command " + + "&7'/mines set area help'&3 set an area within a world to " + + "enable as a normal mine." ); } else { - pMines.getMinesMessages().getLocalizable("mine_created").sendTo(sender); + pMines.getMinesMessages().getLocalizable("mine_created").sendTo(sender); } if ( !virtual && sender != null && sender instanceof Player ) { - // Delete the selection: - Prison.get().getSelectionManager().clearSelection((Player) sender); + // Delete the selection: + Prison.get().getSelectionManager().clearSelection((Player) sender); } } private void sendMessage( CommandSender sender, String message ) { - if ( sender == null ) { - Output.get().logInfo( message ); - } - else { - sender.sendMessage( message ); - } + if ( sender == null ) { + Output.get().logInfo( message ); + } + else { + sender.sendMessage( message ); + } } @Command(identifier = "mines rename", description = "Rename a mine.", @@ -411,35 +411,35 @@ public void renameCommand(CommandSender sender, return; } - if ( newName == null || newName.contains( " " ) || newName.trim().length() == 0 ) { - sender.sendMessage( "&3New mine name cannot contain spaces or be empty. &b[&d" + newName + "&b]" ); - return; - } - newName = newName.trim(); - - PrisonMines pMines = PrisonMines.getInstance(); - - if ( pMines.getMine(newName) != null ) { - sender.sendMessage( "&3Invalid new mine name. Another mine has that name. &b[&d" + newName + "&b]" ); - return; - - } - - Mine mine = pMines.getMine(mineName); - - setLastMineReferenced(newName); - - - pMines.getMineManager().rename(mine, newName); - - - Prison.get().getPlatform().getPlaceholders().reloadPlaceholders(); - - - sender.sendMessage( String.format( "&3Mine &d%s &3was successfully renamed to &d%s&3.", mineName, newName) ); - - pMines.getMinesMessages().getLocalizable("mine_created").sendTo(sender); - + if ( newName == null || newName.contains( " " ) || newName.trim().length() == 0 ) { + sender.sendMessage( "&3New mine name cannot contain spaces or be empty. &b[&d" + newName + "&b]" ); + return; + } + newName = newName.trim(); + + PrisonMines pMines = PrisonMines.getInstance(); + + if ( pMines.getMine(newName) != null ) { + sender.sendMessage( "&3Invalid new mine name. Another mine has that name. &b[&d" + newName + "&b]" ); + return; + + } + + Mine mine = pMines.getMine(mineName); + + setLastMineReferenced(newName); + + + pMines.getMineManager().rename(mine, newName); + + + Prison.get().getPlatform().getPlaceholders().reloadPlaceholders(); + + + sender.sendMessage( String.format( "&3Mine &d%s &3was successfully renamed to &d%s&3.", mineName, newName) ); + + pMines.getMinesMessages().getLocalizable("mine_created").sendTo(sender); + } @@ -454,48 +454,48 @@ public void mineAccessByRankCommand(CommandSender sender, @Arg(name = "mineName", description = "The name of the mine, or *all* for all mines. [*all*]") String mineName, @Arg(name = "enable", description = "Enable the mineAccessByRank: [enable, disable]") String enable ) { - if ( enable == null || !"enable".equalsIgnoreCase( enable ) && !"disable".equalsIgnoreCase( enable ) ) { - - sender.sendMessage( "&cInvalid option. &7The parameter &3enable &7can only have the values of " + - "'enable' or 'disable'. Please try again." ); - return; - } - - boolean accessEnabled = "enable".equalsIgnoreCase( enable ); - - PrisonMines pMines = PrisonMines.getInstance(); - - if ( mineName != null && "*all*".equalsIgnoreCase( mineName ) ) { - int minesUpdated = 0; - int minesNoChange = 0; - int minesWithNoRanks = 0; - - for ( Mine m :pMines.getMines() ) { - if ( m.getRank() == null ) { - minesWithNoRanks++; - } - else if ( m.isMineAccessByRank() == accessEnabled ) { - minesNoChange++; - } - else { - minesUpdated++; - - m.setMineAccessByRank( accessEnabled ); - pMines.getMineManager().saveMine(m); - } - } - - String message = String.format( "&7%s Mine Access by Rank changes were applied to all Mines. " + - "%d were updated. %d had no changes. %d had no ranks so could not be set.", - - (accessEnabled ? "Enabling" : "Disabling"), - minesUpdated, minesNoChange, minesWithNoRanks - ); - - sender.sendMessage( message ); - - return; - } + if ( enable == null || !"enable".equalsIgnoreCase( enable ) && !"disable".equalsIgnoreCase( enable ) ) { + + sender.sendMessage( "&cInvalid option. &7The parameter &3enable &7can only have the values of " + + "'enable' or 'disable'. Please try again." ); + return; + } + + boolean accessEnabled = "enable".equalsIgnoreCase( enable ); + + PrisonMines pMines = PrisonMines.getInstance(); + + if ( mineName != null && "*all*".equalsIgnoreCase( mineName ) ) { + int minesUpdated = 0; + int minesNoChange = 0; + int minesWithNoRanks = 0; + + for ( Mine m :pMines.getMines() ) { + if ( m.getRank() == null ) { + minesWithNoRanks++; + } + else if ( m.isMineAccessByRank() == accessEnabled ) { + minesNoChange++; + } + else { + minesUpdated++; + + m.setMineAccessByRank( accessEnabled ); + pMines.getMineManager().saveMine(m); + } + } + + String message = String.format( "&7%s Mine Access by Rank changes were applied to all Mines. " + + "%d were updated. %d had no changes. %d had no ranks so could not be set.", + + (accessEnabled ? "Enabling" : "Disabling"), + minesUpdated, minesNoChange, minesWithNoRanks + ); + + sender.sendMessage( message ); + + return; + } if (!performCheckMineExists(sender, mineName)) { return; @@ -538,49 +538,49 @@ public void tpAccessByRankCommand(CommandSender sender, @Arg(name = "mineName", description = "The name of the mine, or *all* for all mines. [*all*]") String mineName, @Arg(name = "enable", description = "Enable the tpAccessByRank: [enable, disable]") String enable ) { - if ( enable == null || !"enable".equalsIgnoreCase( enable ) && !"disable".equalsIgnoreCase( enable ) ) { - - sender.sendMessage( "&cInvalid option. &7The parameter &3enable &7can only have the values of " + - "'enable' or 'disable'. Please try again." ); - return; - } - - boolean accessEnabled = "enable".equalsIgnoreCase( enable ); - - PrisonMines pMines = PrisonMines.getInstance(); - - - if ( mineName != null && "*all*".equalsIgnoreCase( mineName ) ) { - int minesUpdated = 0; - int minesNoChange = 0; - int minesWithNoRanks = 0; - - for ( Mine m :pMines.getMines() ) { - if ( m.getRank() == null ) { - minesWithNoRanks++; - } - else if ( m.isTpAccessByRank() == accessEnabled ) { - minesNoChange++; - } - else { - minesUpdated++; - - m.setTpAccessByRank( accessEnabled ); - pMines.getMineManager().saveMine(m); - } - } - - String message = String.format( "&7%s Mine TP Access by Rank changes were applied to all Mines. " + - "%d were updated. %d had no changes. %d had no ranks so could not be set.", - - (accessEnabled ? "Enabling" : "Disabling"), - minesUpdated, minesNoChange, minesWithNoRanks - ); - - sender.sendMessage( message ); - - return; - } + if ( enable == null || !"enable".equalsIgnoreCase( enable ) && !"disable".equalsIgnoreCase( enable ) ) { + + sender.sendMessage( "&cInvalid option. &7The parameter &3enable &7can only have the values of " + + "'enable' or 'disable'. Please try again." ); + return; + } + + boolean accessEnabled = "enable".equalsIgnoreCase( enable ); + + PrisonMines pMines = PrisonMines.getInstance(); + + + if ( mineName != null && "*all*".equalsIgnoreCase( mineName ) ) { + int minesUpdated = 0; + int minesNoChange = 0; + int minesWithNoRanks = 0; + + for ( Mine m :pMines.getMines() ) { + if ( m.getRank() == null ) { + minesWithNoRanks++; + } + else if ( m.isTpAccessByRank() == accessEnabled ) { + minesNoChange++; + } + else { + minesUpdated++; + + m.setTpAccessByRank( accessEnabled ); + pMines.getMineManager().saveMine(m); + } + } + + String message = String.format( "&7%s Mine TP Access by Rank changes were applied to all Mines. " + + "%d were updated. %d had no changes. %d had no ranks so could not be set.", + + (accessEnabled ? "Enabling" : "Disabling"), + minesUpdated, minesNoChange, minesWithNoRanks + ); + + sender.sendMessage( message ); + + return; + } if (!performCheckMineExists(sender, mineName)) { return; @@ -590,15 +590,15 @@ else if ( m.isTpAccessByRank() == accessEnabled ) { if ( mine.getRank() == null ) { - sender.sendMessage( "&cThis mine must be linked to a Rank before you can enable this feature." ); - return; + sender.sendMessage( "&cThis mine must be linked to a Rank before you can enable this feature." ); + return; } if ( mine.isTpAccessByRank() == accessEnabled ) { - sender.sendMessage( - String.format( "&cInvalid setting. &7The mine's setting tpAccessByRank has not been " + - "changed. The mine already is set to the value of: [%s]", enable ) ); - return; + sender.sendMessage( + String.format( "&cInvalid setting. &7The mine's setting tpAccessByRank has not been " + + "changed. The mine already is set to the value of: [%s]", enable ) ); + return; } @@ -621,12 +621,12 @@ public void spawnpointCommand(CommandSender sender, @Arg(name = "options", def = "set", description = "Options: Option to set or remove a spawn. [set *remove*]") String options ) { - Player player = sender.getPlatformPlayer(); - - if (player == null || !player.isOnline()) { - sender.sendMessage( "&3You must be a player in the game to run this command." ); - return; - } + Player player = sender.getPlatformPlayer(); + + if (player == null || !player.isOnline()) { + sender.sendMessage( "&3You must be a player in the game to run this command." ); + return; + } if (!performCheckMineExists(sender, mineName)) { return; @@ -637,13 +637,13 @@ public void spawnpointCommand(CommandSender sender, if ( mine.isVirtual() ) { - sender.sendMessage( "&cMine is a virtual mine&7. Use &a/mines set area &7to enable the mine." ); - return; + sender.sendMessage( "&cMine is a virtual mine&7. Use &a/mines set area &7to enable the mine." ); + return; } if ( !mine.isEnabled() ) { - sender.sendMessage( "&cMine is disabled&7. Use &a/mines info &7for possible cause." ); - return; + sender.sendMessage( "&cMine is disabled&7. Use &a/mines info &7for possible cause." ); + return; } if (!mine.getWorld().isPresent()) { @@ -663,13 +663,13 @@ public void spawnpointCommand(CommandSender sender, setLastMineReferenced(mineName); if ( options != null && options.toLowerCase().contains( "*remove*" ) ) { - mine.setSpawn( null ); - pMines.getMinesMessages().getLocalizable("spawn_removed").sendTo(sender); + mine.setSpawn( null ); + pMines.getMinesMessages().getLocalizable("spawn_removed").sendTo(sender); } else { - mine.setSpawn(((Player) sender).getLocation()); - pMines.getMinesMessages().getLocalizable("spawn_set").sendTo(sender); + mine.setSpawn(((Player) sender).getLocation()); + pMines.getMinesMessages().getLocalizable("spawn_set").sendTo(sender); } pMines.getMineManager().saveMine(mine); @@ -688,12 +688,12 @@ public void tagCommand(CommandSender sender, } if ( tag == null || tag.trim().length() == 0 ) { - sender.sendMessage( "&cTag name must be a valid value. To remove use a value of &anull&c." ); - return; + sender.sendMessage( "&cTag name must be a valid value. To remove use a value of &anull&c." ); + return; } if ( tag.equalsIgnoreCase( "null" ) ) { - tag = null; + tag = null; } PrisonMines pMines = PrisonMines.getInstance(); @@ -703,8 +703,8 @@ public void tagCommand(CommandSender sender, mine.getTag() != null && mine.getTag().equalsIgnoreCase( tag )) { - sender.sendMessage( "&cThe new tag name is the same as what it was. No change was made." ); - return; + sender.sendMessage( "&cThe new tag name is the same as what it was. No change was made." ); + return; } mine.setTag( tag ); @@ -715,14 +715,14 @@ public void tagCommand(CommandSender sender, if ( tag == null ) { - sender.sendMessage( - String.format( "&cThe tag name was cleared for the mine %s.", - mine.getTag() ) ); + sender.sendMessage( + String.format( "&cThe tag name was cleared for the mine %s.", + mine.getTag() ) ); } else { - sender.sendMessage( - String.format( "&cThe tag name was changed to %s for the mine %s.", - tag, mine.getTag() ) ); + sender.sendMessage( + String.format( "&cThe tag name was changed to %s for the mine %s.", + tag, mine.getTag() ) ); } } @@ -738,18 +738,18 @@ public void sortOrderCommand(CommandSender sender, "of -1 or [supress] will prevent the mine from beign included in most listings.", def = "0" ) String sortOrder ) { - int order = 0; - - if (!performCheckMineExists(sender, mineName)) { - return; - } - - if ( sortOrder == null ) { - sortOrder = "0"; - } - else if ( "suppress".equalsIgnoreCase( sortOrder.trim() ) ) { - sortOrder = "-1"; - } + int order = 0; + + if (!performCheckMineExists(sender, mineName)) { + return; + } + + if ( sortOrder == null ) { + sortOrder = "0"; + } + else if ( "suppress".equalsIgnoreCase( sortOrder.trim() ) ) { + sortOrder = "-1"; + } try { order = Integer.parseInt( sortOrder ); @@ -764,26 +764,26 @@ else if ( "suppress".equalsIgnoreCase( sortOrder.trim() ) ) { order = -1; } - PrisonMines pMines = PrisonMines.getInstance(); - Mine mine = pMines.getMine(mineName); - - if ( order == mine.getSortOrder()) { - sender.sendMessage( "&cThe new sort order is the same as what it was. No change was made." ); - return; - } - - mine.setSortOrder( order ); - - setLastMineReferenced(mineName); - - pMines.getMineManager().saveMine(mine); - - String suppressedMessage = order == -1 ? "This mine will be suppressed from most listings." : ""; - sender.sendMessage( - String.format( "&cThe sort order was changed to %s for the mine %s. %s", - Integer.toString( mine.getSortOrder() ), mine.getTag(), - suppressedMessage ) ); - + PrisonMines pMines = PrisonMines.getInstance(); + Mine mine = pMines.getMine(mineName); + + if ( order == mine.getSortOrder()) { + sender.sendMessage( "&cThe new sort order is the same as what it was. No change was made." ); + return; + } + + mine.setSortOrder( order ); + + setLastMineReferenced(mineName); + + pMines.getMineManager().saveMine(mine); + + String suppressedMessage = order == -1 ? "This mine will be suppressed from most listings." : ""; + sender.sendMessage( + String.format( "&cThe sort order was changed to %s for the mine %s. %s", + Integer.toString( mine.getSortOrder() ), mine.getTag(), + suppressedMessage ) ); + } @@ -800,73 +800,70 @@ public void deleteCommand(CommandSender sender, // They have 1 minute to confirm. long now = System.currentTimeMillis(); if ( getConfirmTimestamp() != null && ((now - getConfirmTimestamp()) < 1000 * 60 ) && - confirm != null && "confirm".equalsIgnoreCase( confirm )) { - setConfirmTimestamp( null ); - - PrisonMines pMines = PrisonMines.getInstance(); - - Mine mine = pMines.getMine(mineName); - - // should be able to delete disabled and virtual mines: -// if ( !mine.isEnabled() ) { -// sender.sendMessage( "&cMine is disabled&7. Use &a/mines info &7for possible cause." ); -// return; -// } - - // Remove from the manager: - pMines.getMineManager().removeMine(mine); - - // Terminate the running task for mine resets. Will allow it to be garbage collected. - mine.terminateJob(); - - setLastMineReferenced(null); - - - Prison.get().getPlatform().getPlaceholders().reloadPlaceholders(); - - - pMines.getMinesMessages().getLocalizable("mine_deleted").sendTo(sender); - - } + confirm != null && "confirm".equalsIgnoreCase( confirm )) { + + setConfirmTimestamp( null ); + + PrisonMines pMines = PrisonMines.getInstance(); + + Mine mine = pMines.getMine(mineName); + + // Remove from the manager: + pMines.getMineManager().removeMine(mine); + + // Terminate the running task for mine resets. Will allow it to be garbage collected. + mine.terminateJob(); + + setLastMineReferenced(null); + + + Prison.get().getPlatform().getPlaceholders().reloadPlaceholders(); + + + pMines.getMinesMessages().getLocalizable("mine_deleted").sendTo(sender); + + } else if ( getConfirmTimestamp() == null || ((now - getConfirmTimestamp()) >= 1000 * 60 ) ) { - setConfirmTimestamp( now ); - - ChatDisplay chatDisplay = new ChatDisplay("&cDelete " + mineName); - BulletedListComponent.BulletedListBuilder builder = new BulletedListComponent.BulletedListBuilder(); - builder.add( new FancyMessage( - "&3Confirm the deletion of this mine" ) - .suggest("/mines delete " + mineName + " cancel")); - - builder.add( new FancyMessage( - "&3Click &eHERE&3 to display the command" ) - .suggest("/mines delete " + mineName + " cancel")); - - builder.add( new FancyMessage( - "&3Enter: &7/mines delete " + mineName + " confirm" ) - .suggest("/mines delete " + mineName + " cancel")); - - builder.add( new FancyMessage( - "&3Then change &ecancel&3 to &econfirm&3." ) - .suggest("/mines delete " + mineName + " cancel")); - - builder.add( new FancyMessage("You have 1 minute to respond.")); - - chatDisplay.addComponent(builder.build()); - chatDisplay.send(sender); + setConfirmTimestamp( now ); + + ChatDisplay chatDisplay = new ChatDisplay("&cDelete " + mineName); + BulletedListComponent.BulletedListBuilder builder = new BulletedListComponent.BulletedListBuilder(); + builder.add( new FancyMessage( + "&3Confirm the deletion of this mine" ) + .suggest("/mines delete " + mineName + " cancel")); + + builder.add( new FancyMessage( + "&3Click &eHERE&3 to display the command" ) + .suggest("/mines delete " + mineName + " cancel")); + + builder.add( new FancyMessage( + "&3Enter: &7/mines delete " + mineName + " confirm" ) + .suggest("/mines delete " + mineName + " cancel")); + + builder.add( new FancyMessage( + "&3Then change &ecancel&3 to &econfirm&3." ) + .suggest("/mines delete " + mineName + " cancel")); + + builder.add( new FancyMessage("You have 1 minute to respond.")); + + chatDisplay.addComponent(builder.build()); + chatDisplay.send(sender); - } else if (confirm != null && "cancel".equalsIgnoreCase( confirm )) { - setConfirmTimestamp( null ); + } + else if (confirm != null && "cancel".equalsIgnoreCase( confirm )) { - ChatDisplay display = new ChatDisplay("&cDelete " + mineName); + setConfirmTimestamp( null ); + + ChatDisplay display = new ChatDisplay("&cDelete " + mineName); display.addText("&8Delete canceled."); display.send( sender ); } else { - ChatDisplay display = new ChatDisplay("&cDelete " + mineName); - display.addText("&8Delete confirmation failed. Try again."); - - display.send( sender ); + ChatDisplay display = new ChatDisplay("&cDelete " + mineName); + display.addText("&8Delete confirmation failed. Try again."); + + display.send( sender ); } } @@ -880,6 +877,7 @@ public void infoCommand(CommandSender sender, @Arg(name = "page", def = "1", description = "Page of search results (optional) [1-n, ALL]") String page ) { + if (!performCheckMineExists(sender, mineName)) { return; } @@ -888,7 +886,7 @@ public void infoCommand(CommandSender sender, setLastMineReferenced(mineName); PrisonMines pMines = PrisonMines.getInstance(); - MineManager mMan = pMines.getMineManager(); + MineManager mMan = pMines.getMineManager(); Mine m = pMines.getMine(mineName); @@ -900,23 +898,6 @@ public void infoCommand(CommandSender sender, 1, page ); -// // Same page logic as in mines block search: -// int curPage = 1; -// int pageSize = 10; -// int pages = (m.getBlocks().size() / pageSize) + 1; -// try -// { -// curPage = Integer.parseInt(page); -// } -// catch ( NumberFormatException e ) -// { -// // Ignore: Not an integer, will use the default value. -// } -// curPage = ( curPage < 1 ? 1 : (curPage > pages ? pages : curPage )); -// int pageStart = (curPage - 1) * pageSize; -// int pageEnd = ((pageStart + pageSize) > m.getBlocks().size() ? m.getBlocks().size() : pageStart + pageSize); - - ChatDisplay chatDisplay = mineInfoDetails( sender, mMan.isMineStats(), m, cmdPageData ); @@ -929,42 +910,34 @@ public void infoCommand(CommandSender sender, chatDisplay.send(sender); - // If show all, then include the mine's commands and blockEvents: - // These are different commands, so they will be in different chatDisplay objects - // so cannot weave them together: - // if ( cmdPageData.isShowAll() ) { - //commandList( sender, m.getName() ); - - //blockEventList( sender, m.getName() ); - // } } public void allMinesInfoDetails( StringBuilder sb ) { - PrisonMines pMines = PrisonMines.getInstance(); - MineManager mMan = pMines.getMineManager(); - - List mines = new ArrayList<>(); - mines.addAll( mMan.getMines() ); - Collections.sort( mines ); - - for ( Mine mine : mines ) { - - Prison.get().getPrisonStatsUtil().printFooter( sb ); - - JumboTextFont.makeJumboFontText( mine.getName(), sb ); - sb.append( "\n" ); - - CommandPagedData cmdPageData = new CommandPagedData( - "/mines info " + mine.getName(), mine.getPrisonBlocks().size(), - 1, "all" ); - - ChatDisplay chatDisplay = mineInfoDetails( null, mMan.isMineStats(), mine, cmdPageData ); - - sb.append( chatDisplay.toStringBuilder() ); - } - - Prison.get().getPrisonStatsUtil().printFooter( sb ); + PrisonMines pMines = PrisonMines.getInstance(); + MineManager mMan = pMines.getMineManager(); + + List mines = new ArrayList<>(); + mines.addAll( mMan.getMines() ); + Collections.sort( mines ); + + for ( Mine mine : mines ) { + + Prison.get().getPrisonStatsUtil().printFooter( sb ); + + JumboTextFont.makeJumboFontText( mine.getName(), sb ); + sb.append( "\n" ); + + CommandPagedData cmdPageData = new CommandPagedData( + "/mines info " + mine.getName(), mine.getPrisonBlocks().size(), + 1, "all" ); + + ChatDisplay chatDisplay = mineInfoDetails( null, mMan.isMineStats(), mine, cmdPageData ); + + sb.append( chatDisplay.toStringBuilder() ); + } + + Prison.get().getPrisonStatsUtil().printFooter( sb ); } @@ -978,409 +951,374 @@ private ChatDisplay mineInfoDetails( CommandSender sender, boolean isMineStats, chatDisplay.addSupportHyperLinkData( "Mine %s", m.getName() ); { - RowComponent row = new RowComponent(); - row.addTextComponent("&7Server runtime: %s ", - Prison.get().getServerRuntimeFormatted() ); - - double tps = Prison.get().getPrisonTPS().getAverageTPS(); - String tpsFmt = tps >= 18.5 ? "&a" : - tps >= 16.0 ? "&e" : - tps >= 14.0 ? "&6" : - "&c"; - row.addTextComponent("&7TPS: %s%s", - tpsFmt, - fFmt.format( tps)); - - chatDisplay.addComponent( row ); + RowComponent row = new RowComponent(); + row.addTextComponent("&7Server runtime: %s ", + Prison.get().getServerRuntimeFormatted() ); + + double tps = Prison.get().getPrisonTPS().getAverageTPS(); + String tpsFmt = tps >= 18.5 ? "&a" : + tps >= 16.0 ? "&e" : + tps >= 14.0 ? "&6" : + "&c"; + row.addTextComponent("&7TPS: %s%s", + tpsFmt, + fFmt.format( tps)); + + chatDisplay.addComponent( row ); } // Display Mine Info only: if ( cmdPageData.getCurPage() == 1 ) { - if ( m.isVirtual() ) { - chatDisplay.addText("&cWarning!! This mine is &lVirtual&r&c!! &7Use &3/mines set area &7to enable." ); - } - - if ( !m.isEnabled() ) { - chatDisplay.addText("&cWarning!! This mine is &lDISABLED&r&c!!" ); - } - - - boolean mineAccessByRank = m.isMineAccessByRank(); - boolean tpAccessByRank = m.isTpAccessByRank(); - - if ( mineAccessByRank && tpAccessByRank ) { - RowComponent row = new RowComponent(); - row.addTextComponent( "&3Mine Access by Rank. TP Access by Rank." ); - chatDisplay.addComponent( row ); - } - else if ( !mineAccessByRank && tpAccessByRank ) { - RowComponent row = new RowComponent(); - row.addTextComponent( "&3TP Access by Rank." ); - chatDisplay.addComponent( row ); - } - if ( mineAccessByRank && !tpAccessByRank ) { - RowComponent row = new RowComponent(); - row.addTextComponent( "&3Mine Access by Rank." ); - chatDisplay.addComponent( row ); - } - - if ( !mineAccessByRank ) { - RowComponent row = new RowComponent(); - row.addTextComponent( "&3Mine Access Permission: &7%s &3(Consider using Access by Rank)", - ( m.getAccessPermission() == null ? "&2none" : m.getAccessPermission() ) ); - chatDisplay.addComponent( row ); - } - - - { - RowComponent row = new RowComponent(); - - String noTagMessag = String.format( "&7(not set)" ); - row.addTextComponent("&3Tag: &7%-11s ", - m.getTag() == null ? noTagMessag : m.getTag()); - - if ( m.getRank() == null ) { - row.addTextComponent( "&3No rank is linked to this mine." ); - } - else { - row.addTextComponent( "&3Rank: &7%s", m.getRank() ); - } - - - chatDisplay.addComponent( row ); - } - - - - - - if ( !m.isVirtual() ) { - String worldName = m.getWorld().isPresent() ? m.getWorld().get().getName() : "&cmissing"; - Player player = sender == null ? null : sender.getPlatformPlayer(); - chatDisplay.addText("&3World: &7%-10s &3Center: &7%s &3%s &7%s", - worldName, - m.getBounds().getCenter().toBlockCoordinates(), - (player == null ? "" : "Distance:"), - (player == null ? "" : fFmt.format( m.getBounds().getDistance3d( player.getLocation() ) )) - ); - - - String minCoords = m.getBounds().getMin().toBlockCoordinates(); - String maxCoords = m.getBounds().getMax().toBlockCoordinates(); - chatDisplay.addText("&3Bounds: &7%s &8to &7%s", minCoords, maxCoords); - - String spawnPoint = m.getSpawn() != null ? m.getSpawn().toBlockCoordinates() : "&cnot set"; - chatDisplay.addText("&3Spawnpoint: &7%s", spawnPoint); - - } - - - - -// chatDisplay.text("&3Size: &7%d&8x&7%d&8x&7%d", Math.round(m.getBounds().getWidth()), -// Math.round(m.getBounds().getHeight()), Math.round(m.getBounds().getLength())); - - if ( !m.isVirtual() ) { - RowComponent row = new RowComponent(); - row.addTextComponent( "&3Size: &7%d&8x&7%d&8x&7%d ", Math.round(m.getBounds().getWidth()), - Math.round(m.getBounds().getHeight()), Math.round(m.getBounds().getLength()) ); - - row.addTextComponent( "&3Volume: &7%s &3Blocks", - dFmt.format( Math.round(m.getBounds().getTotalBlockCount())) ); - chatDisplay.addComponent( row ); - } - - - if ( !m.isVirtual() ) { - RowComponent row = new RowComponent(); - row.addTextComponent( "&3Blocks Remaining: &7%s %s%% ", - dFmt.format( m.getRemainingBlockCount() ), - fFmt.format( m.getPercentRemainingBlockCount() ) ); - - chatDisplay.addComponent( row ); - } - - - { - RowComponent row = new RowComponent(); - row.addTextComponent( "&3Liner: &7%s", - m.getLinerData().toInfoString() ); - chatDisplay.addComponent( row ); - } - - - - if ( !cmdPageData.isShowAll() ) { - RowComponent row = new RowComponent(); - row.addTextComponent( "&3Mine Command Count: &7%d &3BlockEvent Count: &7%d", - m.getResetCommands().size(), - m.getBlockEvents().size() ); - chatDisplay.addComponent( row ); - } - - - - - int resetTime = m.getResetTime(); - - if ( resetTime <= 0 ) { - RowComponent row = new RowComponent(); - - row.addTextComponent( "&3Automatic Resets are &7Disabled" ); - chatDisplay.addComponent( row ); - } - else { - RowComponent row = new RowComponent(); - double rtMinutes = resetTime / 60.0D; - row.addTextComponent( - "&3Reset time: &7%s &3Secs (&7%.2f &3Mins) Reset Count: &7%s ", - Integer.toString(resetTime), - rtMinutes, - dFmt.format(m.getResetCount()) ); - chatDisplay.addComponent( row ); - } - -// { -// RowComponent row = new RowComponent(); -// row.addTextComponent( "&3Mine Reset Count: &7%s ", -// dFmt.format(m.getResetCount()) ); -// -//// if ( m.isUsePagingOnReset() ) { -//// row.addTextComponent( " &7-= &5Reset Paging Enabled &7=-" ); -//// } -//// else if ( cmdPageData.isShowAll() ) { -//// row.addTextComponent( " &7-= &3Reset Paging Disabled &7=-" ); -//// } -// -// chatDisplay.addComponent( row ); -// -//// double resetTimeSeconds = m.getStatsResetTimeMS() / 1000.0; -//// if ( !m.isUsePagingOnReset() && resetTimeSeconds > 0.5 ) { -//// String resetTimeSec = PlaceholdersUtil.formattedTime( resetTimeSeconds ); -//// chatDisplay.addText("&5 Warning: &3Reset time is &7%s&3, which is high. " + -//// "It is recommened that you try to enable &7/mines set resetPaging help", -//// resetTimeSec ); -//// } -// } - - if ( !m.isVirtual() && resetTime > 0 ) { - RowComponent row = new RowComponent(); - - long targetResetTime = m.getTargetResetTime(); - double remaining = ( targetResetTime <= 0 ? 0d : - (targetResetTime - System.currentTimeMillis()) / 1000d); - double rtMinutes = remaining / 60.0D; - - row.addTextComponent( "&3Time Until Next Reset: &7%s &3Secs (&7%.2f &3Mins)", - dFmt.format( remaining ), rtMinutes ); - chatDisplay.addComponent( row ); - } - - - - - if ( !m.isVirtual() ) { - if ( m.getResetThresholdPercent() == 0 && cmdPageData.isShowAll() ) { - RowComponent row = new RowComponent(); - row.addTextComponent( "&3Reset Threshold: &cDISABLED"); - chatDisplay.addComponent( row ); - } - else if ( m.getResetThresholdPercent() > 0 ) { - RowComponent row = new RowComponent(); - - double blocks = m.getBounds().getTotalBlockCount() * - m.getResetThresholdPercent() / 100.0d; - row.addTextComponent( "&3Reset Threshold: &7%s &3Percent (&7%s &3blocks)", - fFmt.format( m.getResetThresholdPercent() ), - dFmt.format( blocks ) ); - chatDisplay.addComponent( row ); - } - - } - - - - { - - if ( m.isZeroBlockResetDisabled() && cmdPageData.isShowAll() ) { - RowComponent row = new RowComponent(); - row.addTextComponent( "&3Reset Delay: &cDISABLED"); - chatDisplay.addComponent( row ); - } - else if ( !m.isZeroBlockResetDisabled() ) { - RowComponent row = new RowComponent(); - if ( m.getResetThresholdPercent() == 0 ) { - row.addTextComponent( "&3Reset Delay (zero blocks): &7%s &3Seconds", - fFmt.format( m.getZeroBlockResetDelaySec() )); - } - else { - row.addTextComponent( "&3Reset Delay (&s Percent Threshold): &7%s &3Seconds", - fFmt.format( m.getResetThresholdPercent() ), - fFmt.format( m.getZeroBlockResetDelaySec() )); - } - chatDisplay.addComponent( row ); - } - - } - - - - - if ( resetTime > 0 && m.isSkipResetEnabled() ) { - RowComponent row = new RowComponent(); - row.addTextComponent( - "&3Reset Skip: &2Enabled&3: &3Threshold: &7%s &3SkipLimit: &7%s &3SkipCount: &7%s", - fFmt.format( m.getSkipResetPercent() ), - dFmt.format( m.getSkipResetBypassLimit() ), - dFmt.format( m.getSkipResetBypassCount() ) ); - chatDisplay.addComponent( row ); - -// if ( m.getSkipResetBypassCount() > 0 ) { -// RowComponent row2 = new RowComponent(); -// row2.addTextComponent( " &3Skipping Enabled: Skip Count: &7%s", -// dFmt.format( m.getSkipResetBypassCount() )); -// chatDisplay.addComponent( row2 ); -// } - } - else if ( resetTime > 0 && cmdPageData.isShowAll() ) { - RowComponent row = new RowComponent(); - row.addTextComponent( "&3Reset Skip if no Mining Activity: &cnot enabled"); - chatDisplay.addComponent( row ); - } - - - - if ( resetTime > 0 ) - { - RowComponent row = new RowComponent(); - row.addTextComponent( "&3Notification Mode: &7%s &7%s", - m.getNotificationMode().name(), - ( m.getNotificationMode() == MineNotificationMode.radius ? - dFmt.format( m.getNotificationRadius() ) + " blocks" : "" ) ); - chatDisplay.addComponent( row ); - } - - if ( resetTime > 0 && m.isUseNotificationPermission() || - resetTime > 0 && !m.isUseNotificationPermission() && cmdPageData.isShowAll() ) { - RowComponent row = new RowComponent(); - row.addTextComponent( "&3Notifications Filtered by Permissions: %s", - ( m.isUseNotificationPermission() ? - m.getMineNotificationPermissionName() : "&dDisabled" ) ); - chatDisplay.addComponent( row ); - } - - - - - - if ( m.isMineSweeperEnabled() ) { - - // stats for mine sweeper activity: - long mineSweeperAvgMs = ( m.getMineSweeperCount() == 0 ? 0 : m.getMineSweeperTotalMs() / m.getMineSweeperCount()); - - String mineSweeperBlks = PlaceholdersUtil.formattedKmbtSISize(m.getMineSweeperBlocksChanged(), fFmt, " " ); - - // Format with input requiring seconds: - String totalRunTime = PlaceholdersUtil.formattedTime( m.getMineSweeperTotalMs() / 1000d ); - - RowComponent row = new RowComponent(); - row.addTextComponent( "&3Mine Sweeper: &2Enabled&3: runs: %s Avg ms: %s Time: %s Blks: %s ", - dFmt.format( m.getMineSweeperCount() ), dFmt.format( mineSweeperAvgMs ), - totalRunTime, - mineSweeperBlks ); - chatDisplay.addComponent( row ); - - if ( m.getStatsMineSweeperTaskMs().size() > 0 ) { - RowComponent row2 = new RowComponent(); - row2.addTextComponent( "&3 %s ", m.statsMessageMineSweeper() ); - chatDisplay.addComponent( row2 ); - } - - } - else if ( cmdPageData.isShowAll() ) { - RowComponent row = new RowComponent(); - row.addTextComponent( "&3Mine Sweeper: &cDisabled&3 "); - chatDisplay.addComponent( row ); - } - - - - - String statsMsg = m.statsMessage(); - if ( !m.isVirtual() && (cmdPageData.isShowAll() || isMineStats) && - statsMsg != null && statsMsg.length() > 0 ) { - - int idx = statsMsg.indexOf("BlockUpdateTime:"); - int idx2 = statsMsg.indexOf("ResetPages:", idx); - - String stats1 = statsMsg.substring(0, idx ); - String stats2 = statsMsg.substring( idx, idx2 ); - String stats3 = statsMsg.substring( idx2 ); - - { - RowComponent rowStats = new RowComponent(); - rowStats.addTextComponent( " -- &7 Reset Stats :: &3" ); - rowStats.addTextComponent( stats1 ); - chatDisplay.addComponent(rowStats); - } - { - RowComponent rowStats = new RowComponent(); - rowStats.addTextComponent( " -- &7 Reset Stats :: &3" ); - rowStats.addTextComponent( stats2 ); - chatDisplay.addComponent(rowStats); - } - { - RowComponent rowStats = new RowComponent(); - rowStats.addTextComponent( " -- &7 Reset Stats :: &3" ); - rowStats.addTextComponent( stats3 ); - chatDisplay.addComponent(rowStats); - } - - -// rowStats.addTextComponent( m.statsMessage() ); - } - - - - if ( m.getResetCommands() != null && m.getResetCommands().size() > 0 ) { -// RowComponent row = new RowComponent(); -// row.addTextComponent( "&3Reset Commands: &7%s ", -// dFmt.format( m.getResetCommands().size() ) ); - - BulletedListComponent.BulletedListBuilder builder = new BulletedListComponent.BulletedListBuilder(); - - FancyMessage msg = new FancyMessage(String.format("&3Reset Commands: &7%s", - dFmt.format( m.getResetCommands().size() ))) - .suggest("/mines command list " + m.getName()) - .tooltip("&7Click to list to view the reset commands."); - - builder.add(msg); - - chatDisplay.addComponent( builder.build() ); - } - - + if ( m.isVirtual() ) { + chatDisplay.addText("&cWarning!! This mine is &lVirtual&r&c!! &7Use &3/mines set area &7to enable." ); + } + + if ( !m.isEnabled() ) { + chatDisplay.addText("&cWarning!! This mine is &lDISABLED&r&c!!" ); + } + + + boolean mineAccessByRank = m.isMineAccessByRank(); + boolean tpAccessByRank = m.isTpAccessByRank(); + + if ( mineAccessByRank && tpAccessByRank ) { + RowComponent row = new RowComponent(); + row.addTextComponent( "&3Mine Access by Rank. TP Access by Rank." ); + chatDisplay.addComponent( row ); + } + else if ( !mineAccessByRank && tpAccessByRank ) { + RowComponent row = new RowComponent(); + row.addTextComponent( "&3TP Access by Rank." ); + chatDisplay.addComponent( row ); + } + if ( mineAccessByRank && !tpAccessByRank ) { + RowComponent row = new RowComponent(); + row.addTextComponent( "&3Mine Access by Rank." ); + chatDisplay.addComponent( row ); + } + + if ( !mineAccessByRank ) { + RowComponent row = new RowComponent(); + row.addTextComponent( "&3Mine Access Permission: &7%s &3(Consider using Access by Rank)", + ( m.getAccessPermission() == null ? "&2none" : m.getAccessPermission() ) ); + chatDisplay.addComponent( row ); + } + + + { + RowComponent row = new RowComponent(); + + String noTagMessag = String.format( "&7(not set)" ); + row.addTextComponent("&3Tag: &7%-11s ", + m.getTag() == null ? noTagMessag : m.getTag()); + + if ( m.getRank() == null ) { + row.addTextComponent( "&3No rank is linked to this mine." ); + } + else { + row.addTextComponent( "&3Rank: &7%s", m.getRank() ); + } + + + chatDisplay.addComponent( row ); + } + + + + + + if ( !m.isVirtual() ) { + String worldName = m.getWorld().isPresent() ? m.getWorld().get().getName() : "&cmissing"; + Player player = sender == null ? null : sender.getPlatformPlayer(); + chatDisplay.addText("&3World: &7%-10s &3Center: &7%s &3%s &7%s", + worldName, + m.getBounds().getCenter().toBlockCoordinates(), + (player == null ? "" : "Distance:"), + (player == null ? "" : fFmt.format( m.getBounds().getDistance3d( player.getLocation() ) )) + ); + + + String minCoords = m.getBounds().getMin().toBlockCoordinates(); + String maxCoords = m.getBounds().getMax().toBlockCoordinates(); + chatDisplay.addText("&3Bounds: &7%s &8to &7%s", minCoords, maxCoords); + + String spawnPoint = m.getSpawn() != null ? m.getSpawn().toBlockCoordinates() : "&cnot set"; + chatDisplay.addText("&3Spawnpoint: &7%s", spawnPoint); + + } + + + + + if ( !m.isVirtual() ) { + RowComponent row = new RowComponent(); + row.addTextComponent( "&3Size: &7%d&8x&7%d&8x&7%d ", Math.round(m.getBounds().getWidth()), + Math.round(m.getBounds().getHeight()), Math.round(m.getBounds().getLength()) ); + + row.addTextComponent( "&3Volume: &7%s &3Blocks", + dFmt.format( Math.round(m.getBounds().getTotalBlockCount())) ); + chatDisplay.addComponent( row ); + } + + + if ( !m.isVirtual() ) { + RowComponent row = new RowComponent(); + row.addTextComponent( "&3Blocks Remaining: &7%s %s%% ", + dFmt.format( m.getRemainingBlockCount() ), + fFmt.format( m.getPercentRemainingBlockCount() ) ); + + chatDisplay.addComponent( row ); + } + + + { + RowComponent row = new RowComponent(); + row.addTextComponent( "&3Liner: &7%s", + m.getLinerData().toInfoString() ); + chatDisplay.addComponent( row ); + } + + + + if ( !cmdPageData.isShowAll() ) { + RowComponent row = new RowComponent(); + row.addTextComponent( "&3Mine Command Count: &7%d &3BlockEvent Count: &7%d", + m.getResetCommands().size(), + m.getBlockEvents().size() ); + chatDisplay.addComponent( row ); + } + + + + + int resetTime = m.getResetTime(); + + if ( resetTime <= 0 ) { + RowComponent row = new RowComponent(); + + row.addTextComponent( "&3Automatic Resets are &7Disabled" ); + chatDisplay.addComponent( row ); + } + else { + RowComponent row = new RowComponent(); + double rtMinutes = resetTime / 60.0D; + row.addTextComponent( + "&3Reset time: &7%s &3Secs (&7%.2f &3Mins) Reset Count: &7%s ", + Integer.toString(resetTime), + rtMinutes, + dFmt.format(m.getResetCount()) ); + chatDisplay.addComponent( row ); + } + + + if ( !m.isVirtual() && resetTime > 0 ) { + RowComponent row = new RowComponent(); + + long targetResetTime = m.getTargetResetTime(); + double remaining = ( targetResetTime <= 0 ? 0d : + (targetResetTime - System.currentTimeMillis()) / 1000d); + double rtMinutes = remaining / 60.0D; + + row.addTextComponent( "&3Time Until Next Reset: &7%s &3Secs (&7%.2f &3Mins)", + dFmt.format( remaining ), rtMinutes ); + chatDisplay.addComponent( row ); + } + + + + + if ( !m.isVirtual() ) { + if ( m.getResetThresholdPercent() == 0 && cmdPageData.isShowAll() ) { + RowComponent row = new RowComponent(); + row.addTextComponent( "&3Reset Threshold: &cDISABLED"); + chatDisplay.addComponent( row ); + } + else if ( m.getResetThresholdPercent() > 0 ) { + RowComponent row = new RowComponent(); + + double blocks = m.getBounds().getTotalBlockCount() * + m.getResetThresholdPercent() / 100.0d; + row.addTextComponent( "&3Reset Threshold: &7%s &3Percent (&7%s &3blocks)", + fFmt.format( m.getResetThresholdPercent() ), + dFmt.format( blocks ) ); + chatDisplay.addComponent( row ); + } + + } + + + + { + + if ( m.isZeroBlockResetDisabled() && cmdPageData.isShowAll() ) { + RowComponent row = new RowComponent(); + row.addTextComponent( "&3Reset Delay: &cDISABLED"); + chatDisplay.addComponent( row ); + } + else if ( !m.isZeroBlockResetDisabled() ) { + RowComponent row = new RowComponent(); + if ( m.getResetThresholdPercent() == 0 ) { + row.addTextComponent( "&3Reset Delay (zero blocks): &7%s &3Seconds", + fFmt.format( m.getZeroBlockResetDelaySec() )); + } + else { + row.addTextComponent( "&3Reset Delay (&s Percent Threshold): &7%s &3Seconds", + fFmt.format( m.getResetThresholdPercent() ), + fFmt.format( m.getZeroBlockResetDelaySec() )); + } + chatDisplay.addComponent( row ); + } + + } + + + + + if ( resetTime > 0 && m.isSkipResetEnabled() ) { + RowComponent row = new RowComponent(); + row.addTextComponent( + "&3Reset Skip: &2Enabled&3: &3Threshold: &7%s &3SkipLimit: &7%s &3SkipCount: &7%s", + fFmt.format( m.getSkipResetPercent() ), + dFmt.format( m.getSkipResetBypassLimit() ), + dFmt.format( m.getSkipResetBypassCount() ) ); + chatDisplay.addComponent( row ); + + } + else if ( resetTime > 0 && cmdPageData.isShowAll() ) { + RowComponent row = new RowComponent(); + row.addTextComponent( "&3Reset Skip if no Mining Activity: &cnot enabled"); + chatDisplay.addComponent( row ); + } + + + + if ( resetTime > 0 ) + { + RowComponent row = new RowComponent(); + row.addTextComponent( "&3Notification Mode: &7%s &7%s", + m.getNotificationMode().name(), + ( m.getNotificationMode() == MineNotificationMode.radius ? + dFmt.format( m.getNotificationRadius() ) + " blocks" : "" ) ); + chatDisplay.addComponent( row ); + } + + if ( resetTime > 0 && m.isUseNotificationPermission() || + resetTime > 0 && !m.isUseNotificationPermission() && cmdPageData.isShowAll() ) { + RowComponent row = new RowComponent(); + row.addTextComponent( "&3Notifications Filtered by Permissions: %s", + ( m.isUseNotificationPermission() ? + m.getMineNotificationPermissionName() : "&dDisabled" ) ); + chatDisplay.addComponent( row ); + } + + + + + + if ( m.isMineSweeperEnabled() ) { + + // stats for mine sweeper activity: + long mineSweeperAvgMs = ( m.getMineSweeperCount() == 0 ? 0 : m.getMineSweeperTotalMs() / m.getMineSweeperCount()); + + String mineSweeperBlks = PlaceholdersUtil.formattedKmbtSISize(m.getMineSweeperBlocksChanged(), fFmt, " " ); + + // Format with input requiring seconds: + String totalRunTime = PlaceholdersUtil.formattedTime( m.getMineSweeperTotalMs() / 1000d ); + + RowComponent row = new RowComponent(); + row.addTextComponent( "&3Mine Sweeper: &2Enabled&3: runs: %s Avg ms: %s Time: %s Blks: %s ", + dFmt.format( m.getMineSweeperCount() ), dFmt.format( mineSweeperAvgMs ), + totalRunTime, + mineSweeperBlks ); + chatDisplay.addComponent( row ); + + if ( m.getStatsMineSweeperTaskMs().size() > 0 ) { + RowComponent row2 = new RowComponent(); + row2.addTextComponent( "&3 %s ", m.statsMessageMineSweeper() ); + chatDisplay.addComponent( row2 ); + } + + } + else if ( cmdPageData.isShowAll() ) { + RowComponent row = new RowComponent(); + row.addTextComponent( "&3Mine Sweeper: &cDisabled&3 "); + chatDisplay.addComponent( row ); + } + + + + + String statsMsg = m.statsMessage(); + if ( !m.isVirtual() && (cmdPageData.isShowAll() || isMineStats) && + statsMsg != null && statsMsg.length() > 0 ) { + + int idx = statsMsg.indexOf("BlockUpdateTime:"); + int idx2 = statsMsg.indexOf("ResetPages:", idx); + + String stats1 = statsMsg.substring(0, idx ); + String stats2 = statsMsg.substring( idx, idx2 ); + String stats3 = statsMsg.substring( idx2 ); + + { + RowComponent rowStats = new RowComponent(); + rowStats.addTextComponent( " -- &7 Reset Stats :: &3" ); + rowStats.addTextComponent( stats1 ); + chatDisplay.addComponent(rowStats); + } + { + RowComponent rowStats = new RowComponent(); + rowStats.addTextComponent( " -- &7 Reset Stats :: &3" ); + rowStats.addTextComponent( stats2 ); + chatDisplay.addComponent(rowStats); + } + { + RowComponent rowStats = new RowComponent(); + rowStats.addTextComponent( " -- &7 Reset Stats :: &3" ); + rowStats.addTextComponent( stats3 ); + chatDisplay.addComponent(rowStats); + } + + + } + + + + if ( m.getResetCommands() != null && m.getResetCommands().size() > 0 ) { + + BulletedListComponent.BulletedListBuilder builder = new BulletedListComponent.BulletedListBuilder(); + + FancyMessage msg = new FancyMessage(String.format("&3Reset Commands: &7%s", + dFmt.format( m.getResetCommands().size() ))) + .suggest("/mines command list " + m.getName()) + .tooltip("&7Click to list to view the reset commands."); + + builder.add(msg); + + chatDisplay.addComponent( builder.build() ); + } + + } if ( cmdPageData.isShowAll() || cmdPageData.getCurPage() > 1 ) { - chatDisplay.addText("&3Blocks:"); - chatDisplay.addText("&8Click on a block's name to edit its chances of appearing..." ); - - BulletedListComponent list = getBlocksList(m, cmdPageData, true ); - chatDisplay.addComponent(list); + chatDisplay.addText("&3Blocks:"); + chatDisplay.addText("&8Click on a block's name to edit its chances of appearing..." ); + + BulletedListComponent list = getBlocksList(m, cmdPageData, true ); + chatDisplay.addComponent(list); } if ( cmdPageData.isShowAll() ) { - // Include all the commands for this mine: - ChatDisplay commandDisplay = minesCommandList( m ); - chatDisplay.addChatDisplay( commandDisplay ); - + // Include all the commands for this mine: + ChatDisplay commandDisplay = minesCommandList( m ); + chatDisplay.addChatDisplay( commandDisplay ); + - // Include all the blockEvent commands: + // Include all the blockEvent commands: ChatDisplay blockEventDisplay = new ChatDisplay("BlockEvent Commands for Mine " + m.getTag()); blockEventDisplay.addText("&8Hover over values for more information and clickable actions."); @@ -1418,43 +1356,43 @@ public void resetCommand(CommandSender sender, boolean force = false; if ( options.contains( "nocommands" )) { - options = options.replace( "nocommands", "" ).trim(); - resetActions.add( MineResetActions.NO_COMMANDS ); + options = options.replace( "nocommands", "" ).trim(); + resetActions.add( MineResetActions.NO_COMMANDS ); } if ( options.contains( "details" ) ) { - options = options.replace( "details", "" ).trim(); - resetActions.add( MineResetActions.DETAILS ); + options = options.replace( "details", "" ).trim(); + resetActions.add( MineResetActions.DETAILS ); } if ( options.contains( "force" ) ) { - options = options.replace( "force", "" ).trim(); - force = true; + options = options.replace( "force", "" ).trim(); + force = true; } // The value of chained is an internal value and should not be shown to users: if ( options.contains( "chained" ) ) { - options = options.replace( "chained", "" ).trim(); - resetActions.add( MineResetActions.CHAINED_RESETS ); + options = options.replace( "chained", "" ).trim(); + resetActions.add( MineResetActions.CHAINED_RESETS ); } if ( !options.trim().isEmpty() ) { - sender.sendMessage( "&cInvalid value for &7options&c. " + - "&3The only valid options are: [&7noCommands details&3] or blanks. " + - "[&7" + options + "&3] mine = [&7" + mineName + "&3]" ); - return; + sender.sendMessage( "&cInvalid value for &7options&c. " + + "&3The only valid options are: [&7noCommands details&3] or blanks. " + + "[&7" + options + "&3] mine = [&7" + mineName + "&3]" ); + return; } PrisonMines pMines = PrisonMines.getInstance(); if ( mineName != null && "*all*".equalsIgnoreCase( mineName ) ) { - pMines.resetAllMines( resetType, resetActions ); - return; + pMines.resetAllMines( resetType, resetActions ); + return; } if ( mineName != null && "*cancel*".equalsIgnoreCase( mineName ) ) { - pMines.cancelResetAllMines(); - return; + pMines.cancelResetAllMines(); + return; } @@ -1469,50 +1407,50 @@ public void resetCommand(CommandSender sender, if ( m.isVirtual() ) { - sender.sendMessage( "&cInvalid option. This mine is a virtual mine&7. Use &a/mines set area &7to enable the mine." ); - return; + sender.sendMessage( "&cInvalid option. This mine is a virtual mine&7. Use &a/mines set area &7to enable the mine." ); + return; } if ( !m.isEnabled() ) { - sender.sendMessage( "&cMine is disabled&7. Use &a/mines info &7for possible cause." ); - return; + sender.sendMessage( "&cMine is disabled&7. Use &a/mines info &7for possible cause." ); + return; } if ( !m.getMineStateMutex().isMinable() && force ) { - sender.sendMessage( - String.format( - "&cMine is currently being reset. &7An unlock is being forced to allow " - + "a new reset." ) - ); - - // Force the reset by setting the mineResetStartTimestamp to 10 mins ago: - m.setMineResetStartTimestamp( System.currentTimeMillis() - 10 * 60000 ); + sender.sendMessage( + String.format( + "&cMine is currently being reset. &7An unlock is being forced to allow " + + "a new reset." ) + ); + + // Force the reset by setting the mineResetStartTimestamp to 10 mins ago: + m.setMineResetStartTimestamp( System.currentTimeMillis() - 10 * 60000 ); } else if ( !m.getMineStateMutex().isMinable() ) { - long resetDuration = m.getMineResetStartTimestamp() == -1 ? 0 : + long resetDuration = m.getMineResetStartTimestamp() == -1 ? 0 : System.currentTimeMillis() - m.getMineResetStartTimestamp(); - DecimalFormat dFmt = Prison.get().getDecimalFormatDouble(); - - sender.sendMessage( - String.format( - "&cMine is currently being reset. &7Will try to force an unlock to allow " - + "a new reset. May have to wait 3 minutes before the Mutex is releasable. " - + "The mine was reset %s seconds ago.", - dFmt.format( resetDuration / 1000.0d ) ) + DecimalFormat dFmt = Prison.get().getDecimalFormatDouble(); + + sender.sendMessage( + String.format( + "&cMine is currently being reset. &7Will try to force an unlock to allow " + + "a new reset. May have to wait 3 minutes before the Mutex is releasable. " + + "The mine was reset %s seconds ago.", + dFmt.format( resetDuration / 1000.0d ) ) ); } try { - m.manualReset( resetType, resetActions ); + m.manualReset( resetType, resetActions ); } catch (Exception e) { - pMines.getMinesMessages().getLocalizable("mine_reset_fail") - .withReplacements( m.getName() ) - .sendTo(sender); + pMines.getMinesMessages().getLocalizable("mine_reset_fail") + .withReplacements( m.getName() ) + .sendTo(sender); Output.get().logError("Couldn't reset mine " + mineName, e); return; } @@ -1532,40 +1470,40 @@ public void listCommand(CommandSender sender, @Arg(name = "page", def = "1", description = "Page of search results (optional) [1-n, ALL]") String page ) { - Player player = sender.getPlatformPlayer(); - - MineSortOrder sortOrder = MineSortOrder.fromString( sort ); - - // If sort was invalid, double check to see if it is a page number or ALL: - if ( sortOrder == MineSortOrder.invalid ) { - sortOrder = MineSortOrder.sortOrder; - - if ( sort != null && "ALL".equalsIgnoreCase( sort )) { - // The user did not specify a sort order, but instead this is the page number - // so fix it for them: - page = "ALL"; - } - else if ( sort != null ) { - try { - int test = Integer.parseInt( sort ); - - // This is actually the page number so default to alpha sort: - page = Integer.toString( test ); - } - catch ( NumberFormatException e ) { - // Oof... this isn't a page number, so report an error. - sender.sendMessage( "Invalid sort order. Use a valid sort order " + - "or a page number such as [1-n, ALL]" ); - } - } - } - - ChatDisplay display = new ChatDisplay("Mines"); - display.addText("&8Click a mine's name to see more information."); - - - getMinesList( display, sortOrder, page, player ); - + Player player = sender.getPlatformPlayer(); + + MineSortOrder sortOrder = MineSortOrder.fromString( sort ); + + // If sort was invalid, double check to see if it is a page number or ALL: + if ( sortOrder == MineSortOrder.invalid ) { + sortOrder = MineSortOrder.sortOrder; + + if ( sort != null && "ALL".equalsIgnoreCase( sort )) { + // The user did not specify a sort order, but instead this is the page number + // so fix it for them: + page = "ALL"; + } + else if ( sort != null ) { + try { + int test = Integer.parseInt( sort ); + + // This is actually the page number so default to alpha sort: + page = Integer.toString( test ); + } + catch ( NumberFormatException e ) { + // Oof... this isn't a page number, so report an error. + sender.sendMessage( "Invalid sort order. Use a valid sort order " + + "or a page number such as [1-n, ALL]" ); + } + } + } + + ChatDisplay display = new ChatDisplay("Mines"); + display.addText("&8Click a mine's name to see more information."); + + + getMinesList( display, sortOrder, page, player ); + display.send(sender); @@ -1574,30 +1512,22 @@ else if ( sort != null ) { public void getMinesList( ChatDisplay display, MineSortOrder sortOrder, String page, Player player ) { PrisonMines pMines = PrisonMines.getInstance(); - MineManager mMan = pMines.getMineManager(); - - - // Get mines in the correct sorted order and suppress the mines if they should - PrisonSortableResults sortedMines = pMines.getMines( sortOrder ); - - display.addText( "&3 Mines listed: &7%s &3Mines suppressed: &7%s", - sortedMines.getSortedList().size(), - sortedMines.getSortedSuppressedList().size()); - - if ( sortedMines.getSortedSuppressedList().size() > 0 ) { - display.addText( "&8To view suppressed mines sort by: %s", - sortedMines.getSuppressedListSortTypes() ); - } + MineManager mMan = pMines.getMineManager(); + + + // Get mines in the correct sorted order and suppress the mines if they should + PrisonSortableResults sortedMines = pMines.getMines( sortOrder ); + + display.addText( "&3 Mines listed: &7%s &3Mines suppressed: &7%s", + sortedMines.getSortedList().size(), + sortedMines.getSortedSuppressedList().size()); + + if ( sortedMines.getSortedSuppressedList().size() > 0 ) { + display.addText( "&8To view suppressed mines sort by: %s", + sortedMines.getSuppressedListSortTypes() ); + } -// // Sort first by name, then blocks mined so final sort order will be: -// // Most blocks mined, then alphabetical -// mineList.sort( (a, b) -> a.getName().compareToIgnoreCase( b.getName()) ); -// -// // for now hold off on sorting by total blocks mined. -// if ( "active".equalsIgnoreCase( sort )) { -// mineList.sort( (a, b) -> Long.compare(b.getTotalBlocksMined(), a.getTotalBlocksMined()) ); -// } CommandPagedData cmdPageData = new CommandPagedData( "/mines list " + sortOrder.name(), sortedMines.getSortedList().size(), @@ -1606,10 +1536,9 @@ public void getMinesList( ChatDisplay display, MineSortOrder sortOrder, String p BulletedListComponent list = getMinesLineItemList(sortedMines, player, cmdPageData, mMan.isMineStats()); - display.addComponent(list); - - cmdPageData.generatePagedCommandFooter( display ); - + display.addComponent(list); + + cmdPageData.generatePagedCommandFooter( display ); } @@ -1617,231 +1546,193 @@ public void getMinesList( ChatDisplay display, MineSortOrder sortOrder, String p private BulletedListComponent getMinesLineItemList( PrisonSortableResults sortedMines, Player player, CommandPagedData cmdPageData, boolean isMineStatsEnabled ) { - BulletedListComponent.BulletedListBuilder builder = - new BulletedListComponent.BulletedListBuilder(); - - - DecimalFormat dFmt = Prison.get().getDecimalFormatInt(); - DecimalFormat fFmt = Prison.get().getDecimalFormat("#,##0.00"); - - int count = 0; + BulletedListComponent.BulletedListBuilder builder = + new BulletedListComponent.BulletedListBuilder(); + + + DecimalFormat dFmt = Prison.get().getDecimalFormatInt(); + DecimalFormat fFmt = Prison.get().getDecimalFormat("#,##0.00"); + + int count = 0; for (Mine m : sortedMines.getSortedList()) { if ( cmdPageData == null || count++ >= cmdPageData.getPageStart() && count <= cmdPageData.getPageEnd() ) { - RowComponent row = new RowComponent(); - - //row.addTextComponent( m.getWorldName() + " " ); - - if ( m.getSortOrder() < 1 ) { -// row.addTextComponent( " " ); - -// row.addFancy( -// new FancyMessage( String.format("&3(&b%s&3) ", -// "X") ) -// .tooltip("&7Sort order: Suppressed")); - } - else { - row.addFancy( - new FancyMessage( String.format("&3(&b%s&3) ", - Integer.toString( m.getSortOrder() )) ) - .tooltip("&7Sort order.")); - } - - - String name = m.getName(); - if ( name.length() < 6 ) { - name += " ".substring( 0, (6-name.length()) ); - } - row.addFancy( - new FancyMessage( String.format("&7%s ", name) ) - .command("/mines info " + m.getName()) - .tooltip("&7Mine " + m.getTag() + ": Click to view more info.")); - - - if ( m.getTag() != null && m.getTag().trim().length() > 0 ) { - String tag = m.getTag(); - String tagNoColor = Text.stripColor( tag ); - if ( tagNoColor.length() < 6 ) { - tag += " ".substring( 0, (6 - tagNoColor.length()) ); - } - row.addTextComponent( "%s ", tag ); - } - - - if ( !m.isVirtual() ) { - row.addFancy( - new FancyMessage("&eTP ").command("/mines tp " + m.getName()) - .tooltip("&7Click to TP to the mine")); - } - - - row.addTextComponent( " &3(&2R: " ); - - if ( !m.isVirtual() && m.getResetTime() > 0 ) { - row.addFancy( - new FancyMessage( - String.format( "&7%s &3sec &3/ ", dFmt.format(m.getRemainingTimeSec()))) - - .tooltip( "Estimated time in seconds before the mine resets" ) ); -// row.addTextComponent( " sec &3(&b" ); - } - - - if ( m.getResetTime() <= 0 ) { - - row.addFancy( - new FancyMessage( - String.format( "&7disabled )&b" )) - .tooltip( "Auto resets have been disabled." ) ); - } - else { - - row.addFancy( - new FancyMessage( - String.format( "&7%s &3sec )&b", dFmt.format(m.getResetTime()) )) - .tooltip( "Reset time in seconds" ) ); - } -// row.addTextComponent( " sec&3)&b" ); - - if ( !m.isVirtual() && player != null && - m.getBounds().withinSameWorld( player.getLocation() ) ) { - - double distance = m.getBounds().getDistance3d(player.getLocation()); - -// row.addTextComponent( " &3Dist: &7"); - row.addFancy( - new FancyMessage( - String.format( " &3Dist: &7%s", fFmt.format( distance )) ). - tooltip("Distance to the Mine") ); - - } - - //builder.add(row.getFancy()); - - if ( m.isVirtual() ) { - - row.addTextComponent( "&6Virtual Mine" ); - } - - else { -// RowComponent row2 = new RowComponent(); -// row2.addTextComponent( " &3Rem: " ); - - // Right justify the total blocks mined, with 1000's separators: - String blocksMined = " " + dFmt.format( m.getTotalBlocksMined() ); -// String blocksMined = " " + dFmt.format( m.getTotalBlocksMined() ); - blocksMined = blocksMined.substring( blocksMined.length() - 8); - - row.addFancy( - new FancyMessage( String.format(" %s &3Rem: ", blocksMined)). - tooltip( "Blocks mined" ) ); - - row.addFancy( - new FancyMessage(fFmt.format(m.getPercentRemainingBlockCount())). - tooltip( "Percent Blocks Remaining" ) ); - - row.addTextComponent( "%% &3RCnt: &7" ); - - row.addFancy( - new FancyMessage(dFmt.format(m.getResetCount())). - tooltip( "Times the mine was reset." ) ); - - if ( !m.isVirtual() ) { - - row.addTextComponent( " &3 Vol: &7" ); - row.addFancy( - new FancyMessage(dFmt.format(m.getBounds().getTotalBlockCount())). - tooltip( "Volume in Blocks" ) ); - } - - - - - - boolean hasCmds = m.getResetCommands().size() > 0; - if ( hasCmds ) { - row.addFancy( - new FancyMessage( String.format(" &cCmds: &7%s ", - Integer.toString( m.getResetCommands().size() )) ) - .command("/mines commands list " + m.getName()) - .tooltip("&7Click to view commands.")); - } - - - - boolean hasBlockEvents = m.getBlockEvents().size() > 0; - if ( hasBlockEvents ) { - row.addFancy( - new FancyMessage( String.format(" &cbEvs: &7%s ", - Integer.toString( m.getBlockEvents().size() )) ) - .command("/mines blockEvent list " + m.getName()) - .tooltip("&7Click to view blockEvents.")); - } - - - - if ( m.isVirtual() ) { - row.addFancy( - new FancyMessage( "&cVIRTUAL " ) - .command("/mines set area " + m.getName()) - .tooltip("&7Click to set the mine's area to make it a real mine. ")); - } - - - if ( !m.isEnabled() ) { - row.addFancy( - new FancyMessage( "&cDISABLED!! " ) - .command("/mines info " + m.getName()) - .tooltip("&7Click to view possible reason why the mine is " + - "disabled. World may not exist? ")); - } - - -// if ( m.isUsePagingOnReset() ) { -// row.addFancy( -// new FancyMessage("&5Paged ") -// .tooltip("&7Paging Used during Mine Reset")); -// } - - - -// String noteMode = m.getNotificationMode().name() + -// ( m.getNotificationMode() == MineNotificationMode.radius ? -// " " + dFmt.format( m.getNotificationRadius() ) : "" ); -// row.addFancy( -// new FancyMessage(noteMode).tooltip( "Notification Mode" ) ); -// -// row.addTextComponent( "&7 - &b" ); -// -// row.addFancy( -// new FancyMessage(m.getBounds().getDimensions()).tooltip( "Size of Mine" ) ); -// -// row.addTextComponent( "&7 - &b"); - - - } - - builder.add(row.getFancy()); - - - if ( !m.isVirtual() && isMineStatsEnabled ) { - RowComponent rowStats = new RowComponent(); - - rowStats.addTextComponent( " -- &7 Stats :: " ); - - rowStats.addTextComponent( m.statsMessage() ); - - builder.add(rowStats.getFancy()); - } + RowComponent row = new RowComponent(); + + + if ( m.getSortOrder() < 1 ) { + + } + else { + row.addFancy( + new FancyMessage( String.format("&3(&b%s&3) ", + Integer.toString( m.getSortOrder() )) ) + .tooltip("&7Sort order.")); + } + + + String name = m.getName(); + if ( name.length() < 6 ) { + name += " ".substring( 0, (6-name.length()) ); + } + row.addFancy( + new FancyMessage( String.format("&7%s ", name) ) + .command("/mines info " + m.getName()) + .tooltip("&7Mine " + m.getTag() + ": Click to view more info.")); + + + if ( m.getTag() != null && m.getTag().trim().length() > 0 ) { + String tag = m.getTag(); + String tagNoColor = Text.stripColor( tag ); + if ( tagNoColor.length() < 6 ) { + tag += " ".substring( 0, (6 - tagNoColor.length()) ); + } + row.addTextComponent( "%s ", tag ); + } + + + if ( !m.isVirtual() ) { + row.addFancy( + new FancyMessage("&eTP ").command("/mines tp " + m.getName()) + .tooltip("&7Click to TP to the mine")); + } + + + row.addTextComponent( " &3(&2R: " ); + + if ( !m.isVirtual() && m.getResetTime() > 0 ) { + row.addFancy( + new FancyMessage( + String.format( "&7%s &3sec &3/ ", dFmt.format(m.getRemainingTimeSec()))) + + .tooltip( "Estimated time in seconds before the mine resets" ) ); + } + + + if ( m.getResetTime() <= 0 ) { + + row.addFancy( + new FancyMessage( + String.format( "&7disabled )&b" )) + .tooltip( "Auto resets have been disabled." ) ); + } + else { + + row.addFancy( + new FancyMessage( + String.format( "&7%s &3sec )&b", dFmt.format(m.getResetTime()) )) + .tooltip( "Reset time in seconds" ) ); + } + + if ( !m.isVirtual() && player != null && + m.getBounds().withinSameWorld( player.getLocation() ) ) { + + double distance = m.getBounds().getDistance3d(player.getLocation()); + + row.addFancy( + new FancyMessage( + String.format( " &3Dist: &7%s", fFmt.format( distance )) ). + tooltip("Distance to the Mine") ); + + } + + + if ( m.isVirtual() ) { + + row.addTextComponent( "&6Virtual Mine" ); + } + + else { + + // Right justify the total blocks mined, with 1000's separators: + String blocksMined = " " + dFmt.format( m.getTotalBlocksMined() ); + blocksMined = blocksMined.substring( blocksMined.length() - 8); + + row.addFancy( + new FancyMessage( String.format(" %s &3Rem: ", blocksMined)). + tooltip( "Blocks mined" ) ); + + row.addFancy( + new FancyMessage(fFmt.format(m.getPercentRemainingBlockCount())). + tooltip( "Percent Blocks Remaining" ) ); + + row.addTextComponent( "%% &3RCnt: &7" ); + + row.addFancy( + new FancyMessage(dFmt.format(m.getResetCount())). + tooltip( "Times the mine was reset." ) ); + + if ( !m.isVirtual() ) { + + row.addTextComponent( " &3 Vol: &7" ); + row.addFancy( + new FancyMessage(dFmt.format(m.getBounds().getTotalBlockCount())). + tooltip( "Volume in Blocks" ) ); + } + + + + boolean hasCmds = m.getResetCommands().size() > 0; + if ( hasCmds ) { + row.addFancy( + new FancyMessage( String.format(" &cCmds: &7%s ", + Integer.toString( m.getResetCommands().size() )) ) + .command("/mines commands list " + m.getName()) + .tooltip("&7Click to view commands.")); + } + + + + boolean hasBlockEvents = m.getBlockEvents().size() > 0; + if ( hasBlockEvents ) { + row.addFancy( + new FancyMessage( String.format(" &cbEvs: &7%s ", + Integer.toString( m.getBlockEvents().size() )) ) + .command("/mines blockEvent list " + m.getName()) + .tooltip("&7Click to view blockEvents.")); + } + + + + if ( m.isVirtual() ) { + row.addFancy( + new FancyMessage( "&cVIRTUAL " ) + .command("/mines set area " + m.getName()) + .tooltip("&7Click to set the mine's area to make it a real mine. ")); + } + + + if ( !m.isEnabled() ) { + row.addFancy( + new FancyMessage( "&cDISABLED!! " ) + .command("/mines info " + m.getName()) + .tooltip("&7Click to view possible reason why the mine is " + + "disabled. World may not exist? ")); + } + + + + } + + builder.add(row.getFancy()); + + + if ( !m.isVirtual() && isMineStatsEnabled ) { + RowComponent rowStats = new RowComponent(); + + rowStats.addTextComponent( " -- &7 Stats :: " ); + + rowStats.addTextComponent( m.statsMessage() ); + + builder.add(rowStats.getFancy()); + } } } -// display.addComponent(builder.build()); - return builder.build(); } @@ -1900,39 +1791,34 @@ public void skipResetCommand(CommandSender sender, PrisonMines pMines = PrisonMines.getInstance(); -// if ( !m.isEnabled() ) { -// sender.sendMessage( "&cMine is disabled&7. Use &a/mines info &7for possible cause." ); -// return; -// } - boolean skipEnabled = "enabled".equalsIgnoreCase( enabled ) || "enable".equalsIgnoreCase( enabled ); double skipPercent = 80.0d; int skipBypassLimit = 50; try { - skipPercent = Double.parseDouble( percent ); - if ( skipPercent < 0.0d ) { - skipPercent = 0.0d; - } else if ( skipPercent > 100.0d ) { - skipPercent = 100.0d; - } - } - catch ( NumberFormatException e1 ) { - Output.get().sendWarn( sender,"&7Invalid percentage. Not a number. " + - "Was &b%s&7.", (enabled == null ? "&c-blank-" : enabled) ); - return; + skipPercent = Double.parseDouble( percent ); + if ( skipPercent < 0.0d ) { + skipPercent = 0.0d; + } else if ( skipPercent > 100.0d ) { + skipPercent = 100.0d; } + } + catch ( NumberFormatException e1 ) { + Output.get().sendWarn( sender,"&7Invalid percentage. Not a number. " + + "Was &b%s&7.", (enabled == null ? "&c-blank-" : enabled) ); + return; + } try { - skipBypassLimit = Integer.parseInt( bypassLimit ); - if ( skipBypassLimit < 1 ) { - skipBypassLimit = 1; - } - } - catch ( NumberFormatException e1 ) { - Output.get().sendWarn( sender,"&7Invalid bypass limit. Not number. " + - "Was &b%s&7.", (bypassLimit == null ? "-blank-" : bypassLimit) ); - } + skipBypassLimit = Integer.parseInt( bypassLimit ); + if ( skipBypassLimit < 1 ) { + skipBypassLimit = 1; + } + } + catch ( NumberFormatException e1 ) { + Output.get().sendWarn( sender,"&7Invalid bypass limit. Not number. " + + "Was &b%s&7.", (bypassLimit == null ? "-blank-" : bypassLimit) ); + } int updates = 0; String mName = "&7*all*&r"; @@ -2003,107 +1889,98 @@ public void resetTimeCommand(CommandSender sender, ) { - int resetTime = Mine.MINE_RESET__TIME_SEC__DEFAULT; - - PrisonMines pMines = PrisonMines.getInstance(); - - if ( "*disable*".equalsIgnoreCase( time ) ) { - resetTime = -1; - } - else if ( "*default*".equalsIgnoreCase( time ) ) { - // use the default time - } - else { - try { - if ( time != null && time.trim().length() > 0 ) { - resetTime = Integer.parseInt( time ); - } - } - catch ( NumberFormatException e ) { - Output.get().sendWarn( sender, - "&7Invalid resetTime value for &b%s&7. Must be an integer value of &b%d &7or greater. [&b%s&7]", - mineName, Mine.MINE_RESET__TIME_SEC__MINIMUM, time ); - return; - } - } - if ( !"*disable*".equalsIgnoreCase( time ) && resetTime < Mine.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, Mine.MINE_RESET__TIME_SEC__MINIMUM, resetTime ); - return; - } - - if ( "*all*".equalsIgnoreCase( mineName ) ) { - - for ( Mine mine : pMines.getMines() ) { - if ( mine.getResetTime() != resetTime ) { - - mine.setResetTime( resetTime ); - - pMines.getMineManager().saveMine( mine ); - - if ( resetTime == -1 ) { - - Output.get().logInfo( "&7Automatic resets have been disabled for mine %s.", mine.getTag() ); - } - else { - // User's message: - Output.get().sendInfo( sender, "&7mines set resettime: &b%s &7resetTime set to &b%d", - mine.getTag(), resetTime ); - - // Server Log message: - Player player = sender.getPlatformPlayer(); - Output.get().logInfo( "&bmines set resettime&7: &b%s &7set &b%s &7resetTime to &b%d", - (player == null ? "console" : player.getDisplayName()), mine.getTag(), resetTime ); - } - } - } - - return; - } + int resetTime = Mine.MINE_RESET__TIME_SEC__DEFAULT; + + PrisonMines pMines = PrisonMines.getInstance(); + + if ( "*disable*".equalsIgnoreCase( time ) ) { + resetTime = -1; + } + else if ( "*default*".equalsIgnoreCase( time ) ) { + // use the default time + } + else { + try { + if ( time != null && time.trim().length() > 0 ) { + resetTime = Integer.parseInt( time ); + } + } + catch ( NumberFormatException e ) { + Output.get().sendWarn( sender, + "&7Invalid resetTime value for &b%s&7. Must be an integer value of &b%d &7or greater. [&b%s&7]", + mineName, Mine.MINE_RESET__TIME_SEC__MINIMUM, time ); + return; + } + } + if ( !"*disable*".equalsIgnoreCase( time ) && resetTime < Mine.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, Mine.MINE_RESET__TIME_SEC__MINIMUM, resetTime ); + return; + } + + if ( "*all*".equalsIgnoreCase( mineName ) ) { + + for ( Mine mine : pMines.getMines() ) { + if ( mine.getResetTime() != resetTime ) { + + mine.setResetTime( resetTime ); + + pMines.getMineManager().saveMine( mine ); + + if ( resetTime == -1 ) { + + Output.get().logInfo( "&7Automatic resets have been disabled for mine %s.", mine.getTag() ); + } + else { + // User's message: + Output.get().sendInfo( sender, "&7mines set resettime: &b%s &7resetTime set to &b%d", + mine.getTag(), resetTime ); + + // Server Log message: + Player player = sender.getPlatformPlayer(); + Output.get().logInfo( "&bmines set resettime&7: &b%s &7set &b%s &7resetTime to &b%d", + (player == null ? "console" : player.getDisplayName()), mine.getTag(), resetTime ); + } + } + } + + return; + } if (performCheckMineExists(sender, mineName)) { - setLastMineReferenced(mineName); - - Mine m = pMines.getMine(mineName); - - if ( "*disable*".equalsIgnoreCase( time ) ) { - - m.setResetTime( -1 ); - - pMines.getMineManager().saveMine( m ); - - Output.get().logInfo( "&7Automatic resets have been disabled for mine %s.", m.getTag() ); - - return; - } - - -// if ( 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 ); -// } else - { -// if ( !m.isEnabled() ) { -// sender.sendMessage( "&cMine is disabled&7. Use &a/mines info &7for possible cause." ); -// return; -// } - - m.setResetTime( resetTime ); - - pMines.getMineManager().saveMine( m ); - - // User's message: - Output.get().sendInfo( sender, "&7mines set resettime: &b%s &7resetTime set to &b%d", m.getTag(), resetTime ); - - // Server Log message: - Player player = sender.getPlatformPlayer(); - Output.get().logInfo( "&bmines set resettime&7: &b%s &7set &b%s &7resetTime to &b%d", - (player == null ? "console" : player.getDisplayName()), m.getTag(), resetTime ); - } + setLastMineReferenced(mineName); + + Mine m = pMines.getMine(mineName); + + if ( "*disable*".equalsIgnoreCase( time ) ) { + + m.setResetTime( -1 ); + + pMines.getMineManager().saveMine( m ); + + Output.get().logInfo( "&7Automatic resets have been disabled for mine %s.", m.getTag() ); + + return; + } + + + { + + m.setResetTime( resetTime ); + + pMines.getMineManager().saveMine( m ); + + // User's message: + Output.get().sendInfo( sender, "&7mines set resettime: &b%s &7resetTime set to &b%d", m.getTag(), resetTime ); + + // Server Log message: + Player player = sender.getPlatformPlayer(); + Output.get().logInfo( "&bmines set resettime&7: &b%s &7set &b%s &7resetTime to &b%d", + (player == null ? "console" : player.getDisplayName()), m.getTag(), resetTime ); + } - } + } } @@ -2134,59 +2011,52 @@ public void zeroBlockResetDelayCommand(CommandSender sender, ) { - if ( "*all*".equalsIgnoreCase( mineName ) || - performCheckMineExists(sender, mineName)) { - - double resetTime = - time != null && "disable".equalsIgnoreCase( time ) ? -1.0d : - 0.0d; - - try { - - if ( resetTime != -1.0d && time != null && time.trim().length() > 0 ) { - resetTime = Double.parseDouble( time ); - - // Only displaying two decimal positions, since 0.01 is 10 ms. - // Anything less than 0.01 is set to ZERO so it does not mess with anything unseen. - // Also any value less than 0.05 is basically zero since this value has to be - // converted to ticks. - if ( resetTime < 0.01d ) { - resetTime = 0.0d; - } - } - } - catch ( NumberFormatException e ) { - Output.get().sendWarn( sender, - "&7Invalid zeroBlockResetDelay value for &b%s&7. Must be an double value of &b0.00 &7or " + - "greater. [&b%s&7]", - mineName, time ); - return; - } - - PrisonMines pMines = PrisonMines.getInstance(); - - if ( !"*all*".equalsIgnoreCase( mineName ) ) { - setLastMineReferenced(mineName); - - Mine m = pMines.getMine(mineName); - - minesSetResetDelay(sender, resetTime, pMines, m); - } - else { - - for ( Mine m : pMines.getMines() ) { - minesSetResetDelay(sender, resetTime, pMines, m); - } - } - - -// if ( !m.isEnabled() ) { -// sender.sendMessage( "&cMine is disabled&7. Use &a/mines info &7for possible cause." ); -// return; -// } - - - } + if ( "*all*".equalsIgnoreCase( mineName ) || + performCheckMineExists(sender, mineName)) { + + double resetTime = + time != null && "disable".equalsIgnoreCase( time ) ? -1.0d : + 0.0d; + + try { + + if ( resetTime != -1.0d && time != null && time.trim().length() > 0 ) { + resetTime = Double.parseDouble( time ); + + // Only displaying two decimal positions, since 0.01 is 10 ms. + // Anything less than 0.01 is set to ZERO so it does not mess with anything unseen. + // Also any value less than 0.05 is basically zero since this value has to be + // converted to ticks. + if ( resetTime < 0.01d ) { + resetTime = 0.0d; + } + } + } + catch ( NumberFormatException e ) { + Output.get().sendWarn( sender, + "&7Invalid zeroBlockResetDelay value for &b%s&7. Must be an double value of &b0.00 &7or " + + "greater. [&b%s&7]", + mineName, time ); + return; + } + + PrisonMines pMines = PrisonMines.getInstance(); + + if ( !"*all*".equalsIgnoreCase( mineName ) ) { + setLastMineReferenced(mineName); + + Mine m = pMines.getMine(mineName); + + minesSetResetDelay(sender, resetTime, pMines, m); + } + else { + + for ( Mine m : pMines.getMines() ) { + minesSetResetDelay(sender, resetTime, pMines, m); + } + } + + } } private void minesSetResetDelay(CommandSender sender, double resetTime, PrisonMines pMines, Mine m) { @@ -2236,30 +2106,25 @@ public void resetThresholdPercentCommand(CommandSender sender, ) { if ( "*all*".equalsIgnoreCase( mineName ) || - performCheckMineExists(sender, mineName)) { + performCheckMineExists(sender, mineName)) { - PrisonMines pMines = PrisonMines.getInstance(); - - if ( !"*all*".equalsIgnoreCase( mineName ) ) { - setLastMineReferenced(mineName); - - Mine m = pMines.getMine(mineName); - - changeMinePercentThreshold(sender, percent, pMines, m); - } - else { - for ( Mine m : pMines.getMines() ) { - - changeMinePercentThreshold(sender, percent, pMines, m); + PrisonMines pMines = PrisonMines.getInstance(); + + if ( !"*all*".equalsIgnoreCase( mineName ) ) { + setLastMineReferenced(mineName); + + Mine m = pMines.getMine(mineName); + + changeMinePercentThreshold(sender, percent, pMines, m); + } + else { + for ( Mine m : pMines.getMines() ) { + + changeMinePercentThreshold(sender, percent, pMines, m); } - } - -// if ( !m.isEnabled() ) { -// sender.sendMessage( "&cMine is disabled&7. Use &a/mines info &7for possible cause." ); -// return; -// } - - } + } + + } } private void changeMinePercentThreshold(CommandSender sender, String percent, PrisonMines pMines, Mine m) { @@ -2327,70 +2192,63 @@ public void setNotificationCommand(CommandSender sender, ) { - MineNotificationMode noteMode = MineNotificationMode.fromString( mode, MineNotificationMode.displayOptions ); - - if ( noteMode == MineNotificationMode.displayOptions ) { - sender.sendMessage( "&7Select a Mode: &bdisabled&7, &bwithin &7the mine, &bradius " + - "&7from center of mine&7, &bworld&7, &bserver&7." ); - return; - } - - long noteRadius = 0L; - if ( noteMode == MineNotificationMode.radius ) { - if ( radius == null || radius.trim().length() == 0 ) { - noteRadius = Mine.MINE_RESET__BROADCAST_RADIUS_BLOCKS; - } else { - try { - noteRadius = Long.parseLong( radius ); - - if ( noteRadius < 1 ) { - noteRadius = Mine.MINE_RESET__BROADCAST_RADIUS_BLOCKS; - DecimalFormat dFmt = Prison.get().getDecimalFormatInt(); - Output.get().sendWarn( sender, "&7Invalid radius value. " + - "Must be an positive non-zero integer. Using the default value: &b%s &7[&b%s&7]", - dFmt.format(Mine.MINE_RESET__BROADCAST_RADIUS_BLOCKS), radius ); - return; - } - } - catch ( NumberFormatException e ) { - e.printStackTrace(); - Output.get().sendWarn( sender, "&7Invalid notification radius. " + - "Must be an positive non-zero integer. [&b%s&7]", - radius ); - return; - } - } - } - - PrisonMines pMines = PrisonMines.getInstance(); - - if ( "*all*".equalsIgnoreCase( mineName ) ) { - - int count = 0; - for ( Mine m : pMines.getMines() ) - { - - if ( changeMineNotification( sender, mineName, noteMode, noteRadius, pMines, m, true ) ) { - count++; - } + MineNotificationMode noteMode = MineNotificationMode.fromString( mode, MineNotificationMode.displayOptions ); + + if ( noteMode == MineNotificationMode.displayOptions ) { + sender.sendMessage( "&7Select a Mode: &bdisabled&7, &bwithin &7the mine, &bradius " + + "&7from center of mine&7, &bworld&7, &bserver&7." ); + return; + } + + long noteRadius = 0L; + if ( noteMode == MineNotificationMode.radius ) { + if ( radius == null || radius.trim().length() == 0 ) { + noteRadius = Mine.MINE_RESET__BROADCAST_RADIUS_BLOCKS; + } else { + try { + noteRadius = Long.parseLong( radius ); + + if ( noteRadius < 1 ) { + noteRadius = Mine.MINE_RESET__BROADCAST_RADIUS_BLOCKS; + DecimalFormat dFmt = Prison.get().getDecimalFormatInt(); + Output.get().sendWarn( sender, "&7Invalid radius value. " + + "Must be an positive non-zero integer. Using the default value: &b%s &7[&b%s&7]", + dFmt.format(Mine.MINE_RESET__BROADCAST_RADIUS_BLOCKS), radius ); + return; + } + } + catch ( NumberFormatException e ) { + e.printStackTrace(); + Output.get().sendWarn( sender, "&7Invalid notification radius. " + + "Must be an positive non-zero integer. [&b%s&7]", + radius ); + return; + } + } + } + + PrisonMines pMines = PrisonMines.getInstance(); + + if ( "*all*".equalsIgnoreCase( mineName ) ) { + + int count = 0; + for ( Mine m : pMines.getMines() ) { + + if ( changeMineNotification( sender, mineName, noteMode, noteRadius, pMines, m, true ) ) { + count++; + } } - - Output.get().sendInfo( sender, "&7Notification mode was changed for &b%d&7 mines.", - count ); - } - - else if (performCheckMineExists(sender, mineName)) { - setLastMineReferenced(mineName); - - Mine m = pMines.getMine(mineName); - -// if ( !m.isEnabled() ) { -// sender.sendMessage( "&cMine is disabled&7. Use &a/mines info &7for possible cause." ); -// return; -// } - - - changeMineNotification( sender, mineName, noteMode, noteRadius, pMines, m, false ); + + Output.get().sendInfo( sender, "&7Notification mode was changed for &b%d&7 mines.", + count ); + } + + else if (performCheckMineExists(sender, mineName)) { + setLastMineReferenced(mineName); + + Mine m = pMines.getMine(mineName); + + changeMineNotification( sender, mineName, noteMode, noteRadius, pMines, m, false ); } } @@ -2436,39 +2294,31 @@ public void setNotificationPermissionCommand(CommandSender sender, ) { - - if ( !action.equalsIgnoreCase( "enable" ) && !action.equalsIgnoreCase( "disable" )) { - sender.sendMessage( "&7Invalid value for action: [enable, disable]" ); - return; - } - - if ( "*all*".equalsIgnoreCase( mineName ) || - performCheckMineExists(sender, mineName)) { - - PrisonMines pMines = PrisonMines.getInstance(); + if ( !action.equalsIgnoreCase( "enable" ) && !action.equalsIgnoreCase( "disable" )) { + sender.sendMessage( "&7Invalid value for action: [enable, disable]" ); + return; + } - if ( "*all*".equalsIgnoreCase( mineName ) ) { - setLastMineReferenced(mineName); - - Mine m = pMines.getMine(mineName); - - minesSetNotificationPerm(sender, action, pMines, m); - } - else { - - for ( Mine m : pMines.getMines() ) { - minesSetNotificationPerm(sender, action, pMines, m); + if ( "*all*".equalsIgnoreCase( mineName ) || + performCheckMineExists(sender, mineName)) { + + PrisonMines pMines = PrisonMines.getInstance(); + + if ( "*all*".equalsIgnoreCase( mineName ) ) { + setLastMineReferenced(mineName); + + Mine m = pMines.getMine(mineName); + + minesSetNotificationPerm(sender, action, pMines, m); + } + else { + + for ( Mine m : pMines.getMines() ) { + minesSetNotificationPerm(sender, action, pMines, m); } - } - -// if ( !m.isEnabled() ) { -// sender.sendMessage( "&cMine is disabled&7. Use &a/mines info &7for possible cause." ); -// return; -// } - - - - } + } + + } } private void minesSetNotificationPerm(CommandSender sender, String action, PrisonMines pMines, Mine m) { @@ -2519,23 +2369,22 @@ public void setMinePermissionCommand(CommandSender sender, if ( "*all*".equalsIgnoreCase( mineName ) || performCheckMineExists(sender, mineName)) { - PrisonMines pMines = PrisonMines.getInstance(); - - if ( "*all*".equalsIgnoreCase( mineName ) ) { - - for ( Mine m : pMines.getMines() ) { - - minesSetAccessPermission(sender, permission, pMines, m); - } - } - else { - setLastMineReferenced(mineName); - Mine m = pMines.getMine(mineName); - - minesSetAccessPermission(sender, permission, pMines, m); - } + PrisonMines pMines = PrisonMines.getInstance(); + + if ( "*all*".equalsIgnoreCase( mineName ) ) { + + for ( Mine m : pMines.getMines() ) { + + minesSetAccessPermission(sender, permission, pMines, m); + } + } + else { + setLastMineReferenced(mineName); + Mine m = pMines.getMine(mineName); + + minesSetAccessPermission(sender, permission, pMines, m); + } - } } @@ -2591,116 +2440,81 @@ public void setMineRankCommand(CommandSender sender, ) { - PrisonMines pMines = PrisonMines.getInstance(); - - if ( mineName != null && "*all*".equalsIgnoreCase( mineName ) ) { - - for ( Mine mine : pMines.getMines() ) { + PrisonMines pMines = PrisonMines.getInstance(); + + if ( mineName != null && "*all*".equalsIgnoreCase( mineName ) ) { + + for ( Mine mine : pMines.getMines() ) { if ( "*none*".equalsIgnoreCase( rankName ) && mine.getRank() != null ) { - // First unlink the preexisting mine and rank: - String removedRankName = mine.getRank().getName(); - - // unlinkModuleElement will do the saving - Prison.get().getPlatform().unlinkModuleElements( mine, mine.getRank() ); - - sender.sendMessage( String.format( "&3Rank &7%s &3has been removed from mine &7%s", - removedRankName, mine.getTag() )); + // First unlink the preexisting mine and rank: + String removedRankName = mine.getRank().getName(); + + // unlinkModuleElement will do the saving + Prison.get().getPlatform().unlinkModuleElements( mine, mine.getRank() ); + + sender.sendMessage( String.format( "&3Rank &7%s &3has been removed from mine &7%s", + removedRankName, mine.getTag() )); } else if ( "*mineName*".equalsIgnoreCase( rankName ) ) { - - boolean success = Prison.get().getPlatform().linkModuleElements( mine, - ModuleElementType.RANK, mine.getName() ); - - if ( !success ) { - sender.sendMessage( String.format( - "&3Invalid Rank Name for mine %s: &7%s", mine.getName(), mine.getName() )); - } - else { - sender.sendMessage( String.format( "&3Rank &7%s &3has been linked to mine &7%s", - rankName, mine.getTag() )); - } + + boolean success = Prison.get().getPlatform().linkModuleElements( mine, + ModuleElementType.RANK, mine.getName() ); + + if ( !success ) { + sender.sendMessage( String.format( + "&3Invalid Rank Name for mine %s: &7%s", mine.getName(), mine.getName() )); + } + else { + sender.sendMessage( String.format( "&3Rank &7%s &3has been linked to mine &7%s", + rankName, mine.getTag() )); + } } } - - return; - } - + + return; + } + if (performCheckMineExists(sender, mineName)) { - setLastMineReferenced(mineName); - - Mine m = pMines.getMine(mineName); - + setLastMineReferenced(mineName); + + Mine m = pMines.getMine(mineName); + if ( rankName == null || rankName.trim().length() == 0 ) { - sender.sendMessage( "&cRank name is required." ); - return; + sender.sendMessage( "&cRank name is required." ); + return; } if ( m.getRank() != null ) { - // First unlink the preexisting mine and rank: - String removedRankName = m.getRank().getName(); - - // unlinkModuleElement will do the saving - Prison.get().getPlatform().unlinkModuleElements( m, m.getRank() ); - - sender.sendMessage( String.format( "&3Rank &7%s &3has been removed from mine &7%s", - removedRankName, m.getTag() )); + // First unlink the preexisting mine and rank: + String removedRankName = m.getRank().getName(); + + // unlinkModuleElement will do the saving + Prison.get().getPlatform().unlinkModuleElements( m, m.getRank() ); + + sender.sendMessage( String.format( "&3Rank &7%s &3has been removed from mine &7%s", + removedRankName, m.getTag() )); } if ( !"*none*".equalsIgnoreCase( rankName ) ) { - boolean success = Prison.get().getPlatform().linkModuleElements( m, - ModuleElementType.RANK, rankName ); - - if ( !success ) { - sender.sendMessage( String.format( "&3Invalid Rank Name: &7%s", rankName )); - } - else { - sender.sendMessage( String.format( "&3Rank &7%s &3has been linked to mine &7%s", - rankName, m.getTag() )); - } + boolean success = Prison.get().getPlatform().linkModuleElements( m, + ModuleElementType.RANK, rankName ); + + if ( !success ) { + sender.sendMessage( String.format( "&3Invalid Rank Name: &7%s", rankName )); + } + else { + sender.sendMessage( String.format( "&3Rank &7%s &3has been linked to mine &7%s", + rankName, m.getTag() )); + } } } } - -/* - * Remove this command since the same functionality exists in /mines set rank: - * This will be removed shortly once the replacement is confirmed to work well. - * - * @Command(identifier = "mines set norank", permissions = "mines.set", - * description = "Unlinks a rank from a mine") - * public void setMineNoRankCommand(CommandSender sender, - * @Arg(name = "mineName", description = "The name of the mine.") String mineName - * - * ) { - * - * if (performCheckMineExists(sender, mineName)) { - * setLastMineReferenced(mineName); - * - * PrisonMines pMines = PrisonMines.getInstance(); - * Mine m = pMines.getMine(mineName); - * - * if ( m.getRank() == null ) { - * sender.sendMessage( "&cThis mine has no ranks to unlink." ); - * return; - * } - * - * ModuleElement rank = m.getRank(); - * - * Prison.get().getPlatform().unlinkModuleElements( m, m.getRank() ); - * - * - * sender.sendMessage( String.format( "&3Rank &7%s &3has been removed from mine &7%s", - * rank.getName(), m.getName() )); - * - * } - * } - * - */ @Command(identifier = "mines set area", permissions = "mines.set", @@ -2727,93 +2541,83 @@ public void redefineCommand(CommandSender sender, def = "---") String options ) { - if (!performCheckMineExists(sender, mineName)) { - return; - } + if (!performCheckMineExists(sender, mineName)) { + return; + } PrisonMines pMines = PrisonMines.getInstance(); Mine m = pMines.getMine(mineName); Player player = sender.getPlatformPlayer(); -// if ( !m.isEnabled() ) { -// sender.sendMessage( "&cMine is disabled&7. Use &a/mines info &7for possible cause." ); -// return; -// } Selection selection = null; if ( source != null && "feet".equalsIgnoreCase( source ) ) { - selection = new Selection( player.getLocation(), player.getLocation()); + selection = new Selection( player.getLocation(), player.getLocation()); } else if ( source == null || "wand".equalsIgnoreCase( source ) ) { - selection = Prison.get().getSelectionManager().getSelection( player ); + selection = Prison.get().getSelectionManager().getSelection( player ); } else if ( source == null || "virtual".equalsIgnoreCase( source ) ) { - // do nothing... don't set selection: + // do nothing... don't set selection: } else { - sender.sendMessage( "&3Valid values for &2source &3are &7wand&3, " + - "&7feet&3, and &7virtual&3." ); - return; + sender.sendMessage( "&3Valid values for &2source &3are &7wand&3, " + + "&7feet&3, and &7virtual&3." ); + return; } - - if ( selection == null ) { - - // Revert the mine to a virtual mine: - - setLastMineReferenced(mineName); - - if ( m.isVirtual() ) { - // Already a virtual mine so exit: - String message = "Mine &7" + m.getName() + " &3is already virtual. No changes have been made."; - sender.sendMessage( message ); - - return; - } - - // Make a backup of the mine save file before making virtual: - File backupFile = pMines.getMineManager().backupMine( m ); - - String messageBu = "Mine &7" + m.getName() + " &3has " + - ( backupFile != null && backupFile.exists() ? "been successfully" : "failed to be" ) + - " backed up: " + (backupFile != null ? backupFile.getAbsolutePath() : "none"); - sender.sendMessage( messageBu ); - Output.get().logInfo( messageBu ); - - if ( !backupFile.exists() ) { - Output.get().logInfo( "Since the backup Failed, mine " + m.getName() + " cannot be " + - "virtualized." ); - - return; - } - - // Setting bounds to null will also set spawn to null, the two world fields to null, and - // make the mine virtual and disale the mine too: - m.setBounds( null ); -// m.setSpawn( null ); -// -// m.setWorld( null ); -// m.setWorldName( null ); -// -// m.setVirtual( true ); - - m.getJobStack().clear(); - - // TODO Possibly may need to kill existing jobs and/or set a mutex state of VIRTUAL? - m.getMineStateMutex(); - - pMines.getMineManager().saveMine( m ); - - String message = "Mine &7" + m.getName() + " &3has been set to virtual. "; - sender.sendMessage( message ); - - return; + + if ( selection == null ) { + + // Revert the mine to a virtual mine: + + setLastMineReferenced(mineName); + + if ( m.isVirtual() ) { + // Already a virtual mine so exit: + String message = "Mine &7" + m.getName() + " &3is already virtual. No changes have been made."; + sender.sendMessage( message ); + + return; + } + + // Make a backup of the mine save file before making virtual: + File backupFile = pMines.getMineManager().backupMine( m ); + + String messageBu = "Mine &7" + m.getName() + " &3has " + + ( backupFile != null && backupFile.exists() ? "been successfully" : "failed to be" ) + + " backed up: " + (backupFile != null ? backupFile.getAbsolutePath() : "none"); + sender.sendMessage( messageBu ); + Output.get().logInfo( messageBu ); + + if ( !backupFile.exists() ) { + Output.get().logInfo( "Since the backup Failed, mine " + m.getName() + " cannot be " + + "virtualized." ); + + return; + } + + // Setting bounds to null will also set spawn to null, the two world fields to null, and + // make the mine virtual and disale the mine too: + m.setBounds( null ); + + m.getJobStack().clear(); + + // TODO Possibly may need to kill existing jobs and/or set a mutex state of VIRTUAL? + m.getMineStateMutex(); + + pMines.getMineManager().saveMine( m ); + + String message = "Mine &7" + m.getName() + " &3has been set to virtual. "; + sender.sendMessage( message ); + + return; } if (!selection.isComplete()) { - pMines.getMinesMessages().getLocalizable("select_bounds") - .sendTo(sender); + pMines.getMinesMessages().getLocalizable("select_bounds") + .sendTo(sender); return; } @@ -2828,27 +2632,27 @@ else if ( source == null || "virtual".equalsIgnoreCase( source ) ) { Bounds selectedBounds = selection.asBounds(); if ( Output.get().isDebug() ) { - String msg = String.format( "MinesSetArea Preset: Mine: %s Bounds: %s - %s ", - m.getName(), - selectedBounds.getMin().toWorldCoordinates(), - selectedBounds.getMax().toWorldCoordinates() - ); - Output.get().logInfo( msg ); + String msg = String.format( "MinesSetArea Preset: Mine: %s Bounds: %s - %s ", + m.getName(), + selectedBounds.getMin().toWorldCoordinates(), + selectedBounds.getMax().toWorldCoordinates() + ); + Output.get().logInfo( msg ); } if ( selectedBounds.getTotalBlockCount() > 50000 && (options == null || !options.toLowerCase().contains( "confirm" ) && !options.toLowerCase().contains( "yes" )) ) { - String message = String.format( "&7Warning: This mine has a size of %s. If this is " + - "intentional, then please re-submit this command with adding the " + - "keyword of either 'confirm' or 'yes' to the end of the command. ", - dFmt.format( selectedBounds.getTotalBlockCount() ) ); - sender.sendMessage( message ); - return; + String message = String.format( "&7Warning: This mine has a size of %s. If this is " + + "intentional, then please re-submit this command with adding the " + + "keyword of either 'confirm' or 'yes' to the end of the command. ", + dFmt.format( selectedBounds.getTotalBlockCount() ) ); + sender.sendMessage( message ); + return; } else if ( options.toLowerCase().contains( "confirm" ) || options.toLowerCase().contains( "yes" ) ) { - options = options.replace( "(?i)confirm|yes", "" ).trim(); + options = options.replace( "(?i)confirm|yes", "" ).trim(); } // TODO check to see if they are the same boundaries, if not, don't change... @@ -2861,7 +2665,7 @@ else if ( options.toLowerCase().contains( "confirm" ) || // Before setting the bounds, clear everything by setting them to nulls: // Setting bounds to null will also set spawn to null, the two world fields to null, and - // make the mine virtual and disable the mine too: + // make the mine virtual and disable the mine too: m.setBounds( null ); m.getJobStack().clear(); @@ -2870,18 +2674,15 @@ else if ( options.toLowerCase().contains( "confirm" ) || // Setting the bounds when it's virtual will configure all the internals: m.setBounds(selectedBounds); - - if ( wasVirtual ) { - - - String message = String.format( "&3The mine &7%s &3 is no longer a virutal mine " + - "and has been enabled with an area of &7%s &3blocks.", - m.getTag(), dFmt.format( m.getBounds().getTotalBlockCount() )); - - sender.sendMessage( message ); - Output.get().logInfo( message ); + + String message = String.format( "&3The mine &7%s &3 is no longer a virutal mine " + + "and has been enabled with an area of &7%s &3blocks.", + m.getTag(), dFmt.format( m.getBounds().getTotalBlockCount() )); + + sender.sendMessage( message ); + Output.get().logInfo( message ); } pMines.getMineManager().saveMine( m ); @@ -2891,50 +2692,49 @@ else if ( options.toLowerCase().contains( "confirm" ) || // Delete the selection: Prison.get().getSelectionManager().clearSelection((Player) sender); - //pMines.getMineManager().clearCache(); // adjustSize to zero to reset set all liners: if ( m.getLinerData() != null ) { - m.adjustSize( Edges.walls, 0 ); - - if ( options.length() > 0 ) { - String[] opts = options.split( " " ); - - // Try to set the size of the wall: Increase by: - if ( opts.length > 0 ) { - try { - int size = Integer.parseInt( opts[0] ); - setSizeCommand( sender, mineName, "walls", size ); - } - catch ( Exception e ) { - // ignore error - } - } - - // Try to set the size of the bottom: Increase by: - if ( opts.length > 1 ) { - try { - int size = Integer.parseInt( opts[1] ); - setSizeCommand( sender, mineName, "bottom", size ); - } - catch ( Exception e ) { - // ignore error - } - } - - // Try to set the size of the wall: Increase by: - if ( opts.length > 2 ) { - try { - int size = Integer.parseInt( opts[2] ); - setSizeCommand( sender, mineName, "top", size ); - } - catch ( Exception e ) { - // ignore error - } - } - - } + m.adjustSize( Edges.walls, 0 ); + + if ( options.length() > 0 ) { + String[] opts = options.split( " " ); + + // Try to set the size of the wall: Increase by: + if ( opts.length > 0 ) { + try { + int size = Integer.parseInt( opts[0] ); + setSizeCommand( sender, mineName, "walls", size ); + } + catch ( Exception e ) { + // ignore error + } + } + + // Try to set the size of the bottom: Increase by: + if ( opts.length > 1 ) { + try { + int size = Integer.parseInt( opts[1] ); + setSizeCommand( sender, mineName, "bottom", size ); + } + catch ( Exception e ) { + // ignore error + } + } + + // Try to set the size of the wall: Increase by: + if ( opts.length > 2 ) { + try { + int size = Integer.parseInt( opts[2] ); + setSizeCommand( sender, mineName, "top", size ); + } + catch ( Exception e ) { + // ignore error + } + } + + } } } @@ -2950,26 +2750,26 @@ public void backupMineCommand(CommandSender sender, @Arg(name = "mineName", description = "The name of the mine to edit.") String mineName ) { - if (!performCheckMineExists(sender, mineName)) { - return; - } + if (!performCheckMineExists(sender, mineName)) { + return; + } PrisonMines pMines = PrisonMines.getInstance(); Mine m = pMines.getMine(mineName); - // Make a backup of the mine save file before making virtual: - File backupFile = pMines.getMineManager().backupMine( m ); - - String messageBu = "Mine &7" + m.getName() + " &3has " + - ( backupFile != null && backupFile.exists() ? "been successfully" : "failed to be" ) + - " backed up: " + (backupFile != null ? backupFile.getAbsolutePath() : "none"); - - if ( sender.isPlayer() ) { - sender.sendMessage( messageBu ); - } - Output.get().logInfo( messageBu ); - + // Make a backup of the mine save file before making virtual: + File backupFile = pMines.getMineManager().backupMine( m ); + + String messageBu = "Mine &7" + m.getName() + " &3has " + + ( backupFile != null && backupFile.exists() ? "been successfully" : "failed to be" ) + + " backed up: " + (backupFile != null ? backupFile.getAbsolutePath() : "none"); + + if ( sender.isPlayer() ) { + sender.sendMessage( messageBu ); + } + Output.get().logInfo( messageBu ); + } @@ -2987,24 +2787,24 @@ public void setTracerCommand(CommandSender sender, + "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(); + 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; + sender.sendMessage( "&cMine is a virtual mine&7. Use &a/mines set area &7to enable the mine." ); + return; } mine.enableTracer( resetType ); @@ -3022,40 +2822,35 @@ public void setSizeCommand(CommandSender sender, ) { - if (!performCheckMineExists(sender, mineName)) { - return; - } - - Edges e = Edges.fromString( edge ); - if ( e == null ) { - sender.sendMessage( "&cInvalid edge value. [top, bottom, north, east, south, west, walls]" ); - return; - } - - if ( amount == 0 ) { - sender.sendMessage( "&cSize of mine will not be changed. Will refresh the liner." ); -// return; - } - -// if ( adjustment == null || "smaller".equalsIgnoreCase( adjustment ) || "larger".equalsIgnoreCase( adjustment ) ) { -// sender.sendMessage( "&cInvalid adjustment. [larger, smaller]" ); -// return; -// } - - 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.adjustSize( e, amount ); - - pMines.getMineManager().saveMine( mine ); - - + if (!performCheckMineExists(sender, mineName)) { + return; + } + + Edges e = Edges.fromString( edge ); + if ( e == null ) { + sender.sendMessage( "&cInvalid edge value. [top, bottom, north, east, south, west, walls]" ); + return; + } + + if ( amount == 0 ) { + sender.sendMessage( "&cSize of mine will not be changed. Will refresh the liner." ); + } + + + 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.adjustSize( e, amount ); + + pMines.getMineManager().saveMine( mine ); + + } @@ -3069,34 +2864,34 @@ public void moveMineCommand(CommandSender sender, ) { - if (!performCheckMineExists(sender, mineName)) { - return; - } - - Edges edge = Edges.fromString( direction ); - if ( edge == null || edge == Edges.walls ) { - sender.sendMessage( "&cInvalid direction value. [top, bottom, north, east, south, west]" ); - return; - } - - if ( amount < 1 ) { - sender.sendMessage( "&cInvalid amount. Must be 1 or more." ); - return; - } - - - 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; - } - + if (!performCheckMineExists(sender, mineName)) { + return; + } + + Edges edge = Edges.fromString( direction ); + if ( edge == null || edge == Edges.walls ) { + sender.sendMessage( "&cInvalid direction value. [top, bottom, north, east, south, west]" ); + return; + } + + if ( amount < 1 ) { + sender.sendMessage( "&cInvalid amount. Must be 1 or more." ); + return; + } - mine.moveMine( edge, amount ); - pMines.getMineManager().saveMine( mine ); + 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.moveMine( edge, amount ); + + pMines.getMineManager().saveMine( mine ); } @Command(identifier = "mines set liner", permissions = "mines.set", @@ -3120,148 +2915,99 @@ public void setLinerCommand(CommandSender sender, ) { - if ( mineName != null && "?".equals( mineName ) || - pattern != null && "?".equals( pattern ) || edge != null && "?".equals( edge )) { - - sender.sendMessage( "&cAvailable Edges: &3[&7top bottom north east south west walls&3]" ); - sender.sendMessage( "&3Available Patterns: [&7" + LinerPatterns.toStringAll() + "&3]" ); - sender.sendMessage( "&cUse 'ladderType' for the Edge: &3[&7none normal wide jumbo full&3] Where 'normal' is " + - "1 to 3 ladders wide. 'Wide' is up to 5 wide. 'Jumbo' is up to 7 wide. And 'full' is the full width." ); - return; - } - - if ( !"*all*".equalsIgnoreCase( mineName ) && !performCheckMineExists(sender, mineName)) { - return; - } - - Edges e = Edges.fromString( edge ); - LinerPatterns linerPattern = LinerPatterns.fromString( pattern ); - LadderType ladderType = ( e == null && edge != null && edge.equalsIgnoreCase( "ladderType" ) ? - LadderType.fromString( pattern ) : null ); - - - - if ( e == null && ladderType == null ) { - sender.sendMessage( "&cInvalid edge value. &3[&7top bottom north east south west walls&3]" ); - sender.sendMessage( "&cUse 'ladderType' for the Edge with &3[&7none normal wide jumbo full&3] as the patterns." ); - return; - } - - if ( linerPattern == null && ladderType == null ) { - sender.sendMessage( "&cInvalid pattern.&3 Select one of these: [&7" + - LinerPatterns.toStringAll() + "&3]" ); - return; - } - - boolean isForced = false; - if ( force != null && !"force".equalsIgnoreCase( force ) && !"no".equalsIgnoreCase( force ) ) { - sender.sendMessage( - String.format( "&3The valid values for &7force &3 are &7force&3 and &7no&3. " + - "Was &2[&7%s&2]", force ) ); - } - else if ( "force".equalsIgnoreCase( force ) ) { - isForced = true; - } - - PrisonMines pMines = PrisonMines.getInstance(); - - List mines = new ArrayList<>(); - - if ( "*all*".equalsIgnoreCase( mineName ) ) { - mines.addAll( pMines.getMines() ); - } - else { - mines.add( pMines.getMine(mineName) ); - - } - - for ( Mine mine : mines ) - { - boolean resetLiner = false; - -// if ( mine.isVirtual() ) { -// sender.sendMessage( "&cMine is a virtual mine.&7 Use &a/mines set area &7to enable the mine." ); -// return; -// } - if ( ladderType != null ) { - mine.getLinerData().setLadderType( ladderType ); - sender.sendMessage( "&7The liner's ladderType has been set to '" + ladderType.name() + - "' for mine " + mine.getName() ); - - resetLiner = true; - } - else if ( linerPattern == LinerPatterns.removeAll ) { - - mine.getLinerData().removeAll(); - sender.sendMessage( "&7All liners have been removed from mine " + mine.getName() ); - } - else if ( linerPattern == LinerPatterns.remove ) { - mine.getLinerData().remove( e ); - sender.sendMessage( "&7The liner for the " + e.name() + " has been removed from mine " + mine.getName() ); - } - else { - mine.getLinerData().setLiner( e, linerPattern, isForced ); - - resetLiner = true; - } - - pMines.getMineManager().saveMine( mine ); + if ( mineName != null && "?".equals( mineName ) || + pattern != null && "?".equals( pattern ) || edge != null && "?".equals( edge )) { + + sender.sendMessage( "&cAvailable Edges: &3[&7top bottom north east south west walls&3]" ); + sender.sendMessage( "&3Available Patterns: [&7" + LinerPatterns.toStringAll() + "&3]" ); + sender.sendMessage( "&cUse 'ladderType' for the Edge: &3[&7none normal wide jumbo full&3] Where 'normal' is " + + "1 to 3 ladders wide. 'Wide' is up to 5 wide. 'Jumbo' is up to 7 wide. And 'full' is the full width." ); + return; + } + + if ( !"*all*".equalsIgnoreCase( mineName ) && !performCheckMineExists(sender, mineName)) { + return; + } + + Edges e = Edges.fromString( edge ); + LinerPatterns linerPattern = LinerPatterns.fromString( pattern ); + LadderType ladderType = ( e == null && edge != null && edge.equalsIgnoreCase( "ladderType" ) ? + LadderType.fromString( pattern ) : null ); + + - // Do not try to update the liner if it's a virtual mine: - if ( resetLiner && !mine.isVirtual() ) { - - new MineLinerBuilder( mine, e, linerPattern, isForced ); - } + if ( e == null && ladderType == null ) { + sender.sendMessage( "&cInvalid edge value. &3[&7top bottom north east south west walls&3]" ); + sender.sendMessage( "&cUse 'ladderType' for the Edge with &3[&7none normal wide jumbo full&3] as the patterns." ); + return; + } + + if ( linerPattern == null && ladderType == null ) { + sender.sendMessage( "&cInvalid pattern.&3 Select one of these: [&7" + + LinerPatterns.toStringAll() + "&3]" ); + return; + } + + boolean isForced = false; + if ( force != null && !"force".equalsIgnoreCase( force ) && !"no".equalsIgnoreCase( force ) ) { + sender.sendMessage( + String.format( "&3The valid values for &7force &3 are &7force&3 and &7no&3. " + + "Was &2[&7%s&2]", force ) ); + } + else if ( "force".equalsIgnoreCase( force ) ) { + isForced = true; + } + + PrisonMines pMines = PrisonMines.getInstance(); + + List mines = new ArrayList<>(); + + if ( "*all*".equalsIgnoreCase( mineName ) ) { + mines.addAll( pMines.getMines() ); + } + else { + mines.add( pMines.getMine(mineName) ); + + } + + for ( Mine mine : mines ) { + boolean resetLiner = false; + + if ( ladderType != null ) { + mine.getLinerData().setLadderType( ladderType ); + sender.sendMessage( "&7The liner's ladderType has been set to '" + ladderType.name() + + "' for mine " + mine.getName() ); + + resetLiner = true; + } + else if ( linerPattern == LinerPatterns.removeAll ) { + + mine.getLinerData().removeAll(); + sender.sendMessage( "&7All liners have been removed from mine " + mine.getName() ); + } + else if ( linerPattern == LinerPatterns.remove ) { + mine.getLinerData().remove( e ); + sender.sendMessage( "&7The liner for the " + e.name() + " has been removed from mine " + mine.getName() ); + } + else { + mine.getLinerData().setLiner( e, linerPattern, isForced ); + + resetLiner = true; + } + + pMines.getMineManager().saveMine( mine ); + + // Do not try to update the liner if it's a virtual mine: + if ( resetLiner && !mine.isVirtual() ) { + + new MineLinerBuilder( mine, e, linerPattern, isForced ); + } } } -// @Command(identifier = "mines set resetpaging", permissions = "mines.resetpaging", -// description = "Enable paging during a mine reset.") -// public void setMineResetPagingCommand(CommandSender sender, -// @Arg(name = "mineName", description = "The name of the mine to edit.") String mineName, -// @Arg(name = "paging", def="disabled", -// description = "Enable or disable paging [disable, enable]") -// String paging -// ) { -// -// if (performCheckMineExists(sender, mineName)) { -// setLastMineReferenced(mineName); -// -// PrisonMines pMines = PrisonMines.getInstance(); -// Mine m = pMines.getMine(mineName); -// -//// if ( !m.isEnabled() ) { -//// sender.sendMessage( "&cMine is disabled&7. Use &a/mines info &7for possible cause." ); -//// return; -//// } -// -// if ( paging == null || !"disable".equalsIgnoreCase( paging ) && !"enable".equalsIgnoreCase( paging ) ) { -// sender.sendMessage( "&cInvalid paging option&7. Use &adisable&7 or &aenable&7" ); -// return; -// } -// -// if ( "disable".equalsIgnoreCase( paging ) && m.isUsePagingOnReset() ) { -// m.setUsePagingOnReset( false ); -// pMines.getMineManager().saveMine( m ); -// sender.sendMessage( String.format( "&7Mine Reset Paging has been disabled for mine %s.", m.getTag()) ); -// } -// else if ( "enable".equalsIgnoreCase( paging ) && !m.isUsePagingOnReset() ) { -// m.setUsePagingOnReset( true ); -// pMines.getMineManager().saveMine( m ); -// sender.sendMessage( String.format( "&7Mine Reset Paging has been enabled for mine %s.", m.getTag()) ); -// } -// else { -// sender.sendMessage( String.format( "&7Mine Reset Paging status has not changed for mine %s.", m.getTag()) ); -// -// } -// -// } -// } - - @Command(identifier = "mines set mineSweeper", permissions = "mines.set", description = "Enable the Mine Sweeper task that is used to update the block counts " + "in the mine if there is another plugin that is breaking blocks and " + @@ -3280,53 +3026,53 @@ public void setMineSweeperCommand(CommandSender sender, String mineSweeper ) { - if ( mineSweeper == null || !"disable".equalsIgnoreCase( mineSweeper ) && - !"enable".equalsIgnoreCase( mineSweeper ) ) { - sender.sendMessage( "&cInvalid paging option&7. Use &adisable&7 or &aenable&7" ); - return; - } - - PrisonMines pMines = PrisonMines.getInstance(); - - if ( mineName != null && "*all*".equalsIgnoreCase( mineName ) ) { - - for ( Mine mine : pMines.getMines() ) { - if ( "disable".equalsIgnoreCase( mineSweeper ) && mine.isMineSweeperEnabled() ) { - mine.setMineSweeperEnabled( false ); - pMines.getMineManager().saveMine( mine ); - sender.sendMessage( String.format( "&7Mine Sweeper has been disabled for mine %s.", mine.getTag()) ); - } - else if ( "enable".equalsIgnoreCase( mineSweeper ) && !mine.isMineSweeperEnabled() ) { - mine.setMineSweeperEnabled( true ); - pMines.getMineManager().saveMine( mine ); - sender.sendMessage( String.format( "&7Mine Sweeper has been enabled for mine %s.", mine.getTag()) ); - } - } - - return; - } - + if ( mineSweeper == null || !"disable".equalsIgnoreCase( mineSweeper ) && + !"enable".equalsIgnoreCase( mineSweeper ) ) { + sender.sendMessage( "&cInvalid paging option&7. Use &adisable&7 or &aenable&7" ); + return; + } + + PrisonMines pMines = PrisonMines.getInstance(); + + if ( mineName != null && "*all*".equalsIgnoreCase( mineName ) ) { + + for ( Mine mine : pMines.getMines() ) { + if ( "disable".equalsIgnoreCase( mineSweeper ) && mine.isMineSweeperEnabled() ) { + mine.setMineSweeperEnabled( false ); + pMines.getMineManager().saveMine( mine ); + sender.sendMessage( String.format( "&7Mine Sweeper has been disabled for mine %s.", mine.getTag()) ); + } + else if ( "enable".equalsIgnoreCase( mineSweeper ) && !mine.isMineSweeperEnabled() ) { + mine.setMineSweeperEnabled( true ); + pMines.getMineManager().saveMine( mine ); + sender.sendMessage( String.format( "&7Mine Sweeper has been enabled for mine %s.", mine.getTag()) ); + } + } + + return; + } + if (performCheckMineExists(sender, mineName)) { - setLastMineReferenced(mineName); - - Mine m = pMines.getMine(mineName); + setLastMineReferenced(mineName); + + Mine m = pMines.getMine(mineName); if ( "disable".equalsIgnoreCase( mineSweeper ) && m.isMineSweeperEnabled() ) { - m.setMineSweeperEnabled( false ); - pMines.getMineManager().saveMine( m ); - sender.sendMessage( String.format( "&7Mine Sweeper has been disabled for mine %s.", m.getTag()) ); + m.setMineSweeperEnabled( false ); + pMines.getMineManager().saveMine( m ); + sender.sendMessage( String.format( "&7Mine Sweeper has been disabled for mine %s.", m.getTag()) ); } else if ( "enable".equalsIgnoreCase( mineSweeper ) && !m.isMineSweeperEnabled() ) { - m.setMineSweeperEnabled( true ); - pMines.getMineManager().saveMine( m ); - sender.sendMessage( String.format( "&7Mine Sweeper has been enabled for mine %s.", m.getTag()) ); + m.setMineSweeperEnabled( true ); + pMines.getMineManager().saveMine( m ); + sender.sendMessage( String.format( "&7Mine Sweeper has been enabled for mine %s.", m.getTag()) ); } else { sender.sendMessage( String.format( "&7Mine Sweeper status has not changed for mine %s.", m.getTag()) ); } - } + } } @@ -3353,196 +3099,167 @@ public void mineTp(CommandSender sender, ) { - if ( mineName != null && - "list".equals( mineName )) { - - Player player = playerName != null && playerName.trim().length() > 0 ? - getPlayerByName( playerName ) : - sender.getRankPlayer(); - -// Player playerAlt = getPlayer( playerName ); -// -// if ( playerAlt != null ) { -// player = playerAlt; -// } - - if ( player == null ) { - Output.get().logInfo( "Mine TP List: You must either be a player, or refer to a valid player." ); - return; - } - - Prison.get().getPlatform().listAllMines( sender, player ); - - return; - } - - - if ( mineName != null && - ("spawn".equalsIgnoreCase( mineName ) || "mine".equalsIgnoreCase( mineName )) ) { - target = mineName; - // Since the value spawn and mine are the last parameters, then we know playerName and - // mineName were not provided so set them to empty Strings: - playerName = ""; - mineName = ""; - } - - - // If playerName was not specified, then it could contain the value of target, if so, then copy - // to the target variable and set playerName to an empty String. - if ( playerName != null && - ("spawn".equalsIgnoreCase( playerName ) || "mine".equalsIgnoreCase( playerName )) ) { - target = playerName; - playerName = ""; - } - - // Only valid values are mine and spawn, if anything other than these, set value to spawn: - if ( target == null || - !("spawn".equalsIgnoreCase( target ) || "mine".equalsIgnoreCase( target )) ) { - target = "spawn"; - } - //setLastMineReferenced(mineName); - - PrisonMines pMines = PrisonMines.getInstance(); - Mine m = null; - - // Reset the sender's miscText field: - sender.setMiscText( null ); - - if ( mineName == null || mineName.trim().isEmpty() ) { - // Need to find a "correct" mine to TP to. - - m = (Mine) Prison.get().getPlatform().getPlayerDefaultMine( sender ); - - if ( m == null ) { - - teleportNoTargetMineFoundMsg( sender ); - return; - } - } - else { - - // Load mine information first to confirm the mine exists and the parameter is correct: - if (!performCheckMineExists(sender, mineName)) { - return; - } - - - m = pMines.getMine(mineName); - } - - - - if ( m.isVirtual() ) { - teleportCannotUseVirtualMinesMsg( sender ); - return; - } + if ( mineName != null && + "list".equals( mineName )) { + + Player player = playerName != null && playerName.trim().length() > 0 ? + getPlayerByName( playerName ) : + sender.getRankPlayer(); + + if ( player == null ) { + Output.get().logInfo( "Mine TP List: You must either be a player, or refer to a valid player." ); + return; + } + + Prison.get().getPlatform().listAllMines( sender, player ); + + return; + } + + if ( mineName != null && + ("spawn".equalsIgnoreCase( mineName ) || "mine".equalsIgnoreCase( mineName )) ) { + target = mineName; + // Since the value spawn and mine are the last parameters, then we know playerName and + // mineName were not provided so set them to empty Strings: + playerName = ""; + mineName = ""; + } + + + // If playerName was not specified, then it could contain the value of target, if so, then copy + // to the target variable and set playerName to an empty String. + if ( playerName != null && + ("spawn".equalsIgnoreCase( playerName ) || "mine".equalsIgnoreCase( playerName )) ) { + target = playerName; + playerName = ""; + } + + // Only valid values are mine and spawn, if anything other than these, set value to spawn: + if ( target == null || + !("spawn".equalsIgnoreCase( target ) || "mine".equalsIgnoreCase( target )) ) { + target = "spawn"; + } + + PrisonMines pMines = PrisonMines.getInstance(); + Mine m = null; - Player player = sender.getPlatformPlayer(); - - - // This is not working... it should return an online player... - Player playerAlt = getOnlinePlayer( playerName ); - - - if ( playerName != null && playerName.trim().length() > 0 && playerAlt == null) { - teleportNamedPlayerMustBeIngameMsg( sender ); - return; - } - - - if ( (player == null || !player.isOnline()) && playerAlt != null && !playerAlt.isOnline() ) { - - teleportPlayerMustBeIngameMsg( sender ); - return; - } - - - boolean isOp = sender.isOp(); - - if ( isOp && playerAlt != null && playerAlt.isOnline() ) { - - // The person issuing the tp command is op and they are trying to TP another player - player = playerAlt; - - // Console is trying to TP someone, the other checks do not apply: - teleportPlayer( playerAlt, m, target ); - return; - } - else if ( (player == null || !player.isOnline()) && playerAlt != null && playerAlt.isOnline() ) { - - // If the sender is console or its being ran as a rank command, and the playerName is - // a valid online player, then TP them: - - teleportPlayer( playerAlt, m, target ); - return; - } - else if ( playerAlt != null && !player.getName().equalsIgnoreCase( playerAlt.getName() ) ) { - - teleportCannotTeleportOtherPlayersMsg( sender ); - return; - } + // Reset the sender's miscText field: + sender.setMiscText( null ); + + if ( mineName == null || mineName.trim().isEmpty() ) { + // Need to find a "correct" mine to TP to. + + m = (Mine) Prison.get().getPlatform().getPlayerDefaultMine( sender ); + + if ( m == null ) { + + teleportNoTargetMineFoundMsg( sender ); + return; + } + } + else { + + // Load mine information first to confirm the mine exists and the parameter is correct: + if (!performCheckMineExists(sender, mineName)) { + return; + } + + + m = pMines.getMine(mineName); + } + + + + if ( m.isVirtual() ) { + teleportCannotUseVirtualMinesMsg( sender ); + return; + } + + + Player player = sender.getPlatformPlayer(); + + + // This is not working... it should return an online player... + Player playerAlt = getOnlinePlayer( playerName ); + + + if ( playerName != null && playerName.trim().length() > 0 && playerAlt == null) { + teleportNamedPlayerMustBeIngameMsg( sender ); + return; + } - // From here on down, cannot use playerAlt, so must use either sender or player: - if ( mineName == null || mineName.trim().isEmpty() ) { - // Need to find a "correct" mine to TP to. - - m = (Mine) Prison.get().getPlatform().getPlayerDefaultMine( sender ); - - if ( m == null ) { - - teleportNoTargetMineFoundMsg( sender ); - return; - } - } + if ( (player == null || !player.isOnline()) && playerAlt != null && !playerAlt.isOnline() ) { + + teleportPlayerMustBeIngameMsg( sender ); + return; + } + + + boolean isOp = sender.isOp(); + + if ( isOp && playerAlt != null && playerAlt.isOnline() ) { + + // The person issuing the tp command is op and they are trying to TP another player + player = playerAlt; + + // Console is trying to TP someone, the other checks do not apply: + teleportPlayer( playerAlt, m, target ); + return; + } + else if ( (player == null || !player.isOnline()) && playerAlt != null && playerAlt.isOnline() ) { + + // If the sender is console or its being ran as a rank command, and the playerName is + // a valid online player, then TP them: + + teleportPlayer( playerAlt, m, target ); + return; + } + else if ( playerAlt != null && !player.getName().equalsIgnoreCase( playerAlt.getName() ) ) { + + teleportCannotTeleportOtherPlayersMsg( sender ); + return; + } + + // From here on down, cannot use playerAlt, so must use either sender or player: + + if ( mineName == null || mineName.trim().isEmpty() ) { + // Need to find a "correct" mine to TP to. + + m = (Mine) Prison.get().getPlatform().getPlayerDefaultMine( sender ); + + if ( m == null ) { + + teleportNoTargetMineFoundMsg( sender ); + return; + } + } - // NOTE: Mine.hasTPAccess() checks for rank access and also if they have perms set. + // NOTE: Mine.hasTPAccess() checks for rank access and also if they have perms set. if ( !isOp && !m.hasTPAccess( player ) ) { - teleportUnableToTeleportMsg( sender ); - return; - - } - -// String minePermission = "mines.tp." + m.getName().toLowerCase(); -// if ( !isOp && -// !sender.hasPermission("mines.tp") && -// !sender.hasPermission( minePermission ) ) { -// -// Output.get() -// .sendError(sender, "Sorry. You're unable to teleport there." ); -// return; -// } - - - -// if ( !m.isEnabled() ) { -// sender.sendMessage( "&cMine is disabled&7. Use &a/mines info &7for possible cause." ); -// return; -// } - - if ( sender.isPlayer() ) { - teleportPlayer( (Player) sender, m, target ); - - String msg = teleportSuccessMsg( m.getTag() ); - - if ( sender.getMiscText() != null ) { - msg = msg + " " + sender.getMiscText(); - } -// String msg = String.format( -// "&3Teleported to mine %s. %s", -// m.getTag(), -// ( sender.getMiscText() == null ? "" : sender.getMiscText() ) -// ); - sender.sendMessage( msg ); - -// m.teleportPlayerOut( (Player) sender, target ); - } else { - teleportFailedMsg( sender ); - } + teleportUnableToTeleportMsg( sender ); + return; + + } + + + if ( sender.isPlayer() ) { + teleportPlayer( (Player) sender, m, target ); + + String msg = teleportSuccessMsg( m.getTag() ); + + if ( sender.getMiscText() != null ) { + msg = msg + " " + sender.getMiscText(); + } + sender.sendMessage( msg ); + + } else { + teleportFailedMsg( sender ); + } } @@ -3557,66 +3274,60 @@ else if ( playerAlt != null && !player.getName().equalsIgnoreCase( playerAlt.get public void mineTpTop(CommandSender sender ) { - Player player = sender.getPlatformPlayer(); - //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, "", "", ""); - } - - + Player player = sender.getPlatformPlayer(); + + 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" ) ) { - - // if warm up enabled: - double maxDistance = Prison.get().getPlatform(). - getConfigDouble( "prison-mines.tp-warmup.movementMaxDistance", 1.0 ); - long delayInTicks = Prison.get().getPlatform(). - getConfigLong( "prison-mines.tp-warmup.delayInTicks", 20 ); - - MineTeleportWarmUpTask mineTeleportWarmUp = new MineTeleportWarmUpTask( - player, mine, target, maxDistance ); - PrisonTaskSubmitter.runTaskLater( mineTeleportWarmUp, delayInTicks ); - } - else { - - mine.teleportPlayerOut( player, target ); - - // To "move" the player out of the mine, they are elevated by one block above the surface - // so need to remove the glass block if one is spawned under them. If there is no glass - // block, then it will do nothing. - mine.submitTeleportGlassBlockRemoval(); - } - - + if ( Prison.get().getPlatform().getConfigBooleanFalse( "prison-mines.tp-warmup.enabled" ) ) { + + // if warm up enabled: + double maxDistance = Prison.get().getPlatform(). + getConfigDouble( "prison-mines.tp-warmup.movementMaxDistance", 1.0 ); + long delayInTicks = Prison.get().getPlatform(). + getConfigLong( "prison-mines.tp-warmup.delayInTicks", 20 ); + + MineTeleportWarmUpTask mineTeleportWarmUp = new MineTeleportWarmUpTask( + player, mine, target, maxDistance ); + PrisonTaskSubmitter.runTaskLater( mineTeleportWarmUp, delayInTicks ); + } + else { + + mine.teleportPlayerOut( player, target ); + + // To "move" the player out of the mine, they are elevated by one block above the surface + // so need to remove the glass block if one is spawned under them. If there is no glass + // block, then it will do nothing. + mine.submitTeleportGlassBlockRemoval(); + } } @@ -3626,22 +3337,22 @@ private void teleportPlayer( Player player, Mine mine, String target ) { "(1 tick vs. 10 ticks).") public void mineStats(CommandSender sender) { - PrisonMines pMines = PrisonMines.getInstance(); - MineManager mMan = pMines.getMineManager(); - - // toggle the stats: - mMan.setMineStats( !mMan.isMineStats() ); - - // When mine stats are enabled, then it will also enable the high resolution - // tracking of the Prison TPS: - Prison.get().getPrisonTPS().setHighResolution( mMan.isMineStats() ); - - if ( mMan.isMineStats() ) { - sender.sendMessage( - "&3Mine Stats are now enabled. Use &7/mines list&3 to view stats on last mine reset. "); - } else { - sender.sendMessage( "&3Mine stats are now disabled." ); - } + PrisonMines pMines = PrisonMines.getInstance(); + MineManager mMan = pMines.getMineManager(); + + // toggle the stats: + mMan.setMineStats( !mMan.isMineStats() ); + + // When mine stats are enabled, then it will also enable the high resolution + // tracking of the Prison TPS: + Prison.get().getPrisonTPS().setHighResolution( mMan.isMineStats() ); + + if ( mMan.isMineStats() ) { + sender.sendMessage( + "&3Mine Stats are now enabled. Use &7/mines list&3 to view stats on last mine reset. "); + } else { + sender.sendMessage( "&3Mine stats are now disabled." ); + } } @@ -3650,102 +3361,90 @@ public void mineStats(CommandSender sender) { description = "Identifies what mines you are in, or are the closest to." ) public void mineWhereAmI(CommandSender sender) { - Player player = sender.getPlatformPlayer(); - - if (player == null || !player.isOnline()) { - sender.sendMessage( "&3You must be a player in the game to run this command." ); - return; - } - - player.sendMessage( "&3Your coordinates are: &7" + player.getLocation().toBlockCoordinates() ); - - PrisonMines pMines = PrisonMines.getInstance(); - - - Mine lookingAtMine = null; - - List sightBlocks = player.getLineOfSightBlocks(); - -// Block sightBlock = player.getLineOfSightBlock(); -// Location sightLocation = sightBlock != null ? sightBlock.getLocation() : null; - - - List inMine = new ArrayList<>(); - TreeMap nearMine = new TreeMap<>(); - for ( Mine mine : pMines.getMineManager().getMines() ) { - - - // Check the first 10 blocks in the line of sight to see if any are in a mine. - // The reason why the first 10 are checked is to "look" through mine liners. - if ( lookingAtMine == null && sightBlocks.size() > 0 ) { - int cnt = 0; - for ( Block sightBlock : sightBlocks ) { - if ( mine.isInMineExact( sightBlock.getLocation() ) ) { - lookingAtMine = mine; - break; - } - if ( cnt++ < 10 ) { + Player player = sender.getPlatformPlayer(); + + if (player == null || !player.isOnline()) { + sender.sendMessage( "&3You must be a player in the game to run this command." ); + return; + } + + player.sendMessage( "&3Your coordinates are: &7" + player.getLocation().toBlockCoordinates() ); + + PrisonMines pMines = PrisonMines.getInstance(); + + + Mine lookingAtMine = null; + + List sightBlocks = player.getLineOfSightBlocks(); + + List inMine = new ArrayList<>(); + TreeMap nearMine = new TreeMap<>(); + for ( Mine mine : pMines.getMineManager().getMines() ) { + + + // Check the first 10 blocks in the line of sight to see if any are in a mine. + // The reason why the first 10 are checked is to "look" through mine liners. + if ( lookingAtMine == null && sightBlocks.size() > 0 ) { + int cnt = 0; + for ( Block sightBlock : sightBlocks ) { + if ( mine.isInMineExact( sightBlock.getLocation() ) ) { + lookingAtMine = mine; + break; + } + if ( cnt++ < 10 ) { + break; + } + } + } + + if ( !mine.isVirtual() && mine.getBounds().withinIncludeTopBottomOfMine( player.getLocation() ) ) { + inMine.add( mine ); + } + + // This is checking for within a certain distance from any mine, so we just need to use + // some arbitrary distance as a max radius. We do not want to use the individual values + // that have been set for each mine. + else if ( !mine.isVirtual() && mine.getBounds().within( player.getLocation(), + Mine.MINE_RESET__BROADCAST_RADIUS_BLOCKS) ) { + Double distance = mine.getBounds().getDistance3d( player.getLocation() ); + nearMine.put( distance.intValue(), mine ); + } + } + + if ( lookingAtMine != null ) { + double distance = lookingAtMine.getBounds().getDistance3d( player.getLocation() ); + DecimalFormat dFmt = Prison.get().getDecimalFormat("#,##0.0"); + sender.sendMessage( String.format( "&3You are looking at mine &7%s &3which is &7%s &3blocks away.", + lookingAtMine.getTag(), dFmt.format( distance ) ) ); + } + + if ( inMine.size() > 0 ) { + // You are in the mines: + for ( Mine m : inMine ) { + sender.sendMessage( "&3You are in mine &7" + m.getTag() ); + } + } + if ( nearMine.size() > 0 ) { + // You are near the mines: + int cnt = 0; + Set distances = nearMine.keySet(); + for ( Integer dist : distances ) { + Mine m = nearMine.get( dist ); + sender.sendMessage( "&3You are &7" + dist + " &7blocks away from the center of mine &3" + m.getTag() ); + if ( ++cnt >= 5 ) { break; } } - } -// if ( sightLocation != null && mine.isInMineExact( sightLocation )) { -// lookingAtMine = mine; -// } - - if ( !mine.isVirtual() && mine.getBounds().withinIncludeTopBottomOfMine( player.getLocation() ) ) { - inMine.add( mine ); - } - - // This is checking for within a certain distance from any mine, so we just need to use - // some arbitrary distance as a max radius. We do not want to use the individual values - // that have been set for each mine. - else if ( !mine.isVirtual() && mine.getBounds().within( player.getLocation(), - Mine.MINE_RESET__BROADCAST_RADIUS_BLOCKS) ) { - Double distance = mine.getBounds().getDistance3d( player.getLocation() ); -// Double distance = new Bounds( mine.getBounds().getCenter(), player.getLocation()).getDistance(); - nearMine.put( distance.intValue(), mine ); - } - } - - if ( lookingAtMine != null ) { - double distance = lookingAtMine.getBounds().getDistance3d( player.getLocation() ); - DecimalFormat dFmt = Prison.get().getDecimalFormat("#,##0.0"); - sender.sendMessage( String.format( "&3You are looking at mine &7%s &3which is &7%s &3blocks away.", - lookingAtMine.getTag(), dFmt.format( distance ) ) ); - } - - if ( inMine.size() > 0 ) { - // You are in the mines: - for ( Mine m : inMine ) { - sender.sendMessage( "&3You are in mine &7" + m.getTag() ); - } - } - if ( nearMine.size() > 0 ) { - // You are near the mines: - int cnt = 0; - Set distances = nearMine.keySet(); - for ( Integer dist : distances ) { - Mine m = nearMine.get( dist ); - sender.sendMessage( "&3You are &7" + dist + " &7blocks away from the center of mine &3" + m.getTag() ); - if ( ++cnt >= 5 ) { - break; - } - } - - } - else if ( inMine.size() == 0 ) { - // you are not near any mines: - sender.sendMessage( "&3Sorry, you are not within " + Mine.MINE_RESET__BROADCAST_RADIUS_BLOCKS + - " blocks from any mine." ); - } + + } + else if ( inMine.size() == 0 ) { + // you are not near any mines: + sender.sendMessage( "&3Sorry, you are not within " + Mine.MINE_RESET__BROADCAST_RADIUS_BLOCKS + + " blocks from any mine." ); + } } -// private Player getPlayer( CommandSender sender ) { -// Optional player = Prison.get().getPlatform().getPlayer( sender.getName() ); -// return player.isPresent() ? player.get() : null; -// } private Player getOnlinePlayer( String playerName ) { Player player = null; @@ -3763,12 +3462,12 @@ private Player getOnlinePlayer( String playerName ) { onlyPlayers = false ) public void wandCommand(CommandSender sender) { - Player player = sender.getPlatformPlayer(); - - if (player == null || !player.isOnline()) { - sender.sendMessage( "&3You must be a player in the game to run this command." ); - return; - } + Player player = sender.getPlatformPlayer(); + + if (player == null || !player.isOnline()) { + sender.sendMessage( "&3You must be a player in the game to run this command." ); + return; + } Prison.get().getSelectionManager().bestowSelectionTool(player); sender.sendMessage( @@ -3793,7 +3492,6 @@ public void blockEventList(CommandSender sender, setLastMineReferenced(mineName); PrisonMines pMines = PrisonMines.getInstance(); -// MineManager mMan = pMines.getMineManager(); Mine m = pMines.getMine(mineName); if (m.getBlockEvents() == null || m.getBlockEvents().size() == 0) { @@ -3814,91 +3512,69 @@ public void blockEventList(CommandSender sender, } private void generateBlockEventListing( Mine m, ChatDisplay display, boolean includeRemove ) { - - BulletedListComponent.BulletedListBuilder builder = - new BulletedListComponent.BulletedListBuilder(); - - DecimalFormat dFmt = Prison.get().getDecimalFormat("0.00000"); - - int rowNumber = 0; - for (MineBlockEvent blockEvent : m.getBlockEvents()) { - - RowComponent row = new RowComponent(); - - String chance = dFmt.format( blockEvent.getChance() ); - - row.addTextComponent( " &3Row: &d%d ", ++rowNumber ); - - FancyMessage msgPercent = new FancyMessage( String.format( "&7%s%% ", chance ) ) - .suggest( "/mines blockEvent percent " + m.getName() + " " + rowNumber + " [%]" ) - .tooltip("Percent Chance - Click to Edit"); - row.addFancy( msgPercent ); - - FancyMessage msgPerm = new FancyMessage( String.format( "&3[&7%s&3] ", - blockEvent.getPermission() ) ) - .suggest( "/mines blockEvent permission " + m.getName() + " " + rowNumber + " [permisson]" ) - .tooltip("Permission - Click to Edit"); - row.addFancy( msgPerm ); - - FancyMessage msgEventType = new FancyMessage( String.format( "&7%s", - blockEvent.getEventType().name() ) ) - .suggest( "/mines blockEvent eventType " + m.getName() + " " + rowNumber + " [eventType]" ) - .tooltip("Event Type - Click to Edit"); - row.addFancy( msgEventType ); - - if ( blockEvent.getTriggered() != null ) { - - FancyMessage msgTriggered = new FancyMessage( String.format( "&3:&7%s", - blockEvent.getTriggered() ) ) - .suggest( "/mines blockEvent triggered " + m.getName() + " " + rowNumber + " [triggered]" ) - .tooltip("Triggered - Click to Edit"); - row.addFancy( msgTriggered ); - } - - FancyMessage msgMode = new FancyMessage( String.format( " &3(&7%s&3) ", - blockEvent.getTaskMode().name() ) ) - .suggest( "/mines blockEvent mode " + m.getName() + " " + rowNumber + " [mode]" ) - .tooltip("Event Task Mode - Click to Edit"); - row.addFancy( msgMode ); - - FancyMessage msgCommand = new FancyMessage( String.format( " &a'&7%s&a'", - blockEvent.getCommand() ) ) - //.command("/mines blockEvent remove " + mineName + " " + blockEvent.getCommand() ) - .suggest( "/mines blockEvent update " + m.getName() + " " + rowNumber + " " + blockEvent.getCommand() ) - .tooltip("BlockEvent Command - Click to Edit"); - row.addFancy( msgCommand ); - - -// if ( blockEvent.getPrisonBlocks().size() > 0 ) { -// StringBuilder sb = new StringBuilder(); -// -// for ( PrisonBlock block : blockEvent.getPrisonBlocks() ) { -// if ( sb.length() > 0 ) { -// sb.append( ", " ); -// } -// sb.append( block.getBlockName() ); -// } -// if ( sb.length() > 0 ) { -// sb.insert( 0, "[" ); -// sb.append( "]" ); -// -// FancyMessage msgBlocks = new FancyMessage( sb.toString() ) -// .tooltip( "Block filters. Click block list to add another." ) -// .suggest( "/mines blockvent block add " + m.getName() + " " + -// rowNumber + " block_name" ); -// -// row.addFancy( msgBlocks ); -// } -// } - - if ( includeRemove ) { - - FancyMessage msgRemove = new FancyMessage( " &4Remove&3" ) - .suggest("/mines blockEvent remove " + m.getName() + " " + rowNumber ) - .tooltip("Click to Delete this BlockEvent"); - row.addFancy( msgRemove ); - } + + BulletedListComponent.BulletedListBuilder builder = + new BulletedListComponent.BulletedListBuilder(); + + DecimalFormat dFmt = Prison.get().getDecimalFormat("0.00000"); + + int rowNumber = 0; + for (MineBlockEvent blockEvent : m.getBlockEvents()) { + RowComponent row = new RowComponent(); + + String chance = dFmt.format( blockEvent.getChance() ); + + row.addTextComponent( " &3Row: &d%d ", ++rowNumber ); + + FancyMessage msgPercent = new FancyMessage( String.format( "&7%s%% ", chance ) ) + .suggest( "/mines blockEvent percent " + m.getName() + " " + rowNumber + " [%]" ) + .tooltip("Percent Chance - Click to Edit"); + row.addFancy( msgPercent ); + + FancyMessage msgPerm = new FancyMessage( String.format( "&3[&7%s&3] ", + blockEvent.getPermission() ) ) + .suggest( "/mines blockEvent permission " + m.getName() + " " + rowNumber + " [permisson]" ) + .tooltip("Permission - Click to Edit"); + row.addFancy( msgPerm ); + + FancyMessage msgEventType = new FancyMessage( String.format( "&7%s", + blockEvent.getEventType().name() ) ) + .suggest( "/mines blockEvent eventType " + m.getName() + " " + rowNumber + " [eventType]" ) + .tooltip("Event Type - Click to Edit"); + row.addFancy( msgEventType ); + + if ( blockEvent.getTriggered() != null ) { + + FancyMessage msgTriggered = new FancyMessage( String.format( "&3:&7%s", + blockEvent.getTriggered() ) ) + .suggest( "/mines blockEvent triggered " + m.getName() + " " + rowNumber + " [triggered]" ) + .tooltip("Triggered - Click to Edit"); + row.addFancy( msgTriggered ); + } + + FancyMessage msgMode = new FancyMessage( String.format( " &3(&7%s&3) ", + blockEvent.getTaskMode().name() ) ) + .suggest( "/mines blockEvent mode " + m.getName() + " " + rowNumber + " [mode]" ) + .tooltip("Event Task Mode - Click to Edit"); + row.addFancy( msgMode ); + + FancyMessage msgCommand = new FancyMessage( String.format( " &a'&7%s&a'", + blockEvent.getCommand() ) ) + //.command("/mines blockEvent remove " + mineName + " " + blockEvent.getCommand() ) + .suggest( "/mines blockEvent update " + m.getName() + " " + rowNumber + " " + blockEvent.getCommand() ) + .tooltip("BlockEvent Command - Click to Edit"); + row.addFancy( msgCommand ); + + + if ( includeRemove ) { + + FancyMessage msgRemove = new FancyMessage( " &4Remove&3" ) + .suggest("/mines blockEvent remove " + m.getName() + " " + rowNumber ) + .tooltip("Click to Delete this BlockEvent"); + row.addFancy( msgRemove ); + } + builder.add( row ); @@ -3906,17 +3582,17 @@ private void generateBlockEventListing( Mine m, ChatDisplay display, boolean inc String prisonBlocks = blockEvent.getPrisonBlockStrings(); if ( !prisonBlocks.isEmpty() ) { - RowComponent row2 = new RowComponent(); - - row2.addTextComponent( " " ); - - FancyMessage msgBlocks = new FancyMessage( String.format( " &bBlocks: &3[&7%s&3]", - prisonBlocks ) ) - .command("/mines blockEvent blocks " + m.getName() ) - .tooltip("Event Blocks - Click to Edit"); - row2.addFancy( msgBlocks ); - - builder.add( row2 ); + RowComponent row2 = new RowComponent(); + + row2.addTextComponent( " " ); + + FancyMessage msgBlocks = new FancyMessage( String.format( " &bBlocks: &3[&7%s&3]", + prisonBlocks ) ) + .command("/mines blockEvent blocks " + m.getName() ) + .tooltip("Event Blocks - Click to Edit"); + row2.addFancy( msgBlocks ); + + builder.add( row2 ); } } @@ -3953,7 +3629,7 @@ public void blockEventRemove(CommandSender sender, display.send(sender); - return; + return; } @@ -3963,11 +3639,11 @@ public void blockEventRemove(CommandSender sender, } if ( row > m.getBlockEvents().size() ) { - sender.sendMessage( - String.format("&7Please provide a valid row number no greater than &b%d&7. " + - "Was row=[&b%d&7]", - m.getBlockEvents().size(), (row == null ? "null" : row) )); - return; + sender.sendMessage( + String.format("&7Please provide a valid row number no greater than &b%d&7. " + + "Was row=[&b%d&7]", + m.getBlockEvents().size(), (row == null ? "null" : row) )); + return; } MineBlockEvent blockEvent = m.getBlockEvents().get( row - 1 ); @@ -3975,14 +3651,14 @@ public void blockEventRemove(CommandSender sender, if ( blockEvent != null && m.getBlockEventsRemove( blockEvent ) ) { - pMines.getMineManager().saveMine( m ); - - Output.get().sendInfo(sender, "Removed BlockEvent command '%s' from the mine '%s'.", - blockEvent.getCommand(), m.getTag()); + pMines.getMineManager().saveMine( m ); + + Output.get().sendInfo(sender, "Removed BlockEvent command '%s' from the mine '%s'.", + blockEvent.getCommand(), m.getTag()); } else { - Output.get().sendWarn(sender, - String.format("The mine %s doesn't contain that BlockEvent command. Nothing was changed.", - m.getTag())); + Output.get().sendWarn(sender, + String.format("The mine %s doesn't contain that BlockEvent command. Nothing was changed.", + m.getTag())); } // Redisplay the event list: @@ -4103,19 +3779,6 @@ public void blockEventAdd(CommandSender sender, "you can use with blockEvents") String mineName, @Arg(name = "percent", def = "100.0", description = "Percent chance between 0.0000 and 100.0") Double chance, -// @Arg(name = "permission", def = "none", -// description = "Optional permission that the player must have, or [none] for no perm." -// ) String perm, -// @Arg(name = "eventType", def = "eventTypeAll", -// description = "EventType to trigger BlockEvent: [eventTypeAll, eventBlockBreak, eventTEXplosion]" -// ) String eventType, -// @Arg(name = "triggered", def = "none", -// description = "TE Explosion Triggered sources. Requires TokenEnchant v18.11.0 or newer. [none, ...]" -// ) String triggered, -// @Arg(name = "taskMode", description = "Processing task mode to run the task as console. " + -// "Player runs as player. " + -// "[inline, inlinePlayer, sync, syncPlayer]", -// def = "inline") String mode, @Arg(name = "command") @Wildcard String command) { // Note: async is not an option since the bukkit dispatchCommand will run it as sync. @@ -4123,25 +3786,25 @@ public void blockEventAdd(CommandSender sender, if ( mineName != null && "placeholders".equalsIgnoreCase( mineName ) ) { - String placeholders = - - PrisonCommandTaskData.CustomPlaceholders.listPlaceholders( - PrisonCommandTaskData.CommandEnvironment.all_commands ) + " " + - - PrisonCommandTaskData.CustomPlaceholders.listPlaceholders( - PrisonCommandTaskData.CommandEnvironment.blockevent_commands ); - - String message = String.format( "Valid Placeholders that can be used with blockEvents: [%s]", - placeholders ); - - sender.sendMessage( message ); - return; + String placeholders = + + PrisonCommandTaskData.CustomPlaceholders.listPlaceholders( + PrisonCommandTaskData.CommandEnvironment.all_commands ) + " " + + + PrisonCommandTaskData.CustomPlaceholders.listPlaceholders( + PrisonCommandTaskData.CommandEnvironment.blockevent_commands ); + + String message = String.format( "Valid Placeholders that can be used with blockEvents: [%s]", + placeholders ); + + sender.sendMessage( message ); + return; } String perm = "none"; String mode = "sync"; // "inline"; - if (command.startsWith("/")) { + if (command.startsWith("/")) { command = command.replaceFirst("/", ""); } @@ -4152,103 +3815,72 @@ public void blockEventAdd(CommandSender sender, } if ( chance <= 0d || chance > 100.0d ) { - sender.sendMessage( - String.format("&7Please provide a valid value for chance " + - "between 0.0000 and 100.0. Was state=[&b%d&7]", - chance )); - return; + sender.sendMessage( + String.format("&7Please provide a valid value for chance " + + "between 0.0000 and 100.0. Was state=[&b%d&7]", + chance )); + return; } TaskMode taskMode = TaskMode.fromString( mode ); if ( mode == null || !taskMode.name().equalsIgnoreCase( mode ) ) { - sender.sendMessage( - String.format("&7Task mode is defaulting to %s. " + - "[inline, inlinePlayer, sync, syncPlayer] mode=[&b%s&7]", - taskMode.name(), mode )); - return; + sender.sendMessage( + String.format("&7Task mode is defaulting to %s. " + + "[inline, inlinePlayer, sync, syncPlayer] mode=[&b%s&7]", + taskMode.name(), mode )); + return; } if ( perm == null || perm.trim().length() == 0 || "none".equalsIgnoreCase( perm ) ) { - perm = ""; + perm = ""; } - -// BlockEventType eType = BlockEventType.fromString( eventType ); -// if ( !eType.name().equalsIgnoreCase( eventType ) ) { -// sender.sendMessage( -// String.format("&7Notice: The supplied eventType does not match the list of valid " + -// "BlockEventTypes therefore defaulting to eventTypeAll. Valid eventTypes are: " + -// "[eventTypeAll, eventBlockBreak, eventTEXplosion]", -// eventType )); -// } - -// if ( eType != BlockEventType.eventTEXplosion && triggered != null && !"none".equalsIgnoreCase( triggered ) ) { -// sender.sendMessage( "&7Notice: triggered is only valid exclusivly for eventTEXplosion. " + -// "Defaulting to none." ); -// triggered = null; -// } -// if ( triggered != null && "none".equalsIgnoreCase( triggered ) ) { -// triggered = null; -// } if ( command == null || command.trim().length() == 0 ) { - sender.sendMessage( - String.format( "&7Please provide a valid BlockEvent command: command=[%s]", command) ); - return; + sender.sendMessage( + String.format( "&7Please provide a valid BlockEvent command: command=[%s]", command) ); + return; } PrisonMines pMines = PrisonMines.getInstance(); -// MineManager mMan = pMines.getMineManager(); List mines = new ArrayList<>(); if ( "*all*".equalsIgnoreCase( mineName ) ) { - mines.addAll( pMines.getMines() ); + mines.addAll( pMines.getMines() ); } else { - setLastMineReferenced(mineName); - - Mine m = pMines.getMine(mineName); - mines.add( m ); + setLastMineReferenced(mineName); + + Mine m = pMines.getMine(mineName); + mines.add( m ); } for ( Mine m : mines ) { - MineBlockEvent blockEvent = new MineBlockEvent( chance, perm, command, taskMode ); - m.getBlockEvents().add( blockEvent ); - - pMines.getMineManager().saveMine( m ); - - Output.get().sendInfo(sender, "&7Added BlockEvent command '&b%s&7' " + - "&7to the mine '&b%s&7' with " + - "the optional permission %s. Using the mode %s.", - command, m.getTag(), - perm == null || perm.trim().length() == 0 ? "&3none&7" : "'&3" + perm + "&7'", - mode ); - -// String.format("&7Notice: &3The default eventType has been set to &7all&3. If you need " + -// "to change it to something else, then use the command &7/mines blockEvent eventType help&3. " + -// "[all, blockBreak, TEXplosion] The event type is what causes the block to break. " + -// "Token Enchant's Explosion events are covered and can be focused with the " + -// "triggered parameter." ); - - -// if ( eType == BlockEventType.eventTEXplosion ) { -// sender.sendMessage( "&7Notice: &3Since the event type is for TokenEnchant's eventTEXplosion, " + -// "then you may set the value of &7triggered&7 with the command " + -// "&7/mines blockEvent triggered help&3." ); -// } + MineBlockEvent blockEvent = new MineBlockEvent( chance, perm, command, taskMode ); + m.getBlockEvents().add( blockEvent ); + + pMines.getMineManager().saveMine( m ); + + Output.get().sendInfo(sender, "&7Added BlockEvent command '&b%s&7' " + + "&7to the mine '&b%s&7' with " + + "the optional permission %s. Using the mode %s.", + command, m.getTag(), + perm == null || perm.trim().length() == 0 ? "&3none&7" : "'&3" + perm + "&7'", + mode ); + } if ( !"*all*".equalsIgnoreCase( mineName ) ) { - // Redisplay the event list: - blockEventList( sender, mineName ); + // Redisplay the event list: + blockEventList( sender, mineName ); } } @@ -4271,7 +3903,6 @@ public void blockEventPercent(CommandSender sender, setLastMineReferenced(mineName); PrisonMines pMines = PrisonMines.getInstance(); -// MineManager mMan = pMines.getMineManager(); Mine m = pMines.getMine(mineName); @@ -4294,15 +3925,15 @@ public void blockEventPercent(CommandSender sender, // try to "suggest" reading this command: // mines blockEvent percent [row] [percent] - FancyMessage msgAddBlock = new FancyMessage( String.format( - "&7%s [row] [percent]", - commandRoot ) ) - .suggest( commandRoot + " [row] [percent]" ) - .tooltip("Change the percent for the blockEvent - Click to change"); - - RowComponent rowFancy = new RowComponent(); - rowFancy.addFancy( msgAddBlock ); - display.addComponent( rowFancy ); + FancyMessage msgAddBlock = new FancyMessage( String.format( + "&7%s [row] [percent]", + commandRoot ) ) + .suggest( commandRoot + " [row] [percent]" ) + .tooltip("Change the percent for the blockEvent - Click to change"); + + RowComponent rowFancy = new RowComponent(); + rowFancy.addFancy( msgAddBlock ); + display.addComponent( rowFancy ); display.send(sender); @@ -4311,19 +3942,19 @@ public void blockEventPercent(CommandSender sender, } if ( chance <= 0d || chance > 100.0d ) { - sender.sendMessage( - String.format("&7Please provide a valid value for chance " + - "between 0.0000 and 100.0. Was state=[&b%d&7]", - chance )); - return; + sender.sendMessage( + String.format("&7Please provide a valid value for chance " + + "between 0.0000 and 100.0. Was state=[&b%d&7]", + chance )); + return; } if ( row > m.getBlockEvents().size() ) { - sender.sendMessage( - String.format("&7Please provide a valid row number no greater than &b%d&7. " + - "Was row=[&b%d&7]", - m.getBlockEvents().size(), (row == null ? "null" : row) )); - return; + sender.sendMessage( + String.format("&7Please provide a valid row number no greater than &b%d&7. " + + "Was row=[&b%d&7]", + m.getBlockEvents().size(), (row == null ? "null" : row) )); + return; } MineBlockEvent blockEvent = m.getBlockEvents().get( row - 1 ); @@ -4366,7 +3997,6 @@ public void blockEventPermission(CommandSender sender, setLastMineReferenced(mineName); PrisonMines pMines = PrisonMines.getInstance(); -// MineManager mMan = pMines.getMineManager(); Mine m = pMines.getMine(mineName); @@ -4391,34 +4021,34 @@ public void blockEventPermission(CommandSender sender, // try to "suggest" reading this command: // mines blockEvent permission [row] [permission] - FancyMessage msgAddBlock = new FancyMessage( String.format( - "&7%s [row] [permission]", - commandRoot ) ) - .suggest( commandRoot + " [row] [permission]" ) - .tooltip("Change the permission for the blockEvent - Click to change"); - - RowComponent rowFancy = new RowComponent(); - rowFancy.addFancy( msgAddBlock ); - display.addComponent( rowFancy ); - - + FancyMessage msgAddBlock = new FancyMessage( String.format( + "&7%s [row] [permission]", + commandRoot ) ) + .suggest( commandRoot + " [row] [permission]" ) + .tooltip("Change the permission for the blockEvent - Click to change"); + + RowComponent rowFancy = new RowComponent(); + rowFancy.addFancy( msgAddBlock ); + display.addComponent( rowFancy ); + + display.send(sender); - return; + return; } if ( perm == null || perm.trim().length() == 0 || "none".equalsIgnoreCase( perm ) ) { - perm = ""; + perm = ""; } if ( row > m.getBlockEvents().size() ) { - sender.sendMessage( - String.format("&7Please provide a valid row number no greater than &b%d&7. " + - "Was row=[&b%d&7]", - m.getBlockEvents().size(), (row == null ? "null" : row) )); - return; + sender.sendMessage( + String.format("&7Please provide a valid row number no greater than &b%d&7. " + + "Was row=[&b%d&7]", + m.getBlockEvents().size(), (row == null ? "null" : row) )); + return; } MineBlockEvent blockEvent = m.getBlockEvents().get( row - 1 ); @@ -4468,7 +4098,6 @@ public void blockEventEventType(CommandSender sender, setLastMineReferenced(mineName); PrisonMines pMines = PrisonMines.getInstance(); -// MineManager mMan = pMines.getMineManager(); Mine m = pMines.getMine(mineName); @@ -4490,39 +4119,38 @@ public void blockEventEventType(CommandSender sender, // try to "suggest" reading this command: // mines blockEvent eventType [row] [eventType] - FancyMessage msgAddBlock = new FancyMessage( String.format( - "&7%s [row] [eventType]", - commandRoot ) ) - .suggest( commandRoot + " [row] [eventType]" ) - .tooltip("Change the eventtype for the blockEvent - Click to change"); - - RowComponent rowFancy = new RowComponent(); - rowFancy.addFancy( msgAddBlock ); - display.addComponent( rowFancy ); - - + FancyMessage msgAddBlock = new FancyMessage( String.format( + "&7%s [row] [eventType]", + commandRoot ) ) + .suggest( commandRoot + " [row] [eventType]" ) + .tooltip("Change the eventtype for the blockEvent - Click to change"); + + RowComponent rowFancy = new RowComponent(); + rowFancy.addFancy( msgAddBlock ); + display.addComponent( rowFancy ); + display.send(sender); - return; + return; } BlockEventType eType = BlockEventType.fromString( eventType ); if ( !eType.name().equalsIgnoreCase( eventType ) ) { - sender.sendMessage( - String.format("&7Notice: The supplied eventType does not match the list of valid " + - "BlockEventTypes therefore defaulting to eventTypeAll. Valid eventTypes are: " + - "[%s]", - eventType, BlockEventType.getPrimaryEventTypes() )); + sender.sendMessage( + String.format("&7Notice: The supplied eventType does not match the list of valid " + + "BlockEventTypes therefore defaulting to eventTypeAll. Valid eventTypes are: " + + "[%s]", + eventType, BlockEventType.getPrimaryEventTypes() )); } if ( row > m.getBlockEvents().size() ) { - sender.sendMessage( - String.format("&7Please provide a valid row number no greater than &b%d&7. " + - "Was row=[&b%d&7]", - m.getBlockEvents().size(), (row == null ? "null" : row) )); - return; + sender.sendMessage( + String.format("&7Please provide a valid row number no greater than &b%d&7. " + + "Was row=[&b%d&7]", + m.getBlockEvents().size(), (row == null ? "null" : row) )); + return; } MineBlockEvent blockEvent = m.getBlockEvents().get( row - 1 ); @@ -4536,7 +4164,7 @@ public void blockEventEventType(CommandSender sender, eType != BlockEventType.TEXplosion && eType != BlockEventType.PEExplosive ) { - blockEvent.setTriggered( null ); + blockEvent.setTriggered( null ); } pMines.getMineManager().saveMine( m ); @@ -4547,9 +4175,9 @@ public void blockEventEventType(CommandSender sender, eType.name(), m.getTag(), eTypeOld.name(), blockEvent.getCommand() ); if ( eType == BlockEventType.TEXplosion ) { - sender.sendMessage( "&7Notice: &3Since the event type is for TokenEnchant's eventTEXplosion, " + - "then you may set the value of &7triggered&7 with the command " + - "&7/mines blockEvent triggered help&3." ); + sender.sendMessage( "&7Notice: &3Since the event type is for TokenEnchant's eventTEXplosion, " + + "then you may set the value of &7triggered&7 with the command " + + "&7/mines blockEvent triggered help&3." ); } // Redisplay the event list: @@ -4584,7 +4212,6 @@ public void blockEventTriggered(CommandSender sender, setLastMineReferenced(mineName); PrisonMines pMines = PrisonMines.getInstance(); -// MineManager mMan = pMines.getMineManager(); Mine m = pMines.getMine(mineName); @@ -4607,18 +4234,17 @@ public void blockEventTriggered(CommandSender sender, // try to "suggest" reading this command: // mines blockEvent triggered [row] [triggered] - FancyMessage msgAddBlock = new FancyMessage( String.format( - "&7%s [row] [triggered]", - commandRoot ) ) - .suggest( commandRoot + " [row] [triggered]" ) - .tooltip("Change the triggered source for the blockEvent - Click to change"); - - RowComponent rowFancy = new RowComponent(); - rowFancy.addFancy( msgAddBlock ); - display.addComponent( rowFancy ); + FancyMessage msgAddBlock = new FancyMessage( String.format( + "&7%s [row] [triggered]", + commandRoot ) ) + .suggest( commandRoot + " [row] [triggered]" ) + .tooltip("Change the triggered source for the blockEvent - Click to change"); + + RowComponent rowFancy = new RowComponent(); + rowFancy.addFancy( msgAddBlock ); + display.addComponent( rowFancy ); - display.send(sender); return; @@ -4643,11 +4269,12 @@ public void blockEventTriggered(CommandSender sender, triggered != null && !"none".equalsIgnoreCase( triggered ) ) { - sender.sendMessage( "&7Notice: triggered is only valid with " + - "PrisonExplosion, TEXplosion, or PEExplosive. " + - "Defaulting to 'none'." ); - triggered = null; + sender.sendMessage( "&7Notice: triggered is only valid with " + + "PrisonExplosion, TEXplosion, or PEExplosive. " + + "Defaulting to 'none'." ); + triggered = null; } + if ( triggered != null && "none".equalsIgnoreCase( triggered ) ) { triggered = null; } @@ -4699,7 +4326,6 @@ public void blockEventJobMode(CommandSender sender, setLastMineReferenced(mineName); PrisonMines pMines = PrisonMines.getInstance(); -// MineManager mMan = pMines.getMineManager(); Mine m = pMines.getMine(mineName); @@ -4722,48 +4348,40 @@ public void blockEventJobMode(CommandSender sender, // try to "suggest" reading this command: // mines blockEvent taskMode [row] [taskMode] - FancyMessage msgAddBlock = new FancyMessage( String.format( - "&7%s [row] [taskMode]", - commandRoot ) ) - .suggest( commandRoot + " [row] [taskMode]" ) - .tooltip("Change the taskMode for the blockEvent - Click to change"); - - RowComponent rowFancy = new RowComponent(); - rowFancy.addFancy( msgAddBlock ); - display.addComponent( rowFancy ); + FancyMessage msgAddBlock = new FancyMessage( String.format( + "&7%s [row] [taskMode]", + commandRoot ) ) + .suggest( commandRoot + " [row] [taskMode]" ) + .tooltip("Change the taskMode for the blockEvent - Click to change"); + + RowComponent rowFancy = new RowComponent(); + rowFancy.addFancy( msgAddBlock ); + display.addComponent( rowFancy ); display.send(sender); - return; + return; } TaskMode taskMode = TaskMode.fromString( mode ); if ( mode == null || !taskMode.name().equalsIgnoreCase( mode ) ) { - sender.sendMessage( - String.format("&7Task mode is defaulting to %s. " + - "[inline, inlinePlayer, sync, syncPlayer] mode=[&b%s&7]", - taskMode.name(), mode )); - return; + sender.sendMessage( + String.format("&7Task mode is defaulting to %s. " + + "[inline, inlinePlayer, sync, syncPlayer] mode=[&b%s&7]", + taskMode.name(), mode )); + return; } -// if ( mode == null || !"sync".equalsIgnoreCase( mode ) && !"inline".equalsIgnoreCase( mode ) ) { -// sender.sendMessage( -// String.format("&7Please provide a valid mode for running the commands. " + -// "[inline, sync] mode=[&b%s&7]", -// mode )); -// return; -// } - if ( row > m.getBlockEvents().size() ) { - sender.sendMessage( - String.format("&7Please provide a valid row number no greater than &b%d&7. " + - "Was row=[&b%d&7]", - m.getBlockEvents().size(), (row == null ? "null" : row) )); - return; + sender.sendMessage( + String.format("&7Please provide a valid row number no greater than &b%d&7. " + + "Was row=[&b%d&7]", + m.getBlockEvents().size(), (row == null ? "null" : row) )); + return; } MineBlockEvent blockEvent = m.getBlockEvents().get( row - 1 ); @@ -4801,11 +4419,6 @@ public void blockEventBlockAdd(CommandSender sender, "this command will display a list of all current blockEvents for " + "this mine.") Integer rowBlockEvent, - // search is no longer needed nor is the wildcard join for blockName: -// @Arg(name = "search", description = "Optional keyword 'search' to search " + -// "based upon value of blockName. [search, none, ]", -// def = "") String search, -// @Wildcard(join=true) @Arg(name = "rowBlockName", description = "Row number of the block to add, or " + "if ommitted, then it will show a list of all of the blocks that " + "are available within the selected mine.", @@ -4819,7 +4432,6 @@ public void blockEventBlockAdd(CommandSender sender, setLastMineReferenced(mineName); PrisonMines pMines = PrisonMines.getInstance(); -// MineManager mMan = pMines.getMineManager(); Mine m = pMines.getMine(mineName); @@ -4840,28 +4452,28 @@ public void blockEventBlockAdd(CommandSender sender, // try to "suggest" reading this command: // mines blockEvent block add [row] [search} [block] - FancyMessage msgAddBlock = new FancyMessage( String.format( - "&7%s [rowBlockEvent] [rowBlockName]", - commandRoot ) ) - .suggest( commandRoot + " [rowBlockEvent] [rowBlockName]" ) - .tooltip("Add block to blockEvent - Click to Add"); - - RowComponent rowFancy = new RowComponent(); - rowFancy.addFancy( msgAddBlock ); - display.addComponent( rowFancy ); + FancyMessage msgAddBlock = new FancyMessage( String.format( + "&7%s [rowBlockEvent] [rowBlockName]", + commandRoot ) ) + .suggest( commandRoot + " [rowBlockEvent] [rowBlockName]" ) + .tooltip("Add block to blockEvent - Click to Add"); + + RowComponent rowFancy = new RowComponent(); + rowFancy.addFancy( msgAddBlock ); + display.addComponent( rowFancy ); display.send( sender ); - return; + return; } if ( rowBlockEvent > m.getBlockEvents().size() ) { - sender.sendMessage( - String.format("&7Please provide a valid row number no greater than &b%d&7. " + - "Was rowBlockEvent=[&b%d&7]", - m.getBlockEvents().size(), (rowBlockEvent == null ? "null" : rowBlockEvent) )); - return; + sender.sendMessage( + String.format("&7Please provide a valid row number no greater than &b%d&7. " + + "Was rowBlockEvent=[&b%d&7]", + m.getBlockEvents().size(), (rowBlockEvent == null ? "null" : rowBlockEvent) )); + return; } @@ -4870,74 +4482,70 @@ public void blockEventBlockAdd(CommandSender sender, if ( blockEvent != null ) { - if ( rowBlockName == null || rowBlockName == 0 || - rowBlockName > m.getPrisonBlocks().size() ) { - - String commandBlockEvent = String.format( "" + - "%s %d ", commandRoot, rowBlockEvent ); - - ChatDisplay display = new ChatDisplay("Add blocks to a BlockEvent for " + m.getTag() ); - display.addText("&8Select a block from this mine by using the block's row number:"); - display.addText("&8 " + commandBlockEvent + " [rowBlockName]"); - - DecimalFormat dFmt = Prison.get().getDecimalFormat("0.00000"); - - // Display a list of blocks for the mine: - int blockRow = 0; - - for ( PrisonBlock block : m.getPrisonBlocks() ) - { - - RowComponent rowB = new RowComponent(); - - rowB.addTextComponent( " &3Row: &d%d ", ++blockRow ); - - String message = String.format( "&7%s %s", - block.getBlockName(), dFmt.format( block.getChance() ) ); - - String command = String.format( "%s %d", commandBlockEvent, blockRow ); - - FancyMessage msgAddBlock = new FancyMessage( message ) - .suggest( command ) - .tooltip("Add selected block to blockEvent - Click to Add"); - - rowB.addFancy( msgAddBlock ); - - display.addComponent( rowB ); - } - - - display.send( sender ); - return; - } - - - // Old block model is not supported with blockEvent block filers: - PrisonBlock block = m.getPrisonBlocks().get( rowBlockName - 1 ); - - if ( block != null ) { - - blockEvent.addPrisonBlock( block ); - - pMines.getMineManager().saveMine( m ); - - sender.sendMessage( "Block has been added to BlockEvent" ); - - return; - } - -// PrisonBlockTypes prisonBlockTypes = Prison.get().getPlatform().getPrisonBlockTypes(); -// PrisonBlock block = prisonBlockTypes.getBlockTypesByName( blockName ); - + if ( rowBlockName == null || rowBlockName == 0 || + rowBlockName > m.getPrisonBlocks().size() ) { + + String commandBlockEvent = String.format( "" + + "%s %d ", commandRoot, rowBlockEvent ); + + ChatDisplay display = new ChatDisplay("Add blocks to a BlockEvent for " + m.getTag() ); + display.addText("&8Select a block from this mine by using the block's row number:"); + display.addText("&8 " + commandBlockEvent + " [rowBlockName]"); + + DecimalFormat dFmt = Prison.get().getDecimalFormat("0.00000"); + + // Display a list of blocks for the mine: + int blockRow = 0; + + for ( PrisonBlock block : m.getPrisonBlocks() ) + { + + RowComponent rowB = new RowComponent(); + + rowB.addTextComponent( " &3Row: &d%d ", ++blockRow ); + + String message = String.format( "&7%s %s", + block.getBlockName(), dFmt.format( block.getChance() ) ); + + String command = String.format( "%s %d", commandBlockEvent, blockRow ); + + FancyMessage msgAddBlock = new FancyMessage( message ) + .suggest( command ) + .tooltip("Add selected block to blockEvent - Click to Add"); + + rowB.addFancy( msgAddBlock ); + + display.addComponent( rowB ); + } + + + display.send( sender ); + return; + } + + + // Old block model is not supported with blockEvent block filers: + PrisonBlock block = m.getPrisonBlocks().get( rowBlockName - 1 ); + + if ( block != null ) { + + blockEvent.addPrisonBlock( block ); + + pMines.getMineManager().saveMine( m ); + + sender.sendMessage( "Block has been added to BlockEvent" ); + + return; + } + + } else { - sender.sendMessage( "BlockEvent was not found" ); - // BlockEvent not found. Recheck the blockEven row number. + sender.sendMessage( "BlockEvent was not found" ); + // BlockEvent not found. Recheck the blockEven row number. } - // Redisplay the event list: - // blockEventList( sender, mineName ); sender.sendMessage( "BlockEvent was not completed correctly" ); } @@ -4958,12 +4566,6 @@ public void blockEventBlockRemove(CommandSender sender, "add the block filter to. If not provided, or value of 0, then " + "this command will display a list of all current blockEvents for " + "this mine.") Integer rowBlockEvent, - - // search is no longer needed nor is the wildcard join for blockName: -// @Arg(name = "search", description = "Optional keyword 'search' to search " + -// "based upon value of blockName. [search, none, ]", -// def = "") String search, -// @Wildcard(join=true) @Arg(name = "rowBlockName", description = "Name of block to add, or " + "if ommitted, then it will show a list of all of the blocks that " + "are available within the selected mine.", @@ -4978,7 +4580,6 @@ public void blockEventBlockRemove(CommandSender sender, PrisonMines pMines = PrisonMines.getInstance(); -// MineManager mMan = pMines.getMineManager(); Mine m = pMines.getMine(mineName); @@ -5001,28 +4602,28 @@ public void blockEventBlockRemove(CommandSender sender, // try to "suggest" reading this command: // mines blockEvent block add [row] [search} [block] - FancyMessage msgRemoveBlock = new FancyMessage( String.format( - "&7%s [rowBlockEvent] [rowBlockName]", - commandRoot ) ) - .suggest( commandRoot + " [rowBlockEvent] [rowBlockName]" ) - .tooltip("Remove a block from a blockEvent - Click to Remove"); - - RowComponent rowFancy = new RowComponent(); - rowFancy.addFancy( msgRemoveBlock ); - display.addComponent( rowFancy ); + FancyMessage msgRemoveBlock = new FancyMessage( String.format( + "&7%s [rowBlockEvent] [rowBlockName]", + commandRoot ) ) + .suggest( commandRoot + " [rowBlockEvent] [rowBlockName]" ) + .tooltip("Remove a block from a blockEvent - Click to Remove"); + + RowComponent rowFancy = new RowComponent(); + rowFancy.addFancy( msgRemoveBlock ); + display.addComponent( rowFancy ); display.send( sender ); - return; + return; } if ( rowBlockEvent > m.getBlockEvents().size() ) { - sender.sendMessage( - String.format("&7Please provide a valid row number no greater than &b%d&7. " + - "Was rowBlockEvent=[&b%d&7]", - m.getBlockEvents().size(), (rowBlockEvent == null ? "null" : rowBlockEvent) )); - return; + sender.sendMessage( + String.format("&7Please provide a valid row number no greater than &b%d&7. " + + "Was rowBlockEvent=[&b%d&7]", + m.getBlockEvents().size(), (rowBlockEvent == null ? "null" : rowBlockEvent) )); + return; } @@ -5032,115 +4633,70 @@ public void blockEventBlockRemove(CommandSender sender, if ( blockEvent != null ) { - if ( rowBlockName == null || rowBlockName == 0 || - rowBlockName > m.getBlockEvents().size() ) { - - String commandBlockEvent = String.format( "" + - "%s %d ", commandRoot, rowBlockEvent ); - - ChatDisplay display = new ChatDisplay("Remove a block from a BlockEvent for " + m.getTag() ); - display.addText("&8Select a block filter from this mine by using the block's row number:"); - display.addText("&8 " + commandBlockEvent + " [rowBlockName]"); - -// DecimalFormat dFmt = Prison.get().getDecimalFormat("0.00000"); - - // Display a list of blocks for the mine: - int blockRow = 0; - - - for ( PrisonBlock block : blockEvent.getPrisonBlocks() ) - { - - RowComponent rowB = new RowComponent(); - - rowB.addTextComponent( " &3Row: &d%d ", ++blockRow ); - - String message = String.format( "&7%s", - block.getBlockName() ); -// String message = String.format( "&7%s %s", -// block.getBlockName(), dFmt.format( block.getChance() ) ); - - String command = String.format( "%s %d", commandBlockEvent, blockRow ); - - FancyMessage msgAddBlock = new FancyMessage( message ) - .suggest( command ) - .tooltip("Remove a selected block from a blockEvent - Click to Remove"); - - rowB.addFancy( msgAddBlock ); - - display.addComponent( rowB ); - } - - display.send( sender ); - return; - } - - - if ( blockEvent.removePrisonBlock( rowBlockName ) ) { - - pMines.getMineManager().saveMine( m ); - - sender.sendMessage( "Block has been removed from the BlockEvent" ); - - return; - } + if ( rowBlockName == null || rowBlockName == 0 || + rowBlockName > m.getBlockEvents().size() ) { + + String commandBlockEvent = String.format( "" + + "%s %d ", commandRoot, rowBlockEvent ); + + ChatDisplay display = new ChatDisplay("Remove a block from a BlockEvent for " + m.getTag() ); + display.addText("&8Select a block filter from this mine by using the block's row number:"); + display.addText("&8 " + commandBlockEvent + " [rowBlockName]"); + + + // Display a list of blocks for the mine: + int blockRow = 0; + + + for ( PrisonBlock block : blockEvent.getPrisonBlocks() ) + { + + RowComponent rowB = new RowComponent(); + + rowB.addTextComponent( " &3Row: &d%d ", ++blockRow ); + + String message = String.format( "&7%s", + block.getBlockName() ); + + String command = String.format( "%s %d", commandBlockEvent, blockRow ); + + FancyMessage msgAddBlock = new FancyMessage( message ) + .suggest( command ) + .tooltip("Remove a selected block from a blockEvent - Click to Remove"); + + rowB.addFancy( msgAddBlock ); + + display.addComponent( rowB ); + } + + display.send( sender ); + return; + } + + + if ( blockEvent.removePrisonBlock( rowBlockName ) ) { + + pMines.getMineManager().saveMine( m ); + + sender.sendMessage( "Block has been removed from the BlockEvent" ); + + return; + } -// PrisonBlockTypes prisonBlockTypes = Prison.get().getPlatform().getPrisonBlockTypes(); -// PrisonBlock block = prisonBlockTypes.getBlockTypesByName( blockName ); - } else { - sender.sendMessage( "BlockEvent was not found" ); - // BlockEvent not found. Recheck the blockEven row number. - - return; + sender.sendMessage( "BlockEvent was not found" ); + // BlockEvent not found. Recheck the blockEven row number. + + return; } - - // Redisplay the event list: - // blockEventList( sender, mineName ); - sender.sendMessage( "BlockEvent was not completed correctly" ); } -// private String extractSearchValue( String page, String blockName ) { -// String results = blockName; -// if ( blockName.toLowerCase().startsWith( page.toLowerCase() ) ) { -// results = blockName.substring( page.length() ).trim(); -// } -// -// return results; -// } - -// private String extractPage( String blockName ) { -// String page = "1"; -// -// if ( blockName != null && blockName.toLowerCase().startsWith( "all " ) ) { -// page = "all"; -// } -// else if ( blockName!= null && blockName.contains( " " ) ) { -// -// try { -// String pageStr = blockName.substring( 0, blockName.indexOf( " " ) ); -// -// int pg = Integer.parseInt( pageStr ); -// -// page = Integer.toString( pg ); -// } -// catch ( NumberFormatException e ) { -// } -// } -// -// return page; -// } - - - - - @Command(identifier = "mines command list", description = "Lists the commands for a mine.", @@ -5148,10 +4704,6 @@ public void blockEventBlockRemove(CommandSender sender, public void commandList(CommandSender sender, @Arg(name = "mineName") String mineName) { -// if ( 1 < 2 ) { -// sender.sendMessage( "&cThis command is disabled&7. It will be enabled in the near future." ); -// return; -// } if (!performCheckMineExists(sender, mineName)) { return; @@ -5161,7 +4713,6 @@ public void commandList(CommandSender sender, setLastMineReferenced(mineName); PrisonMines pMines = PrisonMines.getInstance(); -// MineManager mMan = pMines.getMineManager(); Mine m = pMines.getMine(mineName); if (m.getResetCommands() == null || m.getResetCommands().size() == 0) { @@ -5175,40 +4726,40 @@ public void commandList(CommandSender sender, display.send(sender); } -private ChatDisplay minesCommandList( Mine m ) -{ - ChatDisplay display = new ChatDisplay("Mine Reset Commands for Mine " + m.getTag()); - display.addText("&8Click a command to remove it."); - BulletedListComponent.BulletedListBuilder builder = - new BulletedListComponent.BulletedListBuilder(); - - int rowNumber = 1; - for (String command : m.getResetCommands()) { - - - RowComponent row = new RowComponent(); - - row.addTextComponent( " &3Row: &d%d ", rowNumber++ ); - - FancyMessage msg = new FancyMessage( "&a'&7" + command + "&a'" ); - row.addFancy( msg ); - - FancyMessage msgRemove = new FancyMessage( " &4Remove&3" ) - .suggest("/mines command remove " + m.getName() + " " + rowNumber ) - .tooltip("Click to Remove this Mine Command"); - row.addFancy( msgRemove ); - - builder.add( row ); - + private ChatDisplay minesCommandList( Mine m ) + { + ChatDisplay display = new ChatDisplay("Mine Reset Commands for Mine " + m.getTag()); + display.addText("&8Click a command to remove it."); + BulletedListComponent.BulletedListBuilder builder = + new BulletedListComponent.BulletedListBuilder(); + + int rowNumber = 1; + for (String command : m.getResetCommands()) { + + + RowComponent row = new RowComponent(); + + row.addTextComponent( " &3Row: &d%d ", rowNumber++ ); + + FancyMessage msg = new FancyMessage( "&a'&7" + command + "&a'" ); + row.addFancy( msg ); + + FancyMessage msgRemove = new FancyMessage( " &4Remove&3" ) + .suggest("/mines command remove " + m.getName() + " " + rowNumber ) + .tooltip("Click to Remove this Mine Command"); + row.addFancy( msgRemove ); + + builder.add( row ); + + } + + display.addComponent(builder.build()); + display.addComponent(new FancyMessageComponent( + new FancyMessage("&7[&a+&7] Add").suggest("/mines command add " + m.getName() + " /") + .tooltip("&7Add a new command."))); + return display; } - - display.addComponent(builder.build()); - display.addComponent(new FancyMessageComponent( - new FancyMessage("&7[&a+&7] Add").suggest("/mines command add " + m.getName() + " /") - .tooltip("&7Add a new command."))); - return display; -} - + @Command(identifier = "mines command remove", description = "Removes a command from a mine.", onlyPlayers = false, permissions = "mines.set") @@ -5220,11 +4771,11 @@ public void commandRemove(CommandSender sender, if ( row == null || row <= 0 ) { - sender.sendMessage( - String.format("&7Please provide a valid row number greater than zero. " + - "Was row=[&b%d&7]", - (row == null ? "null" : row) )); - return; + sender.sendMessage( + String.format("&7Please provide a valid row number greater than zero. " + + "Was row=[&b%d&7]", + (row == null ? "null" : row) )); + return; } if (!performCheckMineExists(sender, mineName)) { @@ -5234,14 +4785,8 @@ public void commandRemove(CommandSender sender, setLastMineReferenced(mineName); PrisonMines pMines = PrisonMines.getInstance(); -// MineManager mMan = pMines.getMineManager(); Mine m = pMines.getMine(mineName); -// if ( !m.isEnabled() ) { -// sender.sendMessage( "&cMine is disabled&7. Use &a/mines info &7for possible cause." ); -// return; -// } - if (m.getResetCommands() == null || m.getResetCommands().size() == 0) { Output.get().sendInfo(sender, "The mine '%s' contains no commands.", m.getTag()); return; @@ -5249,15 +4794,15 @@ public void commandRemove(CommandSender sender, if (m.getResetCommands() == null) { - m.setResetCommands( new ArrayList<>() ); + m.setResetCommands( new ArrayList<>() ); } if ( row > m.getResetCommands().size() ) { - sender.sendMessage( - String.format("&7Please provide a valid row number no greater than &b%d&7. " + - "Was row=[&b%d&7]", - m.getResetCommands().size(), (row == null ? "null" : row) )); - return; + sender.sendMessage( + String.format("&7Please provide a valid row number no greater than &b%d&7. " + + "Was row=[&b%d&7]", + m.getResetCommands().size(), (row == null ? "null" : row) )); + return; } @@ -5288,22 +4833,22 @@ public void commandAdd(CommandSender sender, if ( mineName != null && "placeholders".equalsIgnoreCase( mineName ) ) { - String placeholders = - - PrisonCommandTaskData.CustomPlaceholders.listPlaceholders( - PrisonCommandTaskData.CommandEnvironment.all_commands ) + " " + - - PrisonCommandTaskData.CustomPlaceholders.listPlaceholders( - PrisonCommandTaskData.CommandEnvironment.mine_commands ); - - String message = String.format( "Valid Placeholders that can be used with mine commands: [%s]", - placeholders ); - - sender.sendMessage( message ); - return; - } - - if (command.startsWith("/")) { + String placeholders = + + PrisonCommandTaskData.CustomPlaceholders.listPlaceholders( + PrisonCommandTaskData.CommandEnvironment.all_commands ) + " " + + + PrisonCommandTaskData.CustomPlaceholders.listPlaceholders( + PrisonCommandTaskData.CommandEnvironment.mine_commands ); + + String message = String.format( "Valid Placeholders that can be used with mine commands: [%s]", + placeholders ); + + sender.sendMessage( message ); + return; + } + + if (command.startsWith("/")) { command = command.replaceFirst("/", ""); } @@ -5312,22 +4857,21 @@ public void commandAdd(CommandSender sender, } if ( state == null || !state.equalsIgnoreCase( "before" ) && !state.equalsIgnoreCase( "after" )) { - sender.sendMessage( - String.format("&7Please provide a valid state: &bbefore&7 or &bafter&7. Was state=[&b%s&7]", - state )); - return; + sender.sendMessage( + String.format("&7Please provide a valid state: &bbefore&7 or &bafter&7. Was state=[&b%s&7]", + state )); + return; } setLastMineReferenced(mineName); PrisonMines pMines = PrisonMines.getInstance(); -// MineManager mMan = pMines.getMineManager(); Mine m = pMines.getMine(mineName); if ( command == null || command.trim().length() == 0 ) { - sender.sendMessage( - String.format( "&7Please provide a valid command: command=[%s]", command) ); - return; + sender.sendMessage( + String.format( "&7Please provide a valid command: command=[%s]", command) ); + return; } String newComand = state + ": " + command; @@ -5672,53 +5216,53 @@ public void worldGuardRegions( CommandSender sender, String wbSetting, String world = null; if ( mine != null ) { - world = mine.getWorldName(); + world = mine.getWorldName(); } else if ( mine == null && !"*global*".equalsIgnoreCase(mineName) ) { - sender.sendMessage( "A valid mine name is required. Try again.");; - return; + sender.sendMessage( "A valid mine name is required. Try again.");; + return; } // First check to make sure the playerName does not contain the world parameter, // but only if world was not set from the mine name. if ( world == null && playerName != null ) { - Optional wOpt = Prison.get().getPlatform().getWorld( playerName ); - if ( wOpt.isPresent() ) { - // Player name is a world name, so use it: - world = playerName; - playerName = ""; - } + Optional wOpt = Prison.get().getPlatform().getWorld( playerName ); + if ( wOpt.isPresent() ) { + // Player name is a world name, so use it: + world = playerName; + playerName = ""; + } } if ( world == null ) { - // If a world name is supplied, then it should be what's left after you remove any possible - // values for 'view' or 'run'. - String worldName = options.replace("view", "").replace("run", "").trim(); - - if ( worldName != null && worldName.length() > 0 ) { - Optional wOpt = Prison.get().getPlatform().getWorld( worldName ); - if ( wOpt.isPresent() ) { - // Player name is a world name, so use it: - world = worldName; - - // Do not change options... it's not used anymore: - } - } + // If a world name is supplied, then it should be what's left after you remove any possible + // values for 'view' or 'run'. + String worldName = options.replace("view", "").replace("run", "").trim(); + + if ( worldName != null && worldName.length() > 0 ) { + Optional wOpt = Prison.get().getPlatform().getWorld( worldName ); + if ( wOpt.isPresent() ) { + // Player name is a world name, so use it: + world = worldName; + + // Do not change options... it's not used anymore: + } + } } // Check to see if run has been specified: if ( playerName.equalsIgnoreCase("run") ) { - run = true; - playerName = null; + run = true; + playerName = null; } else if ( playerName.equalsIgnoreCase("view") ) { - run = false; - playerName = null; + run = false; + playerName = null; } else if ( options != null ) { - String[] opts = options.split( " " ); - String newOpt = ""; - - for (String opt : opts) { + String[] opts = options.split( " " ); + String newOpt = ""; + + for (String opt : opts) { if ( opt.equalsIgnoreCase( "run" ) ) { run = true; } @@ -5727,180 +5271,136 @@ else if ( opt.equalsIgnoreCase( "view" ) ) { } else if ( world == null ) { Optional wOpt = Prison.get().getPlatform().getWorld( opt ); - if ( wOpt.isPresent() ) { - // Set the world name: - world = opt; - } + if ( wOpt.isPresent() ) { + // Set the world name: + world = opt; + } } else { newOpt += opt + " "; } } - - options = newOpt.trim(); + + options = newOpt.trim(); } if ( sender.isPlayer() ) { - player = sender.getPlatformPlayer(); - } - else { - - // Get a Bukkit online player, which is needed to run the WorldGuard commands through: - Prison.get().getPlatform().getPlayer(playerName); + player = sender.getPlatformPlayer(); + } + else { -// player = getPlayerByName( playerName ); -// player = getPlayer( sender, playerName ); - } - - -// if ( playerName.equalsIgnoreCase("run") ) { -// -// if ( sender.isPlayer() ) { -// run = true; -// player = sender.getPlatformPlayer(); -// } -// else { -// sender.sendMessage( "A valid player name must be provided if this command is ran from the console."); -// } -// } -// else if ( playerName.equalsIgnoreCase( "view" ) || options.toLowerCase().contains( "view" ) ) { -// run = false; -// } -// else { -// player = getPlayer( sender, playerName ); -// -// if ( player == null ) { -// } -// -// if ( options.toLowerCase().contains( "run" ) ) { -// run = true; -// } -// } - -// if ( options != null ) { -// -// // If a world name is supplied, then it should be what's left after you remove any possible -// // values for 'view' or 'run'. -// String worldName = options.replace("view", "").replace("run", "").trim(); -// -// if ( worldName != null && worldName.length() > 0 ) { -// Optional wOpt = Prison.get().getPlatform().getWorld( worldName ); -// if ( wOpt.isPresent() ) { -// // Player name is a world name, so use it: -// world = worldName; -// -// // Do not change options... it's not used anymore: -// } -// } -// } - - - String mode = run ? "Running" : "Viewing"; - ChatDisplay display = new ChatDisplay("WorldGuard Region Commands - " + mode); - display.addText("'/mines worldGuard regions " + command +"'"); - display.addText(""); - - if ( mine != null ) { - display.addText( "&3Mine: &7%s", mine.getTag() ); - - } - else if ( "*global*".equalsIgnoreCase(mineName) ) { - display.addText( "&3Global: &7__global__"); - } - - if ( run && player != null ) { - player.sendMessage( String.format( - "&cTeleporting you to mine &3%s &bto run WorldGuard Region " - + "commands on your behalf.", - mine.getTag()) ); - teleportPlayer(player, mine, "spawn"); - } - - String worldName = mine != null && !mine.isVirtual() ? - mine.getWorldName() : - world != null ? world : - player != null ? player.getLocation().getWorld().getName() : - "world-not-set"; - - display.addText( "&3World: &7%s", worldName ); - - display.addText(""); + // Get a Bukkit online player, which is needed to run the WorldGuard commands through: + Prison.get().getPlatform().getPlayer(playerName); + + } + + + String mode = run ? "Running" : "Viewing"; + ChatDisplay display = new ChatDisplay("WorldGuard Region Commands - " + mode); + display.addText("'/mines worldGuard regions " + command +"'"); + display.addText(""); + + if ( mine != null ) { + display.addText( "&3Mine: &7%s", mine.getTag() ); + + } + else if ( "*global*".equalsIgnoreCase(mineName) ) { + display.addText( "&3Global: &7__global__"); + } + + if ( run && player != null ) { + player.sendMessage( String.format( + "&cTeleporting you to mine &3%s &bto run WorldGuard Region " + + "commands on your behalf.", + mine.getTag()) ); + teleportPlayer(player, mine, "spawn"); + } + + String worldName = mine != null && !mine.isVirtual() ? + mine.getWorldName() : + world != null ? world : + player != null ? player.getLocation().getWorld().getName() : + "world-not-set"; + + display.addText( "&3World: &7%s", worldName ); + + display.addText(""); List wbCommands = Prison.get().getPlatform().getConfigStringArray( wbSetting ); if ( wbCommands.size() > 0 ) { - List cmds = new ArrayList<>(); - - - String worldPlaceholder = worldName.equals("world-not-set") ? "" : - !sender.isPlayer() ? "-w " + worldName : - ""; - - - String regionMineName = Prison.get().getPlatform().getConfigString( - "prison-mines.world-guard.region-mine.region-mine-name", "prison_mine_{mine}"); - String regionGroupPerms = Prison.get().getPlatform().getConfigString( - "prison-mines.world-guard.region-mine.region-group-permission", "g:prison.mines.{mine}"); - - regionMineName = regionMineName.replace("{mine}", mine == null ? "(no-mine)" : mine.getName() ); - regionGroupPerms = regionGroupPerms.replace("{mine}", mine == null ? "(no-mine)" : mine.getName() ); - - String minePos1 = mine == null ? "(no-mine)" : - mine.isVirtual() ? "(virtual-mine-no-coordinates)" : - mine.getBounds().getxBlockMin() + "," + - mine.getBounds().getyBlockMin() + "," + - mine.getBounds().getzBlockMin(); - String minePos2 = mine == null ? "(no-mine)" : - mine.isVirtual() ? "(virtual-mine-no-coordinates)" : - mine.getBounds().getxBlockMax() + "," + - mine.getBounds().getyBlockMax() + "," + - mine.getBounds().getzBlockMax(); - - for (String cmd : wbCommands) { - - String msg = cmd.replace("{mine-pos1}", minePos1) - .replace("{mine-pos2}", minePos2) - .replace("{region-mine-name}", regionMineName) - .replace("{region-group-permission}", regionGroupPerms) - .replace("{world}", worldPlaceholder); - - if ( msg.startsWith( "/" ) ) { - msg = msg.substring( 1 ); - } - - cmds.add( msg ); - display.addText( "&4 %s", msg ); - - } - - display.send( sender ); - - if ( run ) { - // submit the commands in cmds: - - for (String cmd : cmds) { - - sender.sendMessage( "&3Running: &7" + cmd ); - if ( player != null ) { - - Prison.get().getPlatform().dispatchCommand(player, cmd); - } - else { - // Player was not defined, so try to run everything as console: - Prison.get().getPlatform().dispatchCommand( cmd ); - } - } - } - + List cmds = new ArrayList<>(); + + + String worldPlaceholder = worldName.equals("world-not-set") ? "" : + !sender.isPlayer() ? "-w " + worldName : + ""; + + + String regionMineName = Prison.get().getPlatform().getConfigString( + "prison-mines.world-guard.region-mine.region-mine-name", "prison_mine_{mine}"); + String regionGroupPerms = Prison.get().getPlatform().getConfigString( + "prison-mines.world-guard.region-mine.region-group-permission", "g:prison.mines.{mine}"); + + regionMineName = regionMineName.replace("{mine}", mine == null ? "(no-mine)" : mine.getName() ); + regionGroupPerms = regionGroupPerms.replace("{mine}", mine == null ? "(no-mine)" : mine.getName() ); + + String minePos1 = mine == null ? "(no-mine)" : + mine.isVirtual() ? "(virtual-mine-no-coordinates)" : + mine.getBounds().getxBlockMin() + "," + + mine.getBounds().getyBlockMin() + "," + + mine.getBounds().getzBlockMin(); + String minePos2 = mine == null ? "(no-mine)" : + mine.isVirtual() ? "(virtual-mine-no-coordinates)" : + mine.getBounds().getxBlockMax() + "," + + mine.getBounds().getyBlockMax() + "," + + mine.getBounds().getzBlockMax(); + + for (String cmd : wbCommands) { + + String msg = cmd.replace("{mine-pos1}", minePos1) + .replace("{mine-pos2}", minePos2) + .replace("{region-mine-name}", regionMineName) + .replace("{region-group-permission}", regionGroupPerms) + .replace("{world}", worldPlaceholder); + + if ( msg.startsWith( "/" ) ) { + msg = msg.substring( 1 ); + } + + cmds.add( msg ); + display.addText( "&4 %s", msg ); + + } + + display.send( sender ); + + if ( run ) { + // submit the commands in cmds: + + for (String cmd : cmds) { + + sender.sendMessage( "&3Running: &7" + cmd ); + if ( player != null ) { + + Prison.get().getPlatform().dispatchCommand(player, cmd); + } + else { + // Player was not defined, so try to run everything as console: + Prison.get().getPlatform().dispatchCommand( cmd ); + } + } + } + } else { - sender.sendMessage( - String.format( "Invalid settings: config.yml does not have the proper WorldGuard settings. " + - "[%s]", wbSetting ) ); + sender.sendMessage( + String.format( "Invalid settings: config.yml does not have the proper WorldGuard settings. " + + "[%s]", wbSetting ) ); } } @@ -5918,52 +5418,38 @@ public void minesDumpCommand(CommandSender sender, if ( mine != null ) { - JsonFileIO jfio = new JsonFileIO(); - -// Gson gson = new GsonBuilder().registerTypeAdapter(IsBean.class, new InterfaceAdapter()).create(); - - DecimalFormat dFmt = new DecimalFormat( "####" ); - - int ser = (int) (Math.random() * 9999d); - - String fName = "temp_mines_" + dFmt.format(ser) + ".json"; - - File f = new File( Prison.get().getDataFolder(), fName); - - - try { - -// if ( mine.getBlockStats().size() > 0 ) { -// -// Entry block = mine.getBlockStats().firstEntry(); -// -// String blockJson = jfio.toString(block); -// -// Output.get().logInfo(blockJson); -// -// -// } - - String mineJson = jfio.toString(mine); - + JsonFileIO jfio = new JsonFileIO(); + + + DecimalFormat dFmt = new DecimalFormat( "####" ); + + int ser = (int) (Math.random() * 9999d); + + String fName = "temp_mines_" + dFmt.format(ser) + ".json"; + + File f = new File( Prison.get().getDataFolder(), fName); + + + try { + +// String mineJson = jfio.toString(mine); jfio.saveJsonFile(f, mine ); sender.sendMessage( "Mine dumpped to: " + f.getAbsolutePath() ); } - catch (Exception e) { - + catch (Exception e) { + sender.sendMessage( "Mine dump error: " + e.getMessage() ); e.printStackTrace(); } - + } else { - sender.sendMessage( "A valid mine name is required. Try again.");; - return; + sender.sendMessage( "A valid mine name is required. Try again.");; + return; } - } } diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesImportCommands.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesImportCommands.java index 837d05c40..21756b523 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesImportCommands.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesImportCommands.java @@ -31,30 +31,17 @@ public MinesImportCommands( String cmdGroup ) { super( cmdGroup ); } - - public void importJetsPrisonMines( CommandSender sender, String options ) { - - boolean save = false; - boolean addLiner = false; - - String path = "JetsPrisonMines//mines//"; - - String worldForced = ""; - -// if ( options.contains( "testImport" ) ) { -// testImport = true; -// list = true; -// options = options.replace( "testImport", "" ).trim(); -// } -// -// if ( options.contains( "list" ) ) { -// testImport = false; -// list = true; -// options = options.replace( "list", "" ).trim(); -// } + + boolean save = false; + boolean addLiner = false; + + String path = "JetsPrisonMines//mines//"; + + String worldForced = ""; + if ( options.contains( "save" ) ) { save = true; @@ -158,22 +145,21 @@ else if ( save ) { mines.addAll( pMines.getMines() ); - for ( Mine mine : mines ) - { - if ( !mine.isVirtual() ) { - - for (Edges edge : Edges.values() ) { - - LinerPatterns linerPattern = LinerPatterns.fromString( - mine.getLinerData().getEdge(edge) ); - - boolean force = mine.getLinerData().getForce(edge); - boolean useTracer = false; - - new MineLinerBuilder( mine, edge, linerPattern, force, useTracer ); + for ( Mine mine : mines ) { + if ( !mine.isVirtual() ) { + + for (Edges edge : Edges.values() ) { + + LinerPatterns linerPattern = LinerPatterns.fromString( + mine.getLinerData().getEdge(edge) ); + + boolean force = mine.getLinerData().getForce(edge); + boolean useTracer = false; + + new MineLinerBuilder( mine, edge, linerPattern, force, useTracer ); } - - } + + } } } diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/Mine.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/Mine.java index 3f63fc3b5..995cebcf5 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/Mine.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/Mine.java @@ -86,36 +86,36 @@ public enum MineUnitTestUsage { } public enum MineNotificationMode { - disabled, - disable, - within, - radius, - world, - server, - - displayOptions - ; - - public static MineNotificationMode fromString(String mode) { - return fromString(mode, radius); - } - public static MineNotificationMode fromString(String mode, MineNotificationMode defaultValue) { - MineNotificationMode results = defaultValue; - - if ( mode != null && mode.trim().length() > 0 ) { - for ( MineNotificationMode mnm : values() ) { - if ( mnm.name().equalsIgnoreCase( mode )) { - results = mnm; - } - } - } - - if ( results == disable ) { - results = disabled; - } - - return results; - } + disabled, + disable, + within, + radius, + world, + server, + + displayOptions + ; + + public static MineNotificationMode fromString(String mode) { + return fromString(mode, radius); + } + public static MineNotificationMode fromString(String mode, MineNotificationMode defaultValue) { + MineNotificationMode results = defaultValue; + + if ( mode != null && mode.trim().length() > 0 ) { + for ( MineNotificationMode mnm : values() ) { + if ( mnm.name().equalsIgnoreCase( mode )) { + results = mnm; + } + } + } + + if ( results == disable ) { + results = disabled; + } + + return results; + } } /** @@ -137,12 +137,9 @@ public Mine() { * @param unitTestUsage */ public Mine( MineUnitTestUsage unitTestUsage, String mineName ) { - super(); + super(); setName( mineName ); - - // Kick off the initialize: - //initialize(); } @@ -154,35 +151,35 @@ public Mine( MineUnitTestUsage unitTestUsage, String mineName ) { * @param selection */ public Mine(String name, Selection selection) { - this( name, selection, MineType.primary ); + this( name, selection, MineType.primary ); } public Mine(String name, Selection selection, MineType mineType, boolean logInfo ) { - super(); - - setName(name); - - setMineType( mineType ); - - if ( selection == null ) { - setVirtual( true ); - } - else { - - setBounds(selection.asBounds(), logInfo ); - - setWorldName( getBounds().getMin().getWorld().getName()); - - setEnabled( true ); - } - - // Kick off the initialize: - initialize(); - } - - public Mine(String name, Selection selection, MineType mineType) { - this( name, selection, mineType, true ); - + super(); + + setName(name); + + setMineType( mineType ); + + if ( selection == null ) { + setVirtual( true ); + } + else { + + setBounds(selection.asBounds(), logInfo ); + + setWorldName( getBounds().getMin().getWorld().getName()); + + setEnabled( true ); + } + + // Kick off the initialize: + initialize(); + } + + public Mine(String name, Selection selection, MineType mineType) { + this( name, selection, mineType, true ); + } /** @@ -224,7 +221,7 @@ public Mine(String name, Selection selection, MineType mineType) { * @throws MineException If the mine couldn't be loaded from the document. */ public Mine(Document document) throws MineException { - super(); + super(); loadFromDocument( document ); @@ -243,7 +240,7 @@ public Mine(Document document) throws MineException { */ @Override protected void initialize() { - super.initialize(); + super.initialize(); } @@ -297,13 +294,13 @@ private void loadFromDocument( Document document ) String accessPerm = (String) document.get("accessPermission"); setAccessPermission( (accessPerm == null || accessPerm.trim().isEmpty() ? null : accessPerm) ); - - setTpAccessByRank( document.get("tpAccessByRank") == null ? false : (boolean) document.get("tpAccessByRank") ); - setMineAccessByRank( document.get("mineAccessByRank") == null ? false : (boolean) document.get("mineAccessByRank") ); - - - setVirtual( document.get("isVirtual") == null ? false : (boolean) document.get("isVirtual") ); - + + setTpAccessByRank( document.get("tpAccessByRank") == null ? false : (boolean) document.get("tpAccessByRank") ); + setMineAccessByRank( document.get("mineAccessByRank") == null ? false : (boolean) document.get("mineAccessByRank") ); + + + setVirtual( document.get("isVirtual") == null ? false : (boolean) document.get("isVirtual") ); + Double sortOrder = (Double) document.get( "sortOrder" ); setSortOrder( sortOrder == null ? 0 : sortOrder.intValue() ); @@ -454,10 +451,6 @@ else if ( blockType == ObsoleteBlockType.NETHER_BRICK ) { totalBlockCount += block.getBlockCountTotal(); -// BlockOld block = new BlockOld(blockType, chance, blockCount); -// block.setConstraintMin( constraintMin ); -// block.setConstraintMax( constraintMax ); - getBlocks().add(block); } else { @@ -543,46 +536,6 @@ else if ( validateBlockNames.contains( prisonBlock.getBlockName() ) ) { } - -// String[] split = docBlock.split("-"); -// String blockTypeName = split[0]; -// double chance = split.length > 1 ? Double.parseDouble(split[1]) : 0; -// long blockCount = split.length > 2 ? Long.parseLong(split[2]) : 0; -// int constraintMin = split.length > 3 ? Integer.parseInt(split[3]) : 0; -// int constraintMax = split.length > 4 ? Integer.parseInt(split[4]) : 0; -// int constraintExcludeTopLayers = split.length > 5 ? Integer.parseInt(split[5]) : 0; -// int constraintExcludeBottomLayers = split.length > 6 ? Integer.parseInt(split[6]) : 0; -// -// if ( blockTypeName != null ) { -// // The new way to get the PrisonBlocks: -// // The blocks return are cloned so they have their own instance: -// PrisonBlock prisonBlock = Prison.get().getPlatform().getPrisonBlock( blockTypeName ); -// -// if ( prisonBlock != null && !validateBlockNames.contains( blockTypeName )) { -// prisonBlock.setChance( chance ); -// prisonBlock.setBlockCountTotal( blockCount ); -// prisonBlock.setConstraintMin( constraintMin ); -// prisonBlock.setConstraintMax( constraintMax ); -// prisonBlock.setConstraintExcludeTopLayers( constraintExcludeTopLayers ); -// prisonBlock.setConstraintExcludeBottomLayers( constraintExcludeBottomLayers ); -// -// -// if ( prisonBlock.isLegacyBlock() ) { -// dirty = true; -// } -// addPrisonBlock( prisonBlock ); -// -// validateBlockNames.add( blockTypeName ); -// } -// else if (validateBlockNames.contains( blockTypeName ) ) { -// // Detected and fixed a duplication so mark as dirty so fixed block list is saved: -// dirty = true; -// inconsistancy = true; -// } -// -// } - - } } @@ -626,7 +579,8 @@ else if ( validateBlockNames.contains( prisonBlock.getBlockName() ) ) { dirty = true; } - } + } + Output.get().logInfo( "Notice: Mine: " + getName() + ": Existing prison block model has " + "been converted to the new block model and will be saved." ); } @@ -636,27 +590,23 @@ else if ( validateBlockNames.contains( prisonBlock.getBlockName() ) ) { setResetCommands( commands == null ? new ArrayList<>() : commands ); -// Boolean usePagingOnReset = (Boolean) document.get( "usePagingOnReset" ); -// setUsePagingOnReset( usePagingOnReset == null ? false : usePagingOnReset.booleanValue() ); - - List mineBlockEvents = (List) document.get("mineBlockEvents"); if ( mineBlockEvents != null ) { - for ( String blockEvent : mineBlockEvents ) { - if ( blockEvent != null ) { - - MineBlockEvent bEvent = MineBlockEvent.fromSaveString( blockEvent, this.getName() ); - - if ( bEvent != null ) { - - getBlockEvents().add( bEvent ); - } - else { - Output.get().logInfo( "Notice: Mine: " + getName() + ": Error trying to parse a blockEvent. " - + "BlockEvent is lost: raw BlockEvent= [" + blockEvent + "]" ); - } - } - } + for ( String blockEvent : mineBlockEvents ) { + if ( blockEvent != null ) { + + MineBlockEvent bEvent = MineBlockEvent.fromSaveString( blockEvent, this.getName() ); + + if ( bEvent != null ) { + + getBlockEvents().add( bEvent ); + } + else { + Output.get().logInfo( "Notice: Mine: " + getName() + ": Error trying to parse a blockEvent. " + + "BlockEvent is lost: raw BlockEvent= [" + blockEvent + "]" ); + } + } + } } @@ -669,26 +619,26 @@ else if ( validateBlockNames.contains( prisonBlock.getBlockName() ) ) { if ( dirty ) { - // Resave the mine data since an update to the mine format was detected and - // needs to be saved. Otherwise the bad data will always need to be converted - // every time the mine is loaded which may lead to other issues. - - // This is enabled since the original is not modified. - - // If dirty, then make a backup since these are automatic changes: - PrisonMines.getInstance().getMineManager().backupMine( this ); - - PrisonMines.getInstance().getMineManager().saveMine( this ); - - if ( inconsistancy ) { - - Output.get().logInfo( "Notice: Mine: " + getName() + ": During the loading of this mine an " + - "inconsistancy was detected and was fixed then saved." ); - } - else { - Output.get().logInfo( "Notice: Mine: " + getName() + ": Updated mine data was successfully saved." ); - - } + // Resave the mine data since an update to the mine format was detected and + // needs to be saved. Otherwise the bad data will always need to be converted + // every time the mine is loaded which may lead to other issues. + + // This is enabled since the original is not modified. + + // If dirty, then make a backup since these are automatic changes: + PrisonMines.getInstance().getMineManager().backupMine( this ); + + PrisonMines.getInstance().getMineManager().saveMine( this ); + + if ( inconsistancy ) { + + Output.get().logInfo( "Notice: Mine: " + getName() + ": During the loading of this mine an " + + "inconsistancy was detected and was fixed then saved." ); + } + else { + Output.get().logInfo( "Notice: Mine: " + getName() + ": Updated mine data was successfully saved." ); + + } } } @@ -699,11 +649,12 @@ public Document toDocument() { // If world name is not set, try to get it from the bounds: String worldName = getWorldName(); if ( (worldName == null || worldName.trim().length() == 0 || - "Virtually-Undefined".equalsIgnoreCase( worldName )) && - getBounds() != null && getBounds().getMin() != null && - getBounds().getMin().getWorld() != null ) { - worldName = getBounds().getMin().getWorld().getName(); - setWorldName( worldName ); + "Virtually-Undefined".equalsIgnoreCase( worldName )) && + getBounds() != null && getBounds().getMin() != null && + getBounds().getMin().getWorld() != null ) { + + worldName = getBounds().getMin().getWorld().getName(); + setWorldName( worldName ); } ret.put("world", worldName ); ret.put("name", getName()); @@ -763,15 +714,15 @@ public Document toDocument() { // originally. In a future release, these may be purged. List blockStrings = new ArrayList<>(); for (BlockOld block : getBlocks()) { - if ( !validateBlockNames.contains( block.getType().name() )) { - - blockStrings.add( block.toSaveFileFormat() ); - -// // Use the BlockType.name() to save the block type to the file: -// blockStrings.add(block.getType().name() + "-" + block.getChance()); -// blockStrings.add(block.getType().getId() + "-" + block.getChance()); - validateBlockNames.add( block.getType().name() ); - } + if ( !validateBlockNames.contains( block.getType().name() )) { + + blockStrings.add( block.toSaveFileFormat() ); + + // // Use the BlockType.name() to save the block type to the file: + // blockStrings.add(block.getType().name() + "-" + block.getChance()); + // blockStrings.add(block.getType().getId() + "-" + block.getChance()); + validateBlockNames.add( block.getType().name() ); + } } ret.put("blocks", blockStrings); @@ -781,13 +732,13 @@ public Document toDocument() { List prisonBlockStrings = new ArrayList<>(); for (PrisonBlock pBlock : getPrisonBlocks() ) { - if ( !validateBlockNames.contains( pBlock.getBlockName()) ) { - - prisonBlockStrings.add( pBlock.toSaveFileFormat() ); - -// prisonBlockStrings.add(pBlock.getBlockNameFormal() + "-" + pBlock.getChance()); - validateBlockNames.add( pBlock.getBlockNameFormal() ); - } + if ( !validateBlockNames.contains( pBlock.getBlockName()) ) { + + prisonBlockStrings.add( pBlock.toSaveFileFormat() ); + + // prisonBlockStrings.add(pBlock.getBlockNameFormal() + "-" + pBlock.getChance()); + validateBlockNames.add( pBlock.getBlockNameFormal() ); + } } ret.put("prisonBlocks", prisonBlockStrings); @@ -795,9 +746,6 @@ public Document toDocument() { ret.put("commands", getResetCommands()); -// ret.put( "usePagingOnReset", isUsePagingOnReset() ); - - if ( getRank() != null ) { String rank = getRank().getModuleElementType() + "," + getRank().getName() + "," + getRank().getId() + "," + getRank().getTag(); @@ -822,7 +770,7 @@ public Document toDocument() { @Override public String toString() { - return getName() + " " + getTotalBlocksMined(); + return getName() + " " + getTotalBlocksMined(); } /** @@ -839,40 +787,36 @@ public String toString() { * @return */ private Location getLocation(Document doc, World world, String x, String y, String z) { - Location results = null; - -// if ( world != null ) { -// -// -// } - Object xD = doc.get(x); - Object yD = doc.get(y); - Object zD = doc.get(z); - - if ( xD != null && yD != null && zD != null ) { - - results = new Location(world, (double) xD, (double) yD, (double) zD ); - } - - return results; + Location results = null; + + Object xD = doc.get(x); + Object yD = doc.get(y); + Object zD = doc.get(z); + + if ( xD != null && yD != null && zD != null ) { + + results = new Location(world, (double) xD, (double) yD, (double) zD ); + } + + return results; } private Location getLocation(Document doc, World world, String x, String y, String z, String pitch, String yaw) { - Location loc = getLocation(doc, world, x, y, z); - - Object pitchD = doc.get(pitch); - Object yawD = doc.get(yaw); - - if ( pitchD != null ) { - - loc.setPitch( ((Double) pitchD ).floatValue() ); - } - - if ( yawD != null ) { - - loc.setYaw( ((Double) yawD ).floatValue() ); - } - return loc; + Location loc = getLocation(doc, world, x, y, z); + + Object pitchD = doc.get(pitch); + Object yawD = doc.get(yaw); + + if ( pitchD != null ) { + + loc.setPitch( ((Double) pitchD ).floatValue() ); + } + + if ( yawD != null ) { + + loc.setYaw( ((Double) yawD ).floatValue() ); + } + return loc; } diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineData.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineData.java index a294e429f..bde6b8f67 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineData.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineData.java @@ -135,7 +135,6 @@ public abstract class MineData private List resetCommands; -// private boolean usePagingOnReset = false; private transient ModuleElement rank; /** @@ -208,7 +207,6 @@ public MineData() { this.resetCommands = new ArrayList<>(); -// this.usePagingOnReset = false; this.rank = null; this.rankString = null; @@ -260,29 +258,7 @@ public void reconnectObjects() { getSpawn().reconnectObects(); } - // Note: getWorld() is actually a helper to get a world object out of - // getBounds() and setWorld() sets the world on both getBounds() and - // getSpawn(). - - - // The following two collections do not use World objects so they do not - // need to be reconnected: -// getPrisonBlocks(); -// getBlockStats(); - } - -// if ( getWorld() == null ) { -// String worldName = getWorldName(); -// -// Optional worldOpt = Prison.get().getPlatform().getWorld(worldName); -// -// if ( worldOpt.isPresent() ) { -// World world = worldOpt.get(); -// -// setWorld( world ); -// } -// } } @@ -327,17 +303,17 @@ public String getName() { } public String getTag() { - return ( tag == null || tag.trim().isEmpty() ? getName() : tag ); + return ( tag == null || tag.trim().isEmpty() ? getName() : tag ); } public void setTag( String tag ) { - this.tag = tag; + this.tag = tag; } public int getSortOrder() { - return sortOrder; + return sortOrder; } public void setSortOrder( int sortOrder ) { - this.sortOrder = sortOrder; + this.sortOrder = sortOrder; } @@ -347,10 +323,10 @@ public void setSortOrder( int sortOrder ) { * set. An id is forced by Ranks and Ladders. */ public int getId() { - return -1; + return -1; } public void setId( int idIsIgnored ) { - // ignore + // ignore } /** @@ -392,7 +368,6 @@ public void setWorldName( String worldName ) { */ public Optional getWorld() { return Optional.ofNullable( isVirtual() ? null : getBounds().getMin().getWorld() ); -// return Prison.get().getPlatform().getWorld(worldName); } /** @@ -417,7 +392,7 @@ public void setWorld( World world ) { } } - setEnabled( world != null ); + setEnabled( world != null ); } public Bounds getBounds() { @@ -425,7 +400,7 @@ public Bounds getBounds() { } public void setBounds(Bounds bounds ) { - setBounds( bounds, true ); + setBounds( bounds, true ); } /** @@ -450,51 +425,51 @@ public void setBounds(Bounds bounds ) { * @param bounds the new boundaries */ public void setBounds(Bounds bounds, boolean logInfo ) { - this.bounds = bounds; - - // if Bounds is null, then clear out the world fields and set mine to virtual and disable the mine: - if ( bounds == null ) { - - setSpawn( null ); - - setWorld( null ); - setWorldName( null ); - setVirtual( true ); - setEnabled( false ); - } - - else if ( isVirtual() || !getWorld().isPresent() || - getWorldName() == null || getWorldName().trim().length() == 0 || - getWorldName().equalsIgnoreCase( "Virtually-Undefined" ) ) { - - World world = bounds.getMin().getWorld(); - - if ( world != null ) { - - setWorld( world ); - setWorldName( world.getName() ); - setVirtual( false ); - setEnabled( true ); - - if ( logInfo ) { - Output.get().logInfo( "&7Mine " + getTag() + "&7: world has been set and is now enabled." ); - } - - } - else { - setEnabled( false ); - Output.get().logWarn( - String.format( "&cCould not activate mine &7%s &cbecause the " + - "world object cannot be aquired. Bounds failed be set correctly " + - "and this mine is &ddisabled&c.", getName()) ); - } - } - - // The world name MUST NEVER be changed. If world is null then it will screw - // up the original location of when the mine was created. World name is set - // in the document loader under Mine.loadFromDocument as the first field - // that is set when restoring from the file. - //this.worldName = bounds.getMin().getWorld().getName(); + this.bounds = bounds; + + // if Bounds is null, then clear out the world fields and set mine to virtual and disable the mine: + if ( bounds == null ) { + + setSpawn( null ); + + setWorld( null ); + setWorldName( null ); + setVirtual( true ); + setEnabled( false ); + } + + else if ( isVirtual() || !getWorld().isPresent() || + getWorldName() == null || getWorldName().trim().length() == 0 || + getWorldName().equalsIgnoreCase( "Virtually-Undefined" ) ) { + + World world = bounds.getMin().getWorld(); + + if ( world != null ) { + + setWorld( world ); + setWorldName( world.getName() ); + setVirtual( false ); + setEnabled( true ); + + if ( logInfo ) { + Output.get().logInfo( "&7Mine " + getTag() + "&7: world has been set and is now enabled." ); + } + + } + else { + setEnabled( false ); + Output.get().logWarn( + String.format( "&cCould not activate mine &7%s &cbecause the " + + "world object cannot be aquired. Bounds failed be set correctly " + + "and this mine is &ddisabled&c.", getName()) ); + } + } + + // The world name MUST NEVER be changed. If world is null then it will screw + // up the original location of when the mine was created. World name is set + // in the document loader under Mine.loadFromDocument as the first field + // that is set when restoring from the file. + //this.worldName = bounds.getMin().getWorld().getName(); } @@ -553,157 +528,34 @@ public boolean removePrisonBlock( PrisonBlock prisonBlock ) { return results; } - // Obsolete... the old block model: -// /** -// * This is only used in an obsolete conversion utility. -// * -// * Adding the newer PrisonBlocks for compatibility. -// * -// * Sets the blocks for this mine -// * -// * @param blockMap the new blockmap with the {@link BlockType} as the key, and the chance of the -// * block appearing as the value. -// */ -// public void setBlocks(HashMap blockMap) { -// this.blocks.clear(); -// this.prisonBlocks.clear(); -// -// for (Map.Entry entry : blockMap.entrySet()) { -// blocks.add(new BlockOld(entry.getKey(), entry.getValue(), 0)); -// -// PrisonBlock prisonBlock = Prison.get().getPlatform().getPrisonBlock( entry.getKey().name() ); -// if ( prisonBlock != null ) { -// prisonBlock.setChance( entry.getValue() ); -// prisonBlocks.add( prisonBlock ); -// } -// } -// } public PrisonBlock getPrisonBlock(String blockName ) { - PrisonBlock results = null; - - if ( blockName != null && !blockName.trim().isEmpty() ) { - for ( PrisonBlock b : getPrisonBlocks() ) { - if ( b.getBlockName().equalsIgnoreCase( blockName ) ) { - results = b; - break; - } - } - } - - return results; + PrisonBlock results = null; + + if ( blockName != null && !blockName.trim().isEmpty() ) { + for ( PrisonBlock b : getPrisonBlocks() ) { + if ( b.getBlockName().equalsIgnoreCase( blockName ) ) { + results = b; + break; + } + } + } + + return results; } -// public BlockOld getBlockOld(String blockName ) { -// BlockOld results = null; -// -// if ( blockName != null && !blockName.trim().isEmpty() ) { -// for ( BlockOld b : getBlocks() ) { -// if ( b.getBlockName().equalsIgnoreCase( blockName ) ) { -// results = b; -// break; -// } -// } -// } -// -// return results; -// } public boolean hasBlock( String blockName ) { - boolean results = false; - - if ( blockName != null && !blockName.trim().isEmpty() ) { - - results = getPrisonBlock( blockName ) != null; - } + boolean results = false; + + if ( blockName != null && !blockName.trim().isEmpty() ) { + + results = getPrisonBlock( blockName ) != null; + } return results; } -// public boolean incrementBlockMiningCount( Block block ) { -// boolean results = false; -// -// String blockName = block.getPrisonBlock().getBlockName().toLowerCase(); -// -// // Need to always get the target block so it can be marked as counted: -// MineTargetPrisonBlock targetPrisonBlock = getTargetPrisonBlock( block ); -// -// if ( targetPrisonBlock != null && targetPrisonBlock.isAirBroke() ) { -// // If this targetPrisonBlock was originally air or already counted -// // then skip so it is not double counted: -// results = false; -// } -// else if ( targetPrisonBlock != null ){ -// -// // If the block is AIR get the original block name: -// if ( block.getPrisonBlock().isAir() ) { -// -// String targetBlockName = targetPrisonBlock.getPrisonBlock().getBlockName(); -// blockName = targetBlockName; -// } -// -//// Output.get().logInfo( "#### MineData.incrementBlockCount: " + -//// "oBlock= AIR tBlock= %s target= [%s]", blockName, -//// (targetPrisonBlock == null ? "null" : targetPrisonBlock.toString())); -// -// // Set the targetPrisonBlock's airBroke to true to indicate it is being -// // counted during this transaction so it won't be counted again: -// targetPrisonBlock.setAirBroke( true ); -// -// results = incrementBlockMiningCount( blockName ); -// } -// -// return results; -// } - -// public boolean incrementBlockMiningCount( BlockOld block ) { -// String blockName = block.getType().name().toLowerCase(); -// return incrementBlockMiningCount( blockName ); -// } - - - - // MineTargetPrisonBlock getTargetPrisonBlock( Block block ) - -// /** -// *

This function is not as obvious it appears. Basically when this function -// * should be called, it may be too late to get the correct block value before -// * it is lost (set to AIR). So it is critical that getTargetPrisonBlockName( Block block ) -// * is called first before the original block is processed (broke or auto picked up). -// *

-// * -// *

The end result of calling getTargetPrisonBlockName( Block block ) first is that -// * the block name will have already been resolved to the correct original block name. -// * There is also a higher chance that the block name extracted then, may never -// * be AIR to begin with. -// *

-// * -// *

Keep in mind, that if the original block was AIR before being processed for -// * a natural break, or auto pickup, then it may not have been properly mined since -// * AIR cannot be mined. That said, if another process intercepted prison's -// * event handlers, then the targetBlocks will not exist until the mine is reset -// * for the first time when the server starts up. So server startups will -// * have higher risk of not being able to resolve the correct block type to -// * report. -// *

-// * -// * @param blockName -// * @return -// */ -// private boolean incrementBlockMiningCount( String targetBlockName ) { -// boolean results = false; -// -// incrementBlockBreakCount(); -// incrementTotalBlocksMined(); -// -// PrisonBlockStatusData sBlock = getBlockStats( targetBlockName ); -// if ( sBlock != null ) { -// -// sBlock.incrementMiningBlockCount(); -// } -// -// return results; -// } /** *

This is actually the more correct way to count a block that has been mined @@ -721,112 +573,100 @@ public boolean hasBlock( String blockName ) { * @param targetPrisonBlock */ public boolean incrementBlockMiningCount( MineTargetPrisonBlock targetPrisonBlock ) { - boolean results = false; - - // Only count the block as being broke if it was not originally air and - // and it has not been broke before. - - // NOTE: setAirBroke() and setMined() will be set to true if the mine reset - // places an air block. That will prevent the air from being processed. - if ( targetPrisonBlock != null && !targetPrisonBlock.isCounted() ) { - - targetPrisonBlock.setAirBroke( true ); - targetPrisonBlock.setCounted( true ); - - // The field isMined() is used to "reserve" a block to indicate that it is in - // the stages of being processed, since much later in the processing will the - // block be set to setAirBreak() or even setCounted(). This prevents - // high-speed or concurrent operations from multiple players from trying to - // process the same block. So set it to true here, if it has not already - // been set. - if ( !targetPrisonBlock.isMined() ) { - - targetPrisonBlock.setMined( true ); - } - - incrementBlockBreakCount(); - incrementTotalBlocksMined(); - - if ( targetPrisonBlock.getPrisonBlock() != null ) { - - targetPrisonBlock.getPrisonBlock().incrementMiningBlockCount(); - } - - results = true; - } - - return results; + boolean results = false; + + // Only count the block as being broke if it was not originally air and + // and it has not been broke before. + + // NOTE: setAirBroke() and setMined() will be set to true if the mine reset + // places an air block. That will prevent the air from being processed. + if ( targetPrisonBlock != null && !targetPrisonBlock.isCounted() ) { + + targetPrisonBlock.setAirBroke( true ); + targetPrisonBlock.setCounted( true ); + + // The field isMined() is used to "reserve" a block to indicate that it is in + // the stages of being processed, since much later in the processing will the + // block be set to setAirBreak() or even setCounted(). This prevents + // high-speed or concurrent operations from multiple players from trying to + // process the same block. So set it to true here, if it has not already + // been set. + if ( !targetPrisonBlock.isMined() ) { + + targetPrisonBlock.setMined( true ); + } + + incrementBlockBreakCount(); + incrementTotalBlocksMined(); + + if ( targetPrisonBlock.getPrisonBlock() != null ) { + + targetPrisonBlock.getPrisonBlock().incrementMiningBlockCount(); + } + + results = true; + } + + return results; } -// public void incrementBlockMiningCount( Block block ) { -// -// MineTargetPrisonBlock targetBlock = getTargetPrisonBlock( block ); -// incrementBlockMiningCount( targetBlock ); -// -// } - abstract public MineTargetPrisonBlock getTargetPrisonBlock( PrisonBlock block ); -// abstract public String getTargetPrisonBlockName( Block block ); abstract public boolean checkZeroBlockReset(); public boolean hasUnsavedBlockCounts() { - return getUnsavedBlockCount() > 0; + return getUnsavedBlockCount() > 0; } public long getUnsavedBlockCount() { - long results = 0; - - for ( PrisonBlockStatusData blockStats : getBlockStats().values() ) { - results += blockStats.getBlockCountUnsaved(); - } - - return results; + long results = 0; + + for ( PrisonBlockStatusData blockStats : getBlockStats().values() ) { + results += blockStats.getBlockCountUnsaved(); + } + + return results; } public void resetUnsavedBlockCounts() { - for ( PrisonBlockStatusData blockStats : getBlockStats().values() ) { - // Since the mine was just saved reset the unsaved value : - blockStats.setBlockCountUnsaved( 0 ); - - // Reset the block count for the reset event since the mine will be regenerated: - blockStats.setBlockPlacedCount( 0 ); - } + for ( PrisonBlockStatusData blockStats : getBlockStats().values() ) { + // Since the mine was just saved reset the unsaved value : + blockStats.setBlockCountUnsaved( 0 ); + + // Reset the block count for the reset event since the mine will be regenerated: + blockStats.setBlockPlacedCount( 0 ); + } } public void resetResetBlockCounts() { - for ( PrisonBlockStatusData block : getBlocks() ) { - - // Reset the block count for the reset event since the mine will be regenerated: - block.setBlockPlacedCount( 0 ); - block.setRangeBlockCountLow( -1 ); - block.setRangeBlockCountHigh( -1 ); - block.setRangeBlockCountLowLimit( -1 ); - block.setRangeBlockCountHighLimit( -1 ); -// block.setIncludeInLayerCalculations( true ); - } - - for ( PrisonBlockStatusData block : getPrisonBlocks() ) { - - // Reset the block count for the reset event since the mine will be regenerated: - block.setBlockPlacedCount( 0 ); - block.setRangeBlockCountLow( -1 ); - block.setRangeBlockCountHigh( -1 ); - block.setRangeBlockCountLowLimit( -1 ); - block.setRangeBlockCountHighLimit( -1 ); -// block.setIncludeInLayerCalculations( true ); - } + for ( PrisonBlockStatusData block : getBlocks() ) { + + // Reset the block count for the reset event since the mine will be regenerated: + block.setBlockPlacedCount( 0 ); + block.setRangeBlockCountLow( -1 ); + block.setRangeBlockCountHigh( -1 ); + block.setRangeBlockCountLowLimit( -1 ); + block.setRangeBlockCountHighLimit( -1 ); + // block.setIncludeInLayerCalculations( true ); + } + + for ( PrisonBlockStatusData block : getPrisonBlocks() ) { + + // Reset the block count for the reset event since the mine will be regenerated: + block.setBlockPlacedCount( 0 ); + block.setRangeBlockCountLow( -1 ); + block.setRangeBlockCountHigh( -1 ); + block.setRangeBlockCountLowLimit( -1 ); + block.setRangeBlockCountHighLimit( -1 ); + // block.setIncludeInLayerCalculations( true ); + } -// for ( PrisonBlockStatusData blockStats : getBlockStats().values() ) { -// // Reset the block count for the reset event since the mine will be regenerated: -// blockStats.setResetBlockCount( 0 ); -// } } /** @@ -837,49 +677,49 @@ public void resetResetBlockCounts() { * @param statsBlock */ public PrisonBlockStatusData incrementResetBlockCount( PrisonBlockStatusData statsBlock ) { - - PrisonBlockStatusData sBlock = null; - - if ( statsBlock != null ) { - sBlock = getBlockStats( statsBlock ); - - if ( sBlock != null ) { - - sBlock.incrementResetBlockCount(); - } - } - - return sBlock; + + PrisonBlockStatusData sBlock = null; + + if ( statsBlock != null ) { + sBlock = getBlockStats( statsBlock ); + + if ( sBlock != null ) { + + sBlock.incrementResetBlockCount(); + } + } + + return sBlock; } public PrisonBlockStatusData getBlockStats( PrisonBlockStatusData statsBlock ) { - return getBlockStats( statsBlock.getBlockName() ); + return getBlockStats( statsBlock.getBlockName() ); } public PrisonBlockStatusData getBlockStats( String blockName ) { - PrisonBlockStatusData results = null; - - if ( blockName != null && !blockName.trim().isEmpty() ) { - - if ( !getBlockStats().containsKey( blockName ) ) { - - for ( PrisonBlock block : getPrisonBlocks() ) { - if ( block.getBlockName().equalsIgnoreCase( blockName ) ) { - getBlockStats().put( block.getBlockName(), block ); - - results = block; - break; - } - } - - } - else { - - results = getBlockStats().get( blockName ); - } - } - - return results; + PrisonBlockStatusData results = null; + + if ( blockName != null && !blockName.trim().isEmpty() ) { + + if ( !getBlockStats().containsKey( blockName ) ) { + + for ( PrisonBlock block : getPrisonBlocks() ) { + if ( block.getBlockName().equalsIgnoreCase( blockName ) ) { + getBlockStats().put( block.getBlockName(), block ); + + results = block; + break; + } + } + + } + else { + + results = getBlockStats().get( blockName ); + } + } + + return results; } public TreeMap getBlockStats() { @@ -894,59 +734,45 @@ public boolean isInMineExact(Location location) { } public boolean isInMineIncludeTopBottomOfMine(Location location) { - if ( isVirtual() ) { - return false; - } - return getBounds().withinIncludeTopBottomOfMine( location ); + if ( isVirtual() ) { + return false; + } + return getBounds().withinIncludeTopBottomOfMine( location ); } - // Obsolete... the old block model: -// public boolean isInMine(BlockType blockType) { -// //TO DO Not sure if virtual should return false... they do have blocks. -//// if ( isVirtual() ) { -//// return false; -//// } -// for (BlockOld block : getBlocks()) { -// if (blockType == block.getType()) { -// return true; -// } -// } -// return false; -// } - public boolean isInMine(PrisonBlock blockType) { - //TODO Not sure if virtual should return false... they do have blocks. - if ( isVirtual() ) { - return false; - } - for (PrisonBlock block : getPrisonBlocks()) { - if (blockType.getBlockNameFormal().equalsIgnoreCase( block.getBlockNameFormal())) { - return true; - } - } - return false; + //TODO Not sure if virtual should return false... they do have blocks. + if ( isVirtual() ) { + return false; + } + for (PrisonBlock block : getPrisonBlocks()) { + if (blockType.getBlockNameFormal().equalsIgnoreCase( block.getBlockNameFormal())) { + return true; + } + } + return false; } public PrisonBlock getPrisonBlock( PrisonBlock blockType ) { - PrisonBlock results = null; - - if ( blockType != null && blockType.getBlockNameFormal() != null ) { - - for (PrisonBlock block : getPrisonBlocks()) { - if ( block.getBlockNameFormal().equalsIgnoreCase( blockType.getBlockNameFormal() )) { - results = block; - break; - } - } - } - - return results; + PrisonBlock results = null; + + if ( blockType != null && blockType.getBlockNameFormal() != null ) { + + for (PrisonBlock block : getPrisonBlocks()) { + if ( block.getBlockNameFormal().equalsIgnoreCase( blockType.getBlockNameFormal() )) { + results = block; + break; + } + } + } + + return results; } public double area() { - if ( isVirtual() ) { - return 0; - } + if ( isVirtual() ) { + return 0; + } return getBounds().getArea(); } @@ -978,18 +804,18 @@ public double area() { * @return */ public boolean hasTPAccess( Player player ) { - boolean results = false; - - String minePermission = "mines.tp." + getName().toLowerCase(); - - if ( isTpAccessByRank() && Prison.get().getPlatform().isMineAccessibleByRank( player, this ) || - player.hasPermission("mines.tp") || - !isTpAccessByRank() && player.hasPermission( minePermission ) ) { - - results = true; - } - - return results; + boolean results = false; + + String minePermission = "mines.tp." + getName().toLowerCase(); + + if ( isTpAccessByRank() && Prison.get().getPlatform().isMineAccessibleByRank( player, this ) || + player.hasPermission("mines.tp") || + !isTpAccessByRank() && player.hasPermission( minePermission ) ) { + + results = true; + } + + return results; } /** @@ -1020,59 +846,59 @@ public boolean hasTPAccess( Player player ) { * @return */ public boolean hasMiningAccess( Player player ) { - boolean results = false; - - StringBuilder dbug = new StringBuilder(); - - dbug.append( "&3## hasMineAccess: mineAccessByRank: " ).append( isMineAccessByRank() ); - - /// Note: the following cannot be added here since it will grant access if both are disabled - // || !isMineAccessByRank() && !isAccessPermissionEnabled() - - if ( isMineAccessByRank() ) { - - if ( Prison.get().getPlatform().isMineAccessibleByRank( player, this ) ) { - - dbug.append( "Success!" ); - results = true; - } - else { - dbug.append( "&cFailed! &aPlayer does not have access based upon their rank." ); - } - - } - else { - - dbug.append( " accessByPerms: " ).append( isAccessPermissionEnabled() ); - - if ( isAccessPermissionEnabled() ) { - - if ( player.hasPermission( getAccessPermission() )) { - - dbug.append( "Success!" ); - results = true; - } - else { - dbug.append( "&cFailed! &aPlayer does not have access based upon the permission: [" ) - .append( getAccessPermission() == null ? "null" : getAccessPermission() ); - } - } - else { - - dbug.append( " &cFailed! &aMust have either accessByRank or accessByPerm enabled. " ); - } - - } - - if ( Output.get().isDebug() ) { - Output.get().logInfo( dbug.toString() ); - } - - return results; + boolean results = false; + + StringBuilder dbug = new StringBuilder(); + + dbug.append( "&3## hasMineAccess: mineAccessByRank: " ).append( isMineAccessByRank() ); + + /// Note: the following cannot be added here since it will grant access if both are disabled + // || !isMineAccessByRank() && !isAccessPermissionEnabled() + + if ( isMineAccessByRank() ) { + + if ( Prison.get().getPlatform().isMineAccessibleByRank( player, this ) ) { + + dbug.append( "Success!" ); + results = true; + } + else { + dbug.append( "&cFailed! &aPlayer does not have access based upon their rank." ); + } + + } + else { + + dbug.append( " accessByPerms: " ).append( isAccessPermissionEnabled() ); + + if ( isAccessPermissionEnabled() ) { + + if ( player.hasPermission( getAccessPermission() )) { + + dbug.append( "Success!" ); + results = true; + } + else { + dbug.append( "&cFailed! &aPlayer does not have access based upon the permission: [" ) + .append( getAccessPermission() == null ? "null" : getAccessPermission() ); + } + } + else { + + dbug.append( " &cFailed! &aMust have either accessByRank or accessByPerm enabled. " ); + } + + } + + if ( Output.get().isDebug() ) { + Output.get().logInfo( dbug.toString() ); + } + + return results; } public boolean isAccessPermissionEnabled() { - return accessPermission != null && !accessPermission.trim().isEmpty(); + return accessPermission != null && !accessPermission.trim().isEmpty(); } public String getAccessPermission() { return accessPermission; @@ -1124,7 +950,7 @@ public void setMineAccessByRank( boolean mineAccessByRank ) { * world can't be found */ public Location getSpawn() { - return spawn; + return spawn; } /** @@ -1134,11 +960,11 @@ public Location getSpawn() { * @return this instance for chaining */ public void setSpawn(Location location) { - // cannot set spawn when virtual: - if ( !isVirtual() ) { - hasSpawn = (location != null); - spawn = location; - } + // cannot set spawn when virtual: + if ( !isVirtual() ) { + hasSpawn = (location != null); + spawn = location; + } } public boolean isHasSpawn() { @@ -1328,13 +1154,6 @@ public void setResetCommands( List resetCommands ) { this.resetCommands = resetCommands; } -// public boolean isUsePagingOnReset() { -// return usePagingOnReset; -// } -// public void setUsePagingOnReset( boolean usePagingOnReset ) { -// this.usePagingOnReset = usePagingOnReset; -// } - public ModuleElement getRank() { return rank; } diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineLevelBlockListData.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineLevelBlockListData.java index 6ffe17b7b..4e8490dd6 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineLevelBlockListData.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineLevelBlockListData.java @@ -219,9 +219,6 @@ public PrisonBlock randomlySelectPrisonBlock() for ( PrisonBlock block : selectedBlocks ) { - // NOTE: do not have use this field anymore: -// block.isIncludeInLayerCalculations(); - // If chance falls on this block, then select it as long as it has not // exceed the max count for this block if the max constraint is enabled. // If the block's constraint max is reached, then isIncludedInLayerCalculation will @@ -247,8 +244,6 @@ public PrisonBlock randomlySelectPrisonBlock() selected.getConstraintMax() > 0 && (selected.getBlockPlacedCount() + 1) >= selected.getConstraintMax() ) { -// selected.setIncludeInLayerCalculations( false ); - selectedBlocks.remove(selected); selectedChance -= selected.getChance(); 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 d021e15b1..1ef1e9525 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 @@ -120,11 +120,6 @@ public abstract class MineReset private transient long statsBlockUpdateTimeMS = 0; private transient long statsBlockUpdateTimeNanos = 0; - // Note: The time it takes to teleport players and broadcast is so trivial - // that they are being disabled to reduce the clutter and memory load. -// private long statsTeleport1TimeMS = 0; -// private long statsTeleport2TimeMS = 0; -// private long statsMessageBroadcastTimeMS = 0; private transient int statsResetPages = 0; private transient long statsResetPageBlocks = 0; @@ -137,9 +132,6 @@ public abstract class MineReset public MineReset() { super(); -// this.mineTargetPrisonBlocks = new ArrayList<>(); -// this.mineTargetPrisonBlocksMap = new TreeMap<>(); - this.statsMineSweeperTaskMs = new ArrayList<>(); this.currentJob = null; @@ -159,270 +151,94 @@ public MineReset() { */ @Override protected void initialize() { - super.initialize(); - - if ( !isVirtual() ) { - - // Once the mine has been loaded, MUST get a count of all air blocks. - refreshBlockBreakCountUponStartup( 0 ); - } + super.initialize(); + + if ( !isVirtual() ) { + + // Once the mine has been loaded, MUST get a count of all air blocks. + refreshBlockBreakCountUponStartup( 0 ); + } } -// /** -// *

Optimized the mine reset to focus on itself. Also set the Y plane to refresh at the top and work its -// * way down. That way if the play is teleported to the top, it will appear like the whole mine has reset -// * instantly and they will not see the delay from the bottom of the mine working up to the top. This will -// * also reduce the likelihood of the player falling back in to the mine if there is no spawn set. -// *

-// * -// *

The ONLY code that could be asynchronous ran is the random generation of the blocks. The other -// * lines of code is using bukkit and/or spigot api calls which MUST be ran synchronously. -// *

-// */ -// protected void resetSynchonously() { -// -// if ( isDeleted() ) { -// // if the mine is deleted, just return without doing anything. This will -// // cancel the job. -// return; -// } -// -// long start = System.currentTimeMillis(); -// -// // The all-important event -// MineResetEvent event = new MineResetEvent(this, resetType); -// Prison.get().getEventBus().post(event); -// if (!event.isCanceled()) { -// resetSynchonouslyInternal(); -// } -// -// long stop = System.currentTimeMillis(); -// setStatsResetTimeMS( stop - start ); -// -// // Tie to the command stats mode so it logs it if stats are enabled: -// if ( PrisonMines.getInstance().getMineManager().isMineStats() ) { -// DecimalFormat dFmt = Prison.get().getDecimalFormatInt(); -// Output.get().logInfo("&cMine reset: &7" + getTag() + -// "&c Blocks: &7" + dFmt.format( getBounds().getTotalBlockCount() ) + -// statsMessage() ); -// } -// -// } - -// /** -// *

This function now follows the general behavior as the async reset in that it now -// * uses a target block listing to help ensure the constraints are honored when -// * generating the blocks. -// *

-// * -// */ -// private void resetSynchonouslyInternal() { -// try { -// -// if ( isVirtual() || isDeleted() ) { -// // Mine is virtual and cannot be reset. Just skip this with no error messages. -// // If the mine is deleted, just return without doing anything. -// return; -// } -// -// if ( !isEnabled() ) { -// Output.get().logError( -// String.format( "MineReset: Reset failure: Mine is not enabled. " + -// "Ensure world exists. mine= %s ", -// getName() )); -// return; -// } -// -// -// teleportAllPlayersOut(); -//// setStatsTeleport1TimeMS( -//// teleportAllPlayersOut( getBounds().getyBlockMax() ) ); -// -// -// // Reset stats: -// resetStats(); -// -// -// generateBlockListAsync(); -// -// -// if ( !getCurrentJob().getResetActions().contains( MineResetActions.NO_COMMANDS )) { -// -// // Before reset commands: -// if ( getResetCommands() != null && getResetCommands().size() > 0 ) { -// -// List cmdTasks = new ArrayList<>(); -// -// int row = 0; -// for (String command : getResetCommands() ) { -// row++; -//// String formatted = cmd.replace("{player}", prisonPlayer.getName()) -//// .replace("{player_uid}", player.uid.toString()); -// if ( command.startsWith( "before: " )) { -// String cmd = command.replace( "before: ", "" ); -// -// String debugInfo = "MineReset sync: " + getName() + " Before:"; -// PrisonCommandTaskData cmdTask = new PrisonCommandTaskData( -// debugInfo, cmd, row ); -// -// cmdTasks.add( cmdTask ); -//// PrisonCommandTasks.submitTasks( cmdTask ); -// //PrisonAPI.dispatchCommand(cmd); -// } -// } -// -// PrisonCommandTasks.submitTasks( cmdTasks ); -// } -// } -// -// -// MinePagedResetAsyncTask resetTask = new MinePagedResetAsyncTask( (Mine) this, MineResetType.normal ); -// resetTask.submitTaskAsync(); -//// resetAsynchonouslyUpdate( false ); -// -// -// -// // If a player falls back in to the mine before it is fully done being reset, -// // such as could happen if there is lag or a lot going on within the server, -// // this will TP anyone out who would otherwise suffocate. I hope! lol -// teleportAllPlayersOut(); -//// setStatsTeleport2TimeMS( -//// teleportAllPlayersOut( getBounds().getyBlockMax() ) ); -// -// -// incrementResetCount(); -// -// if ( !getCurrentJob().getResetActions().contains( MineResetActions.NO_COMMANDS )) { -// -// // After reset commands: -// if ( getResetCommands() != null && getResetCommands().size() > 0 ) { -// -// List cmdTasks = new ArrayList<>(); -// -// int row = 0; -// for (String command : getResetCommands() ) { -// row++; -//// String formatted = cmd.replace("{player}", prisonPlayer.getName()) -//// .replace("{player_uid}", player.uid.toString()); -// if ( command.startsWith( "after: " )) { -// String cmd = command.replace( "after: ", "" ); -// -// String debugInfo = "MineReset sync: " + getName() + " After:"; -// PrisonCommandTaskData cmdTask = new PrisonCommandTaskData( -// debugInfo, cmd, row ); -// -// cmdTasks.add( cmdTask ); -// } -// } -// -// PrisonCommandTasks.submitTasks( cmdTasks ); -// } -// } -// -// -// // Broadcast message to all players within a certain radius of this mine: -// broadcastResetMessageToAllPlayersWithRadius(); -//// broadcastResetMessageToAllPlayersWithRadius( MINE_RESET__BROADCAST_RADIUS_BLOCKS ); -// -// -// submitTeleportGlassBlockRemoval(); -// -// -// // If part of a chained_resets, then kick off the next reset: -// if ( getCurrentJob().getResetActions().contains( MineResetActions.CHAINED_RESETS )) { -// -// PrisonMines pMines = PrisonMines.getInstance(); -// pMines.resetAllMinesNext(); -// } -// -// -// } catch (Exception e) { -// Output.get().logError("&cFailed to reset mine " + getName(), e); -// } -// } - public String statsMessage() { - StringBuilder sb = new StringBuilder(); - DecimalFormat dFmt = Prison.get().getDecimalFormatDouble(); - DecimalFormat iFmt = Prison.get().getDecimalFormatInt(); - - sb.append( "&3 ResetTime: &7" ); - sb.append( dFmt.format(getStatsResetTimeMS() / 1000.0d )).append( " s " ); - - sb.append( "&3 BlockGenTime: &7" ); - sb.append( dFmt.format(getStatsBlockGenTimeMS() / 1000.0d )).append( " s " ); - - - sb.append( "&3 BlockUpdateTime: &7" ); - sb.append( dFmt.format(getStatsBlockUpdateTimeMS() / 1000.0d )).append( " s " ); - sb.append( dFmt.format(getStatsBlockUpdateTimeNanos() / 1000000.0d )).append( " ms(nanos) " ); - - - sb.append( "&3 ResetPages: &7" ); - sb.append( iFmt.format(getStatsResetPages() )); - - double avgBlocks = getStatsResetPages() == 0 ? 0 : - getStatsResetPageBlocks() / getStatsResetPages(); - double avgMs = getStatsResetPages() == 0 ? 0 : - getStatsResetPageMs() / getStatsResetPages(); - - sb.append( "&3 avgBlocksPerPage: &7" ); - sb.append( dFmt.format(avgBlocks)); - - sb.append( "&3 avgMsPerPage: &7" ); - sb.append( dFmt.format(avgMs)); - - sb.append( statsMessageMineSweeper() ); - -// sb.append( " TPS: " ) -// .append( Prison.get().getPrisonTPS().getAverageTPSFormatted() ); - - return sb.toString(); + StringBuilder sb = new StringBuilder(); + DecimalFormat dFmt = Prison.get().getDecimalFormatDouble(); + DecimalFormat iFmt = Prison.get().getDecimalFormatInt(); + + sb.append( "&3 ResetTime: &7" ); + sb.append( dFmt.format(getStatsResetTimeMS() / 1000.0d )).append( " s " ); + + sb.append( "&3 BlockGenTime: &7" ); + sb.append( dFmt.format(getStatsBlockGenTimeMS() / 1000.0d )).append( " s " ); + + + sb.append( "&3 BlockUpdateTime: &7" ); + sb.append( dFmt.format(getStatsBlockUpdateTimeMS() / 1000.0d )).append( " s " ); + sb.append( dFmt.format(getStatsBlockUpdateTimeNanos() / 1000000.0d )).append( " ms(nanos) " ); + + + sb.append( "&3 ResetPages: &7" ); + sb.append( iFmt.format(getStatsResetPages() )); + + double avgBlocks = getStatsResetPages() == 0 ? 0 : + getStatsResetPageBlocks() / getStatsResetPages(); + double avgMs = getStatsResetPages() == 0 ? 0 : + getStatsResetPageMs() / getStatsResetPages(); + + sb.append( "&3 avgBlocksPerPage: &7" ); + sb.append( dFmt.format(avgBlocks)); + + sb.append( "&3 avgMsPerPage: &7" ); + sb.append( dFmt.format(avgMs)); + + sb.append( statsMessageMineSweeper() ); + + // sb.append( " TPS: " ) + // .append( Prison.get().getPrisonTPS().getAverageTPSFormatted() ); + + return sb.toString(); } public String statsMessageMineSweeper() { - StringBuilder sb = new StringBuilder(); - - if ( getStatsMineSweeperTaskMs().size() > 0 ) { - sb.append( " &3 MineSweeper ms: " ); - - for ( Long sweepMs : getStatsMineSweeperTaskMs() ) { - sb.append( sweepMs ).append( " " ); - } - } - - return sb.toString(); + StringBuilder sb = new StringBuilder(); + + if ( getStatsMineSweeperTaskMs().size() > 0 ) { + sb.append( " &3 MineSweeper ms: " ); + + for ( Long sweepMs : getStatsMineSweeperTaskMs() ) { + sb.append( sweepMs ).append( " " ); + } + } + + return sb.toString(); } private void resetStats() { - setResetPage( 0 ); - - setBlockBreakCount( 0 ); - - // The reset position is critical in ensuring that all blocks within the mine are reset - // and that when a reset process pages (allows another process to run) then it will be - // used to pick up where it left off. - setResetPosition( 0 ); - - setSkipResetBypassCount( 0 ); - - // NOTE: DO NOT reset blockBreakCount here! Players can break many blocks between - // here and when the mine actually starts to reset. - - setAirCountOriginal( 9 ); - setAirCount( 0 ); - - setStatsResetTimeMS( 0 ); - setStatsBlockGenTimeMS( 0 ); - setStatsBlockUpdateTimeMS( 0 ); - setStatsBlockUpdateTimeNanos( 0 ); -// setStatsTeleport1TimeMS( 0 ); -// setStatsTeleport2TimeMS( 0 ); -// setStatsMessageBroadcastTimeMS( 0 ); - - setStatsResetPages( 0 ); - setStatsResetPageBlocks( 0 ); + setResetPage( 0 ); + + setBlockBreakCount( 0 ); + + // The reset position is critical in ensuring that all blocks within the mine are reset + // and that when a reset process pages (allows another process to run) then it will be + // used to pick up where it left off. + setResetPosition( 0 ); + + setSkipResetBypassCount( 0 ); + + // NOTE: DO NOT reset blockBreakCount here! Players can break many blocks between + // here and when the mine actually starts to reset. + + setAirCountOriginal( 9 ); + setAirCount( 0 ); + + setStatsResetTimeMS( 0 ); + setStatsBlockGenTimeMS( 0 ); + setStatsBlockUpdateTimeMS( 0 ); + setStatsBlockUpdateTimeNanos( 0 ); + + setStatsResetPages( 0 ); + setStatsResetPageBlocks( 0 ); setStatsResetPageMs( 0 ); @@ -464,12 +280,8 @@ public void saveIfUnsavedBlockCounts() { * * @param callbackAsync */ -// public abstract int submitAsyncTask( PrisonRunnable callbackAsync ); - public abstract int submitAsyncTask( PrisonRunnable callbackAsync, long delay ); -// public abstract int submitSyncTask( PrisonRunnable callbackSync ); - public abstract int submitSyncTask( PrisonRunnable callbackSync, long delay ); @@ -532,10 +344,11 @@ public int getPlayerCount() { */ public void generateBlockListAsync() { - if ( isVirtual() || isDeleted() ) { - // ignore and generate no error messages: - return; - } + if ( isVirtual() || isDeleted() ) { + // ignore and generate no error messages: + return; + } + if ( !isEnabled() ) { Output.get().logError( String.format( "MineReset: Block count failure: Mine is not enabled. " + @@ -543,8 +356,8 @@ public void generateBlockListAsync() { getName() )); return; } - - long start = System.currentTimeMillis(); + + long start = System.currentTimeMillis(); // Reset stats: resetStats(); @@ -559,9 +372,6 @@ public void generateBlockListAsync() { resetResetBlockCounts(); -// // setup the monitoring of the blocks that have constraints: -// List constrainedBlocks = null; - Optional worldOptional = getWorld(); World world = worldOptional.get(); @@ -612,10 +422,6 @@ public void generateBlockListAsync() { targetLocation.setEdge( isEdge ); targetLocation.setCorner( isCorner ); -// MineTargetBlock mtb = null; - - // track the constraints: (obsolete) - //trackConstraints( currentLevel, constrainedBlocks ); PrisonBlock prisonBlock = mineLevelBlockList.randomlySelectPrisonBlock(); @@ -623,18 +429,15 @@ public void generateBlockListAsync() { prisonBlock = PrisonBlock.AIR.clone(); } -// PrisonBlock prisonBlock = randomlySelectPrisonBlock( random, currentLevel ); // Increment the mine's block count. This block is one of the control blocks: incrementResetBlockCount( prisonBlock ); // TODO AIR block fix - allow AIR to be part of the regular block list? addMineTargetPrisonBlock( prisonBlock, targetLocation ); -// mtb = new MineTargetPrisonBlock( prisonBlock, x, y, z); if ( prisonBlock.isAir() ) { -// if ( prisonBlock.equals( PrisonBlock.AIR ) ) { -// mAirBlocks[i++] = true; + airCount++; } @@ -655,7 +458,6 @@ public void generateBlockListAsync() { if ( Output.get().isDebug() && Output.get().isSelectiveTarget( DebugTarget.blockConstraints ) ) { DecimalFormat dFmt = Prison.get().getDecimalFormatDouble(); - //DecimalFormat iFmt = Prison.get().getDecimalFormatInt(); for ( PrisonBlockStatusData b : getPrisonBlocks() ) { @@ -693,520 +495,155 @@ public void generateBlockListAsync() { } -// private void trackConstraints( int currentLevel, List constrainedBlocks ) -// { -// -// // If the constrainedBlocks list has not be configured, set it up with the -// // blocks that have constraints: -// if ( constrainedBlocks == null ) { -// -// constrainedBlocks = new ArrayList<>(); -// -// for (PrisonBlock block : getPrisonBlocks()) { -// if ( block.getConstraintExcludeTopLayers() > 0 || -// block.getConstraintExcludeBottomLayers() > 0 ) { -// -// constrainedBlocks.add( block ); -// } -// } -// } -// -// -// // If there are any constrained blocks, then need to record -// for ( PrisonBlockStatusData block : constrainedBlocks ) { -// -// // If exclude top layers is enabled, then only try to set the -// // rangeBlockCountLowLimit once since we need the lowest possible -// // value. The inital value for getRangeBlockCountLowLimit is -1. -// if ( block.getConstraintExcludeTopLayers() > 0 && -// block.getRangeBlockCountLowLimit() <= 0 && -// currentLevel > block.getConstraintExcludeTopLayers() ) { -// -// int targetBlockPosition = getMineTargetPrisonBlocks().size(); -// block.setRangeBlockCountLowLimit( targetBlockPosition ); -// } -// -// // If exclude bottom layer is enabled, then we need to track every number -// // until the currentLevel exceeds the getConstraintExcludeBottomLayers value. -// // If exclude top layers, then do not record for the bottom layers until -// // the top layers is cleared. -// if ( (block.getConstraintExcludeTopLayers() > 0 && -// currentLevel > block.getConstraintExcludeTopLayers() || -// block.getConstraintExcludeTopLayers() == 0) && -// -// block.getConstraintExcludeBottomLayers() > 0 && -// block.getConstraintExcludeBottomLayers() < currentLevel -// ) { -// -// int targetBlockPosition = getMineTargetPrisonBlocks().size(); -// block.setRangeBlockCountHighLimit( targetBlockPosition ); -// -// } -// } -// -// } - -// /** -// * -// *

Update 2021-08-25 : This function should only be called once now. The main -// * work on performing the actual resets is now performed within the task -// * MinePagedResetAsyncTask. This is now to be ran asynchronously. -// *

-// * -// *

Yeah I know, it has async in the name of the function, but it still can only -// * be ran synchronously. The async part implies this is the reset "part" for the -// * async workflow. -// *

-// * -// *

Before this part is ran, the generateBlockListAsync() function must be ran -// * to regenerate the new block list. -// *

-// * -// */ -// protected void resetAsynchonously() { -// boolean canceled = false; -// -//// Output.get().logInfo( "MineRest.resetAsynchonously() " + getName() ); -// -// if ( isVirtual() ) { -// canceled = true; -// } -// -// if ( !canceled && getResetPage() == 0 ) { -// generateBlockListAsync(); -// -// canceled = resetAsynchonouslyInitiate( MineResetType.normal ); -// } -// -// if ( !canceled ) { -// -//// // First time through... reset the block break count and run the before reset commands: -//// if ( getResetPosition() == 0 ) { -//// -//// // Reset the block break count before resetting the blocks: -//// // Set it to the original air count, if subtracted from total block count -//// // in the mine, then the result will be blocks remaining. -//// setBlockBreakCount( getAirCountOriginal() ); -//// -//// -//// if ( !getCurrentJob().getResetActions().contains( MineResetActions.NO_COMMANDS )) { -//// -//// // Before reset commands: -//// if ( getResetCommands() != null && getResetCommands().size() > 0 ) { -//// -//// for (String command : getResetCommands() ) { -////// String formatted = cmd.replace("{player}", prisonPlayer.getName()) -////// .replace("{player_uid}", player.uid.toString()); -//// if ( command.startsWith( "before: " )) { -//// String cmd = command.replace( "before: ", "" ); -//// -//// PrisonCommandTask cmdTask = new PrisonCommandTask( "MineReset: Before:" ); -//// cmdTask.submitCommandTask( cmd ); -//// -//// // PrisonAPI.dispatchCommand(cmd); -//// } -//// } -//// } -//// } -//// -//// } -// -// asynchronouslyResetSetup(); -// -// MinePagedResetAsyncTask resetTask = new MinePagedResetAsyncTask( (Mine) this, MineResetType.normal ); -// resetTask.submitTaskAsync(); -// -// asynchronouslyResetFinalize( null ); -// -// -//// resetAsynchonouslyUpdate( true ); -// -//// if ( getResetPosition() == getMineTargetPrisonBlocks().size() ) { -//// // Done resetting the mine... wrap up: -//// -//// -//// // If a player falls back in to the mine before it is fully done being reset, -//// // such as could happen if there is lag or a lot going on within the server, -//// // this will TP anyone out who would otherwise suffocate. I hope! lol -//// teleportAllPlayersOut(); -////// setStatsTeleport2TimeMS( -////// teleportAllPlayersOut( getBounds().getyBlockMax() ) ); -//// -//// // Reset the paging for the next reset: -//// setResetPage( 0 ); -//// -//// incrementResetCount(); -//// -//// if ( !getCurrentJob().getResetActions().contains( MineResetActions.NO_COMMANDS )) { -//// -//// // After reset commands: -//// if ( getResetCommands() != null && getResetCommands().size() > 0 ) { -//// -//// for (String command : getResetCommands() ) { -////// String formatted = cmd.replace("{player}", prisonPlayer.getName()) -////// .replace("{player_uid}", player.uid.toString()); -//// if ( command.startsWith( "after: " )) { -//// String cmd = command.replace( "after: ", "" ); -//// -//// PrisonCommandTask cmdTask = new PrisonCommandTask( "MineReset: After:" ); -//// cmdTask.submitCommandTask( cmd ); -//// -//// // PrisonAPI.dispatchCommand(cmd); -//// } -//// } -//// } -//// } -//// -//// -//// // Broadcast message to all players within a certain radius of this mine: -//// broadcastResetMessageToAllPlayersWithRadius(); -////// broadcastResetMessageToAllPlayersWithRadius( MINE_RESET__BROADCAST_RADIUS_BLOCKS ); -//// -//// -//// submitTeleportGlassBlockRemoval(); -//// -//// -//// // Tie to the command stats mode so it logs it if stats are enabled: -//// if ( PrisonMines.getInstance().getMineManager().isMineStats() || -//// getCurrentJob().getResetActions().contains( MineResetActions.DETAILS ) ) { -//// DecimalFormat dFmt = Prison.get().getDecimalFormatInt(); -//// Output.get().logInfo("&cMine reset: &7" + getTag() + -//// "&c Blocks: &7" + dFmt.format( getBounds().getTotalBlockCount() ) + -//// statsMessage() ); -//// } -//// -//// // If part of a chained_resets, then kick off the next reset: -//// if ( getCurrentJob().getResetActions().contains( MineResetActions.CHAINED_RESETS )) { -//// -//// PrisonMines pMines = PrisonMines.getInstance(); -//// pMines.resetAllMinesNext(); -//// } -//// -//// -//// } -// -//// NOTE: Only run this ONCE now... MinePagedResetAsyncTask handles the paging now -//// else { -//// -//// // Need to continue to reset the mine. Resubmit it to run again. -//// MineResetAsyncResubmitTask mrAsyncRT = new MineResetAsyncResubmitTask( this, null, -//// getCurrentJob().getResetActions() ); -//// -//// // Must run synchronously!! -//// submitSyncTask( mrAsyncRT ); -//// } -// } -// -// -// } - public List getTargetBlockStatsPerLevel() { - List layers = new ArrayList<>(); - - - // Scan all blocks to see if they are the same or now air - // Use isCheckAir() and isCheckSamme(); - scanAllBlocksForUpdates(); - - -// int blocksPerLayer = getBounds().getBlockCountPerLayer(); - //int totalLayers = getBounds().getTotalLayers(); - - // BlockName = BlockLetter -// TreeMap translator = new TreeMap<>(); -// TreeMap map = new TreeMap<>(); -// TreeMap mapMine = new TreeMap<>(); - - // Add AIR to make sure it is there: - PrisonBlock air = PrisonBlock.AIR.clone(); - boolean hasAir = getPrisonBlock( air.getBlockName() ) != null; - - if ( !hasAir ) { - getPrisonBlocks().add( air ); - getBlockStats( air ); - } - - int j = 0; - TreeSet keys = new TreeSet<>( getBlockStats().keySet() ); - for (String key : keys) { + List layers = new ArrayList<>(); + + + // Scan all blocks to see if they are the same or now air + // Use isCheckAir() and isCheckSamme(); + scanAllBlocksForUpdates(); + + + // Add AIR to make sure it is there: + PrisonBlock air = PrisonBlock.AIR.clone(); + boolean hasAir = getPrisonBlock( air.getBlockName() ) != null; + + if ( !hasAir ) { + getPrisonBlocks().add( air ); + getBlockStats( air ); + } + + int j = 0; + TreeSet keys = new TreeSet<>( getBlockStats().keySet() ); + for (String key : keys) { PrisonBlockStatusData blk = getBlockStats().get( key ); blk.setAltValues( j++ ); } - - -// String codesStr = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789@#&*"; -// List codes = Arrays.asList( codesStr.split("|")); -// String colors = "12345789abcde"; - - - // Always add the air block: -// translator.put( PrisonBlock.AIR.getBlockName(), "" ); - - - -// // Build translations: -// char blk = 'A'; -//// double chance = 0; -//// boolean hasAir = false; -// -// // First add all the blocks with an empty String as the value: -// for (PrisonBlock b : getPrisonBlocks() ) { -//// chance += b.getChance(); -// translator.put( b.getBlockName(), "" ); -//// if ( b.isAir() ) { -//// hasAir = true; -//// } -// } -//// if ( !hasAir && chance < 100.0d ) { -//// translator.put( PrisonBlock.AIR.getBlockName(), "" ); -//// } -// -// // Now that they are in order, assign the alphabetical names: -// Set tkeys = translator.keySet(); -// for (String tKey : tkeys) { -// translator.put( tKey, Character.toString( blk ) ); -// -// if ( blk == 'Z' ) { -// blk = 'a'; -// } -// else if ( blk == 'z' ) { -// blk = '1'; -// } -// else { -// blk++; -// } -// } - -// String airName = PrisonBlock.AIR.getBlockName(); -// String keyAir = translator.get(airName); -// -// map.put( keyAir, 0 ); -// mapMine.put( keyAir, 0 ); - - int layer = 0; - int blockCount = 0; - - for ( int i = 0; i < getMineTargetPrisonBlocks().size(); i++ ) { - - MineTargetPrisonBlock tBlock = getMineTargetPrisonBlocks().get(i); - int y = getMineTargetPrisonBlocks().get(i).getLocation().getBlockY(); - blockCount++; - - - { - PrisonBlockStatusData statsBlock = null; - - // the getPrisonblock() should not return a null value: - PrisonBlockStatusData sBlock = tBlock.getPrisonBlock(); - - if ( sBlock == null ) { - sBlock = PrisonBlock.AIR.clone(); - } - - String blockName = sBlock.getBlockName(); - statsBlock = getBlockStats().get( blockName ); - - - // TODO Not sure if air.getBlockName() is correct! It was just 'air' which was wrong. - // Did not have time to review this code to see if blockName is correct. - if ( statsBlock == null ) { - statsBlock = getBlockStats().get( air.getBlockName() ); - } - - - statsBlock.setAltCountVirtual( statsBlock.getAltCountVirtual() + 1); - if ( tBlock.isCheckSame() ) { - statsBlock.setAltCountPhysical( statsBlock.getAltCountPhysical() + 1); - } - else if ( tBlock.isCheckAir() ) { - - PrisonBlockStatusData airStats = getBlockStats( air ); - airStats.setAltCountPhysical( airStats.getAltCountPhysical() + 1); - - } - - } - - -// int level = (int) ((i / (double) blocksPerLayer) + 1); - -// getBlockStats(keyAir); -// tBlock.getPrisonBlock(); -// -// String keyPrime = tBlock == null || tBlock.getPrisonBlock() == null ? -// airName : -// tBlock.getPrisonBlock().getBlockName(); -// -// String key = translator.get(keyPrime); -// -// if ( !map.containsKey(key) ) { -// map.put( key, 1 ); -// } -// else { -// map.put( key, 1 + map.get(key) ); -// } -// -// if ( !mapMine.containsKey(key) ) { -// mapMine.put( key, 0 ); -// } -//// if ( !mapMine.containsKey(keyAir) ) { -//// mapMine.put( keyAir, 0 ); -//// } -// -// if ( tBlock.isCheckSame() ) { -// mapMine.put( key, 1 + mapMine.get(key) ); -// } -// else if ( tBlock.isCheckAir() ) { -// mapMine.put( keyAir, 1 + mapMine.get(keyAir) ); -// -// } - + + int layer = 0; + int blockCount = 0; + + for ( int i = 0; i < getMineTargetPrisonBlocks().size(); i++ ) { + + MineTargetPrisonBlock tBlock = getMineTargetPrisonBlocks().get(i); + int y = getMineTargetPrisonBlocks().get(i).getLocation().getBlockY(); + blockCount++; + + + { + PrisonBlockStatusData statsBlock = null; + + // the getPrisonblock() should not return a null value: + PrisonBlockStatusData sBlock = tBlock.getPrisonBlock(); + + if ( sBlock == null ) { + sBlock = PrisonBlock.AIR.clone(); + } + + String blockName = sBlock.getBlockName(); + statsBlock = getBlockStats().get( blockName ); + + + // TODO Not sure if air.getBlockName() is correct! It was just 'air' which was wrong. + // Did not have time to review this code to see if blockName is correct. + if ( statsBlock == null ) { + statsBlock = getBlockStats().get( air.getBlockName() ); + } + + + statsBlock.setAltCountVirtual( statsBlock.getAltCountVirtual() + 1); + if ( tBlock.isCheckSame() ) { + statsBlock.setAltCountPhysical( statsBlock.getAltCountPhysical() + 1); + } + else if ( tBlock.isCheckAir() ) { + + PrisonBlockStatusData airStats = getBlockStats( air ); + airStats.setAltCountPhysical( airStats.getAltCountPhysical() + 1); + + } + + } - if ( (i + 1) >= getMineTargetPrisonBlocks().size() || - getMineTargetPrisonBlocks().get(i + 1).getLocation().getBlockY() != y ) { - - StringBuilder sb = new StringBuilder(); - - sb.append( "Layer " ).append( layer++ ) - .append( " (" ).append( blockCount ).append(")") - .append( " : " ); - -// TreeSet keys = new TreeSet<>( map.keySet() ); - for ( String k : keys ) { - - PrisonBlockStatusData statsBlock = getBlockStats( k ); - - sb.append( statsBlock.getAltColorCode() ) - .append( statsBlock.getAltAlias() ) - .append( Output.get().getColorCodeInfo() ) - .append( ":" ) - .append( statsBlock.getAltCountVirtual() ); - - if ( statsBlock.getAltCountVirtual() != statsBlock.getAltCountPhysical() ) { - sb.append( ":" ) - .append( statsBlock.getAltCountPhysical() ); - } - - sb.append( " " ); - - statsBlock.resetAltValues(); - -// for ( Entry eSet : translator.entrySet()) { -// if ( eSet.getValue().equalsIgnoreCase(k) ) { -// -// String blockName = eSet.getKey(); -// sb.append( blockName ).append( ":" ).append( map.get(k) ).append( " " ); -// -// break; -// } -// } - -// int c = k.charAt(0) % colors.length(); -// -// String color = "&" + String.valueOf(colors.charAt(c)); -// -// int count = map.get(k); -// int countMine = mapMine.get(k); -// -// sb -// .append( color ).append( k ).append( Output.get().getColorCodeDebug() ) -// .append( ":" ).append( count ); -// -// if ( count != countMine ) { -// sb -// .append( ":" ).append( countMine ); -// } -// -// sb.append( " " ); - } - - layers.add( sb.toString() ); - - blockCount = 0; - - -// map.clear(); -// mapMine.clear(); -// -// map.put( keyAir, 0 ); -// mapMine.put( keyAir, 0 ); - } -// // if last block of the layer: -// if ( (int) (((i + 1) / (double) blocksPerLayer) + 1) > level ) { -// StringBuilder sb = new StringBuilder(); -// -// sb.append( "Layer " ).append( layer++ ).append( " : " ); -// -// TreeSet keys = new TreeSet<>( map.keySet() ); -// for ( String k : keys ) { -//// for ( Entry eSet : translator.entrySet()) { -//// if ( eSet.getValue().equalsIgnoreCase(k) ) { -//// -//// String blockName = eSet.getKey(); -//// sb.append( blockName ).append( ":" ).append( map.get(k) ).append( " " ); -//// -//// break; -//// } -//// } -// sb.append( k ).append( ":" ).append( map.get(k) ).append( " " ); -// } -// -// layers.add( sb.toString() ); -// -// map.clear(); -// } - } - - - { - // print the legend: - StringBuilder sb = new StringBuilder(); - sb.append( "Legend: " ); + if ( (i + 1) >= getMineTargetPrisonBlocks().size() || + getMineTargetPrisonBlocks().get(i + 1).getLocation().getBlockY() != y ) { + + StringBuilder sb = new StringBuilder(); + + sb.append( "Layer " ).append( layer++ ) + .append( " (" ).append( blockCount ).append(")") + .append( " : " ); + + for ( String k : keys ) { + + PrisonBlockStatusData statsBlock = getBlockStats( k ); + + sb.append( statsBlock.getAltColorCode() ) + .append( statsBlock.getAltAlias() ) + .append( Output.get().getColorCodeInfo() ) + .append( ":" ) + .append( statsBlock.getAltCountVirtual() ); + + if ( statsBlock.getAltCountVirtual() != statsBlock.getAltCountPhysical() ) { + sb.append( ":" ) + .append( statsBlock.getAltCountPhysical() ); + } + + sb.append( " " ); + + statsBlock.resetAltValues(); + + } + + layers.add( sb.toString() ); + + blockCount = 0; + } - for ( String k : keys ) { - - PrisonBlockStatusData statsBlock = getBlockStats( k ); - - sb.append( statsBlock.getAltColorCode() ) - .append( statsBlock.getAltAlias() ) - .append( Output.get().getColorCodeInfo() ) - .append( "=" ) - .append( statsBlock.getBlockName() ) - .append( " " ); - - } - -// for ( Entry eSet : translator.entrySet()) { -// String blockName = eSet.getKey(); -// -// String value = eSet.getValue(); -// -// int c = value.charAt(0) % colors.length(); -// String color = "&" + String.valueOf(colors.charAt(c)); -// -// sb -// .append( color ).append( eSet.getValue() ).append( Output.get().getColorCodeDebug() ) -// .append( ":" ).append( blockName ).append( " " ); -// } + } + + + // Print the legend: + { + // print the legend: + StringBuilder sb = new StringBuilder(); + + sb.append( "Legend: " ); + + for ( String k : keys ) { + + PrisonBlockStatusData statsBlock = getBlockStats( k ); + + sb.append( statsBlock.getAltColorCode() ) + .append( statsBlock.getAltAlias() ) + .append( Output.get().getColorCodeInfo() ) + .append( "=" ) + .append( statsBlock.getBlockName() ) + .append( " " ); + + + } - layers.add( sb.toString() ); - } - - if ( !hasAir ) { - removePrisonBlock( air ); - getBlockStats().remove( air.getBlockName() ); - } - - - return layers; + layers.add( sb.toString() ); + + } + + + // If there is no air in the layers, then remove it from the stats: + if ( !hasAir ) { + removePrisonBlock( air ); + getBlockStats().remove( air.getBlockName() ); + } + + + return layers; } @@ -1228,8 +665,7 @@ public void asynchronouslyResetSetup() { int row = 0; for (String command : getResetCommands() ) { row++; -// String formatted = cmd.replace("{player}", prisonPlayer.getName()) -// .replace("{player_uid}", player.uid.toString()); + if ( command.startsWith( "before: " )) { String cmd = command.replace( "before: ", "" ); @@ -1238,8 +674,6 @@ public void asynchronouslyResetSetup() { debugInfo, cmd, row ); cmdTasks.add( cmdTask ); -// PrisonCommandTasks.submitTasks( cmdTask ); - // PrisonAPI.dispatchCommand(cmd); } } @@ -1254,15 +688,12 @@ public void asynchronouslyResetFinalize( List jobResetActions // this will TP anyone out who would otherwise suffocate. I hope! lol - if ( Prison.get().getPlatform().getConfigBooleanTrue( "prison-mines.tp-to-spawn-on-mine-resets" ) ) { - MineTeleportTask teleportTask = new MineTeleportTask( (Mine) this ); - teleportTask.submitTaskSync(); - } + if ( Prison.get().getPlatform().getConfigBooleanTrue( "prison-mines.tp-to-spawn-on-mine-resets" ) ) { + MineTeleportTask teleportTask = new MineTeleportTask( (Mine) this ); + teleportTask.submitTaskSync(); + } -// teleportAllPlayersOut(); -// setStatsTeleport2TimeMS( -// teleportAllPlayersOut( getBounds().getyBlockMax() ) ); // Reset the paging for the next reset: setResetPage( 0 ); @@ -1287,8 +718,7 @@ public void asynchronouslyResetFinalize( List jobResetActions int row = 0; for (String command : getResetCommands() ) { row++; -// String formatted = cmd.replace("{player}", prisonPlayer.getName()) -// .replace("{player_uid}", player.uid.toString()); + if ( command.startsWith( "after: " )) { String cmd = command.replace( "after: ", "" ); @@ -1307,7 +737,6 @@ public void asynchronouslyResetFinalize( List jobResetActions // Broadcast message to all players within a certain radius of this mine: broadcastResetMessageToAllPlayersWithRadius(); -// broadcastResetMessageToAllPlayersWithRadius( MINE_RESET__BROADCAST_RADIUS_BLOCKS ); submitTeleportGlassBlockRemoval(); @@ -1315,16 +744,17 @@ public void asynchronouslyResetFinalize( List jobResetActions // Tie to the command stats mode so it logs it if stats are enabled: if ( PrisonMines.getInstance().getMineManager().isMineStats() || - getCurrentJob().getResetActions().contains( MineResetActions.DETAILS ) ) { - DecimalFormat dFmt = Prison.get().getDecimalFormatInt(); - Output.get().logInfo("&cMine reset: &7" + getTag() + - "&c Blocks: &7" + dFmt.format( getBounds().getTotalBlockCount() ) + - statsMessage() ); + getCurrentJob().getResetActions().contains( MineResetActions.DETAILS ) ) { + + DecimalFormat dFmt = Prison.get().getDecimalFormatInt(); + Output.get().logInfo("&cMine reset: &7" + getTag() + + "&c Blocks: &7" + dFmt.format( getBounds().getTotalBlockCount() ) + + statsMessage() ); } // If part of a chained_resets, then kick off the next reset: if ( jobResetActions != null && jobResetActions.contains( MineResetActions.CHAINED_RESETS ) || - getCurrentJob().getResetActions().contains( MineResetActions.CHAINED_RESETS )) { + getCurrentJob().getResetActions().contains( MineResetActions.CHAINED_RESETS )) { PrisonMines pMines = PrisonMines.getInstance(); pMines.resetAllMinesNext(); @@ -1332,164 +762,43 @@ public void asynchronouslyResetFinalize( List jobResetActions } - public boolean resetAsynchonouslyInitiate( MineResetType resetType ) { - boolean canceled = false; - - if ( isVirtual()) { - canceled = true; - } - else - if ( !isEnabled() ) { - Output.get().logError( - String.format( "MineReset: resetAsynchonouslyInitiate failure: Mine is not enabled. " + - "Ensure world exists. mine= %s ", - getName() )); - canceled = true; - } - else { -// long start = System.currentTimeMillis(); - - // The all-important event - MineResetEvent event = new MineResetEvent(this, resetType); - Prison.get().getEventBus().post(event); + public boolean resetAsynchonouslyInitiate( MineResetType resetType ) { + boolean canceled = false; - canceled = event.isCanceled(); - if (!canceled) { + if ( isVirtual()) { + canceled = true; + } + else + if ( !isEnabled() ) { + Output.get().logError( + String.format( "MineReset: resetAsynchonouslyInitiate failure: Mine is not enabled. " + + "Ensure world exists. mine= %s ", + getName() )); + canceled = true; + } + else { + + // The all-important event + MineResetEvent event = new MineResetEvent(this, resetType); + Prison.get().getEventBus().post(event); + + canceled = event.isCanceled(); + if (!canceled) { + + + if ( Prison.get().getPlatform().getConfigBooleanTrue( "prison-mines.tp-to-spawn-on-mine-resets" ) ) { + MineTeleportTask teleportTask = new MineTeleportTask( (Mine) this ); + teleportTask.submitTaskSync(); + } + + } - - if ( Prison.get().getPlatform().getConfigBooleanTrue( "prison-mines.tp-to-spawn-on-mine-resets" ) ) { - MineTeleportTask teleportTask = new MineTeleportTask( (Mine) this ); - teleportTask.submitTaskSync(); - } - -// try { -// teleportAllPlayersOut(); -//// setStatsTeleport1TimeMS( -//// teleportAllPlayersOut( getBounds().getyBlockMax() ) ); -// -// } catch (Exception e) { -// Output.get().logError("&cMineReset: Failed to TP players out of mine. mine= " + -// getName(), e); -// canceled = true; -// } } - -// long stop = System.currentTimeMillis(); -// setStatsResetTimeMS( stop - start ); - } - - return canceled; + + return canceled; } -// /** -// *

This is the synchronous part of the job that actually updates the blocks. -// * It will only replace what it can within the given allocated milliseconds, -// * then it will terminate and allow this process to re-run, picking up where it -// * left off. -// *

-// * -// *

Paging is what this is doing. Running, and doing what it can within it's -// * limited amount of time, then yielding to any other task, then resuming later. -// * This is a way of running a massive synchronous task, without hogging all the -// * resources and killing the TPS. -// *

-// * -// *

NOTE: The values for MINE_RESET__PAGE_TIMEOUT_CHECK__BLOCK_COUNT and for -// * MINE_RESET__MAX_PAGE_ELASPSED_TIME_MS are set to arbitrary values and may not -// * be the correct values. They may be too large and may have to be adjusted to -// * smaller values to better tune the process. -// *

-// * -// */ -// private void resetAsynchonouslyUpdate( boolean paged ) { -// if ( isVirtual() ) { -// // ignore: -// } -// else -// if ( !isEnabled() ) { -// Output.get().logError( -// String.format( "MineReset: resetAsynchonouslyUpdate failure: Mine is not enabled. " + -// "Ensure world exists. mine= %s ", -// getName() )); -// } -// else { -// World world = getBounds().getCenter().getWorld(); -// -// -// long start = System.currentTimeMillis(); -// -//// boolean isFillMode = PrisonMines.getInstance().getConfig().fillMode; -// -// int blocksPlaced = 0; -// long elapsed = 0; -// -// int i = getResetPosition(); -// for ( ; i < getMineTargetPrisonBlocks().size(); i++ ) -// { -// MineTargetPrisonBlock target = getMineTargetPrisonBlocks().get(i); -// -// Location targetBlock = new Location(world, -// target.getBlockKey().getX(), target.getBlockKey().getY(), -// target.getBlockKey().getZ()); -// -//// if (!isFillMode || isFillMode && targetBlock.getBlockAt().isEmpty()) { -//// } -// if ( isUseNewBlockModel() ) { -// -// targetBlock.getBlockAt().setPrisonBlock( (PrisonBlock) target.getPrisonBlock() ); -// } -// else { -// -// targetBlock.getBlockAt().setType( ((BlockOld) target.getPrisonBlock()).getType() ); -// } -// -// /** -// * If paged is enabled... -// * -// * About every 250 blocks, or so, check to see if the current wall time -// * spent is greater than -// * the threshold. If it is greater, then end the update and let it resubmit. -// * It does not matter how many blocks were actually updated during this "page", -// * but what it is more important is the actual elapsed time. This is to allow other -// * processes to get processing time and to eliminate possible lagging. -// */ -// if ( paged && i % getResetPageTimeoutCheckBlockCount() == 0 ) { -// elapsed = System.currentTimeMillis() - start; -// if ( elapsed > getResetPageMaxPageElapsedTimeMs() ) { -// -// break; -// } -// } -// } -// -// blocksPlaced = i - getResetPosition(); -// -// if ( PrisonMines.getInstance().getMineManager().isMineStats() ) { -// -// // Only print these details if stats is enabled: -// Output.get().logInfo( "MineReset.resetAsynchonouslyUpdate() :" + -// " page " + getResetPage() + -// " blocks = " + blocksPlaced + " elapsed = " + elapsed + -// " ms TPS: " + Prison.get().getPrisonTPS().getAverageTPSFormatted() ); -// } -// -// setResetPosition( i ); -// -// setResetPage( getResetPage() + 1 ); -// -// long time = System.currentTimeMillis() - start; -// setStatsBlockUpdateTimeMS( time + getStatsBlockUpdateTimeMS() ); -// setStatsResetTimeMS( time + getStatsResetTimeMS() ); -// -// -// setStatsResetPages( getStatsResetPages() + 1 ); -// setStatsResetPageBlocks( getStatsResetPageBlocks() + blocksPlaced ); -// setStatsResetPageMs( getStatsResetPageMs() + time ); -// } -// -// } - /** @@ -1502,25 +811,9 @@ public boolean resetAsynchonouslyInitiate( MineResetType resetType ) { */ public void refreshBlockBreakCountUponStartup( long delay) { - // if the mine is being used in a unit test, then it will not have a value for - // bounds and therefore do not run the task. -// if ( getBounds() != null ) { - -// OnStartupRefreshBlockBreakCountSyncTask.getInstance().submit( delay ); - -// OnStartupRefreshBlockBreakCountSyncTask.getInstance().submit( this, delay ); - -// OnStartupRefreshBlockBreakCountAsyncTask cabAsyncTask = new OnStartupRefreshBlockBreakCountAsyncTask(this); -// -// // Must run synchronously!! -// submitSyncTask( cabAsyncTask ); -// //submitAsyncTask( cabAsyncTask ); -// } + // not used } -// protected void resetAirCountStartupAsyncTask() { -// refreshAirCountAsyncTask( false ); -// } /** *

This function performs the air count and should be ran as an async task. @@ -1539,47 +832,47 @@ protected boolean refreshAirCountSyncTaskCheckBeforeSubmit() { boolean results = false; - if ( isVirtual() ) { - // ignore: - } - else - if ( !isEnabled() ) { - Output.get().logError( - String.format( "MineReset: refreshAirCountAsyncTask failure: Mine is not enabled. " + - "Ensure world exists. mine= %s ", - getName() )); - } - else if ( getPrisonBlocks().size() == 1 && - getPrisonBlocks().get( 0 ).equals( PrisonBlock.IGNORE ) ) { - - // This mine is set to ignore all blocks when trying to do a reset, - // so for now ignore the types and just set air count to zero. - // Basically, this mine, if using natural spawned landscape, may contain blocks that are - // not registered and tracked within prison, and hence will report incorrect errors. - setAirCount( 0 ); - } - else { - Optional worldOptional = getWorld(); - World world = worldOptional.get(); - - if ( world == null ) { + if ( isVirtual() ) { + // ignore: + } + else + if ( !isEnabled() ) { Output.get().logError( - String.format( "MineReset: refreshAirCountAsyncTask failure: The world is invalid and " + - "cannot be located. mine= %s worldName=%s ", - getName(), getWorldName() )); - - + String.format( "MineReset: refreshAirCountAsyncTask failure: Mine is not enabled. " + + "Ensure world exists. mine= %s ", + getName() )); + } + else if ( getPrisonBlocks().size() == 1 && + getPrisonBlocks().get( 0 ).equals( PrisonBlock.IGNORE ) ) { + + // This mine is set to ignore all blocks when trying to do a reset, + // so for now ignore the types and just set air count to zero. + // Basically, this mine, if using natural spawned landscape, may contain blocks that are + // not registered and tracked within prison, and hence will report incorrect errors. + setAirCount( 0 ); } else { + Optional worldOptional = getWorld(); + World world = worldOptional.get(); - // This means we can actually go ahead and perform the air-counts and so the - // actual job can be submitted: - return true; + if ( world == null ) { + Output.get().logError( + String.format( "MineReset: refreshAirCountAsyncTask failure: The world is invalid and " + + "cannot be located. mine= %s worldName=%s ", + getName(), getWorldName() )); + + + } + else { + + // This means we can actually go ahead and perform the air-counts and so the + // actual job can be submitted: + return true; + } + } - - } - - return results; + + return results; } @@ -1594,25 +887,15 @@ else if ( getPrisonBlocks().size() == 1 && public List refreshAirCountSyncTaskBuildLocations() { List locations = new ArrayList<>(); -// long start = System.currentTimeMillis(); Optional worldOptional = getWorld(); World world = worldOptional.get(); - - { -// boolean containsCustomBlocks = getPrisonBlockTypes().contains( PrisonBlockType.CustomItems ); - + { // Reset the target block lists: clearMineTargetPrisonBlocks(); - -// int airCount = 0; -// int errorCount = 0; - - - int yMin = getBounds().getyBlockMin(); int yMax = getBounds().getyBlockMax(); @@ -1623,9 +906,6 @@ public List refreshAirCountSyncTaskBuildLocations() { int zMax = getBounds().getzBlockMax(); - -// StringBuilder sb = new StringBuilder(); - for (int y = yMax; y >= yMin; y--) { for (int x = xMin; x <= xMax; x++) { for (int z = zMin; z <= zMax; z++) { @@ -1645,74 +925,13 @@ public List refreshAirCountSyncTaskBuildLocations() { locations.add( targetLocation ); - - -// try { -// -// Block tBlock = targetBlock.getBlockAt( containsCustomBlocks ); -// -// -// -// -// PrisonBlock pBlock = tBlock.getPrisonBlock(); -// -// if ( pBlock != null ) { -// -// // Increment the mine's block count. This block is one of the control blocks: -// addMineTargetPrisonBlock( incrementResetBlockCount( pBlock ), targetBlock ); -// -// } -// -// if ( pBlock == null || pBlock.isAir() ) { -// airCount++; -// } -// } -// catch ( Exception e ) { -// // Updates to the "world" should never be ran async. Upon review of the above -// // that gets the location and block, causes the chunk to load, if it is not loaded, -// // and if there is an entity in that loaded chunk it will throw an exception: -// // java.lang.IllegalStateException: Asynchronous entity world add! -// // If there are no entities, it will be fine, but they could cause issues with async -// // access of unloaded chunks. -// String coords = String.format( "%d.%d.%d ", x, y, z ); -// if ( errorCount ++ == 0 ) { -// String message = String.format( -// "MineReset.refreshAirCountAsyncTask: Error counting air blocks: " + -// "Mine=%s coords=%s Error: %s ", getName(), coords, e.getMessage() ); -// if ( e.getMessage() != null && e.getMessage().contains( "Asynchronous entity world add" )) { -// Output.get().logWarn( message, e ); -// } else { -// Output.get().logWarn( message, e ); -// } -// -// } -// else if ( errorCount <= 20 ) { -// sb.append( coords ); -// } -// } } } } -// if ( errorCount > 0 ) { -// String message = String.format( -// "MineReset.refreshAirCountAsyncTask: Error counting air blocks: Mine=%s: " + -// "errorCount=%d blocks%s : %s", getName(), errorCount, -// (errorCount > 20 ? "(first 20)" : ""), -// sb.toString() ); -// Output.get().logWarn( message ); -// } -// -// -// setAirCount( airCount ); - -// long stop = System.currentTimeMillis(); -// long elapsed = stop - start; -// setAirCountElapsedTimeMs( elapsed ); -// setAirCountTimestamp( stop ); } - return locations; + return locations; } @@ -1720,7 +939,6 @@ public void refreshAirCountSyncTaskSetLocation( Location targetLocation, OnStartupRefreshBlockBreakCountSyncTask stats ) { try { -// Location targetBlock = new Location(world, x, y, z); boolean containsCustomBlocks = getPrisonBlockTypes().contains( PrisonBlockType.CustomItems ) || @@ -1757,8 +975,6 @@ public void refreshAirCountSyncTaskSetLocation( Location targetLocation, // java.lang.IllegalStateException: Asynchronous entity world add! // If there are no entities, it will be fine, but they could cause issues with async // access of unloaded chunks. -// String coords = String.format( "%d.%d.%d ", -// targetLocation.getBlockX(), targetLocation.getBlockY(), targetLocation.getBlockZ() ); String coords = targetLocation.toBlockCoordinates(); @@ -1811,11 +1027,10 @@ private void scanAllBlocksForUpdates() { i++; -; targetBlock.setCheckAir( false ); + targetBlock.setCheckAir( false ); targetBlock.setCheckSame( false ); try { -// Location targetBlock = new Location(world, x, y, z); boolean containsCustomBlocks = getPrisonBlockTypes().contains( PrisonBlockType.CustomItems ) || @@ -1851,8 +1066,6 @@ else if ( pBlock.getBlockName().equalsIgnoreCase( targetBlockName) ) { } - - } catch ( Exception e ) { @@ -2014,9 +1227,6 @@ public double getPercentRemainingBlockCount() { int totalCount = getBounds().getTotalBlockCount(); int remainingCount = getRemainingBlockCount(); double percentRemaining = (totalCount == 0d ? 0d : (remainingCount * 100d) / (double) totalCount); -// double remainingBlocksP = (totalCount - getAirCount()) * 100d; -// double originalCount = totalCount - getAirCountOriginal(); -// double percentRemaining = (originalCount == 0d ? 0d : remainingBlocksP / originalCount); return percentRemaining; } @@ -2059,134 +1269,8 @@ else if ( getPercentRemainingBlockCount() > getSkipResetPercent() ) { MinePagedResetAsyncTask resetTask = new MinePagedResetAsyncTask( (Mine) this, MineResetType.normal ); resetTask.submitTaskAsync(); -// resetAsynchonously(); } -// public void refreshMineAsyncResubmitTask() { -// -// // Mine reset here: -// resetAsynchonously(); -// } - - - -// private PrisonBlock randomlySelectPrisonBlock( Random random, int currentLevel ) { -// -// int targetBlockPosition = getMineTargetPrisonBlocks().size(); -// -// PrisonBlock prisonBlock = Prison.get().getPlatform().getPrisonBlock( "AIR" ); -// -// -// // this fallbackBlock field will provide a valid block that can be used when all other -// // blocks have failed to be matched due to constraints not aligning with the random chance. -// // As a result of failing to find a block, would result in an AIR block being used instead. -// PrisonBlock fallbackBlock = null; -// -// -// // If a chosen block was skipped, try to find another block, but try no more than 10 times -// // to prevent a possible endless loop. Side effects of failing to find a block in 10 attempts -// // would be an air block. -// boolean success = false; -// int attempts = 0; -// while ( !success && attempts++ < 10 ) { -// double chance = random.nextDouble() * 100.0d; -// -// for (PrisonBlock block : getPrisonBlocks()) { -// boolean isBlockEnabled = block.isBlockConstraintsEnbled( currentLevel, targetBlockPosition ); -// -// if ( fallbackBlock == null && isBlockEnabled && !block.isAir() ) { -// fallbackBlock = block; -// } -// -// if ( chance <= block.getChance() && isBlockEnabled ) { -// -// // If this block is chosen and it was not skipped, then use this block and exit. -// // Otherwise the chance will be recalculated and tried again to find a valid block, -// // since the odds have been thrown off... -// prisonBlock = block; -// -// // stop trying to locate a block so success will terminate the search: -// success = true; -// -// break; -// } else { -// chance -= block.getChance(); -// } -// } -// -// if ( !success && fallbackBlock != null ) { -// prisonBlock = fallbackBlock; -// success = true; -// } -// } -// return prisonBlock; -// } - - // Obsolete... the old block model: -// private BlockOld randomlySelectBlock( Random random, int currentLevel ) { -// -// int targetBlockPosition = getMineTargetPrisonBlocks().size(); -// -// BlockOld results = BlockOld.AIR; -// -// -// // this fallbackBlock field will provide a valid block that can be used when all other -// // blocks have failed to be matched due to constraints not aligning with the random chance. -// // As a result of failing to find a block, would result in an AIR block being used instead. -// BlockOld fallbackBlock = null; -// -// -// -// // If a chosen block was skipped, try to find another block, but try no more than 10 times -// // to prevent a possible endless loop. Side effects of failing to find a block in 10 attempts -// // would be an air block. -// boolean success = false; -// int attempts = 0; -// while ( !success && attempts++ < 10 ) { -// double chance = random.nextDouble() * 100.0d; -// -// for (BlockOld block : getBlocks()) { -// boolean isBlockEnabled = block.isBlockConstraintsEnbled( currentLevel, targetBlockPosition ); -// -// if ( fallbackBlock == null && isBlockEnabled && !block.isAir() ) { -// fallbackBlock = block; -// } -// -// if ( chance <= block.getChance() && isBlockEnabled ) { -// -// // If this block is chosen and it was not skipped, then use this block and exit. -// // Otherwise the chance will be recalculated and tried again to find a valid block, -// // since the odds have been thrown off... -// results = block; -// -// // stop trying to locate a block so success will terminate the search: -// success = true; -// -// break; -// } else { -// chance -= block.getChance(); -// } -// } -// } -// -// if ( !success && fallbackBlock != null ) { -// results = fallbackBlock; -// success = true; -// } -// -//// for (BlockOld block : getBlocks()) { -//// if (block.checkConstraints( currentLevel, targetBlockPosition ) && -//// chance <= block.getChance() && -//// (block.getConstraintMax() == 0 || block.getResetBlockCount() < block.getConstraintMax())) { -//// results = block; -//// break; -//// } else { -//// chance -= block.getChance(); -//// } -//// } -// return results; -// } - private void constraintsApplyMin() { @@ -2214,66 +1298,58 @@ private void constraintsApplyMin() { private void constraintsApplyMin( PrisonBlockStatusData block ) { - if ( block.getConstraintMin() > 0 && block.getBlockPlacedCount() < block.getConstraintMin() ) { - - int maxAttempts = (block.getConstraintMin() - block.getBlockPlacedCount()) + 3; - - for ( int i = 0; i < maxAttempts && block.getBlockPlacedCount() < block.getConstraintMin(); i++ ) { - -// int maxSize = getMineTargetPrisonBlocks().size(); - - - - // Get an unmatched block in the block's range (not the same block): - int blockPos = block.getRandomBlockPositionInRangeUnmatched( getMineTargetPrisonBlocks() ); - - -// int rangeLow = block.getRangeBlockCountLowLimit(); -// int rangeHigh = block.getRangeBlockCountHighLimit(); - - // Each block has a valid range in which it can spawn in the mine. This range - // is honored by using the rangeHigh and rangeLow values. -// int rndPos = ((int) Math.round( Math.random() * (rangeHigh - rangeLow) )) + rangeLow; - - if ( blockPos > -1 && blockPos < getMineTargetPrisonBlocks().size() ) { - - MineTargetPrisonBlock targetBlock = getMineTargetPrisonBlocks().get( blockPos ); - - if ( targetBlock != null && - targetBlock.getPrisonBlock().getConstraintMin() == 0 && - targetBlock.getPrisonBlock().getConstraintMax() == 0 && - !targetBlock.getPrisonBlock().getBlockName().equalsIgnoreCase( - block.getBlockName() ) ) { - - // decrement the block count on the block being removed: - if ( targetBlock.getPrisonBlock().isAir() ) { - - // Need to remove one from the air count fields: - setAirCountOriginal( getAirCountOriginal() - 1 ); - setAirCount( getAirCount() - 1 ); - - } - else { - targetBlock.getPrisonBlock().decrementResetBlockCount(); - } - - - // Add the new block and increment it's count: - targetBlock.setPrisonBlock( block ); - - // If the reset is placing an AiR block, then mark the block as - // setAirBroke() and setMined() to ensure they are not counted or - // processed during normal mining operations, or through - // MineSweeper checks. - if ( block.isAir() ) { - targetBlock.setAirBroke( true ); - targetBlock.setMined( true ); - } - block.incrementResetBlockCount(); - } - } - } - } + if ( block.getConstraintMin() > 0 && block.getBlockPlacedCount() < block.getConstraintMin() ) { + + int maxAttempts = (block.getConstraintMin() - block.getBlockPlacedCount()) + 3; + + for ( int i = 0; i < maxAttempts && block.getBlockPlacedCount() < block.getConstraintMin(); i++ ) { + + // Get an unmatched block in the block's range (not the same block): + int blockPos = block.getRandomBlockPositionInRangeUnmatched( getMineTargetPrisonBlocks() ); + + // Each block has a valid range in which it can spawn in the mine. This range + // is honored by using the rangeHigh and rangeLow values. + // int rndPos = ((int) Math.round( Math.random() * (rangeHigh - rangeLow) )) + rangeLow; + + if ( blockPos > -1 && blockPos < getMineTargetPrisonBlocks().size() ) { + + MineTargetPrisonBlock targetBlock = getMineTargetPrisonBlocks().get( blockPos ); + + if ( targetBlock != null && + targetBlock.getPrisonBlock().getConstraintMin() == 0 && + targetBlock.getPrisonBlock().getConstraintMax() == 0 && + !targetBlock.getPrisonBlock().getBlockName().equalsIgnoreCase( + block.getBlockName() ) ) { + + // decrement the block count on the block being removed: + if ( targetBlock.getPrisonBlock().isAir() ) { + + // Need to remove one from the air count fields: + setAirCountOriginal( getAirCountOriginal() - 1 ); + setAirCount( getAirCount() - 1 ); + + } + else { + targetBlock.getPrisonBlock().decrementResetBlockCount(); + } + + + // Add the new block and increment it's count: + targetBlock.setPrisonBlock( block ); + + // If the reset is placing an AiR block, then mark the block as + // setAirBroke() and setMined() to ensure they are not counted or + // processed during normal mining operations, or through + // MineSweeper checks. + if ( block.isAir() ) { + targetBlock.setAirBroke( true ); + targetBlock.setMined( true ); + } + block.incrementResetBlockCount(); + } + } + } + } } /** @@ -2282,8 +1358,8 @@ private void constraintsApplyMin( PrisonBlockStatusData block ) */ public void enableTracer(MineResetType resetType) { - // First clear the mine: - clearMine( resetType ); + // First clear the mine: + clearMine( resetType ); // Prison.get().getPlatform().enableMineTracer( // getWorldName(), @@ -2305,39 +1381,39 @@ public void enableTracer(MineResetType resetType) { */ public void adjustSize( Edges edge, int amount ) { - // First clear the mine: - clearMine( MineResetType.clear ); - - // if amount is zero, then just refresh the liner: - - if ( amount < 0 ) { - while ( amount++ < 0 ) { - - new MineLinerBuilder( (Mine) this, edge, LinerPatterns.repair, false ); - - Bounds newBounds = new Bounds( getBounds(), edge, -1 ); - setBounds( newBounds ); - - new MineLinerBuilder( (Mine) this, edge, LinerPatterns.repair, false ); - } - } - else if ( amount > 0 ) { - new MineLinerBuilder( (Mine) this, edge, LinerPatterns.repair, false ); - - Bounds newBounds = new Bounds( getBounds(), edge, amount ); - setBounds( newBounds ); - } - - // Rebuild the liner if it exists: - for ( Edges targtEdge : Edges.values() ) { + // First clear the mine: + clearMine( MineResetType.clear ); - if ( getLinerData().hasEdge( targtEdge ) ) { - - LinerPatterns pattern = LinerPatterns.fromString( getLinerData().getEdge( targtEdge ) ); - boolean force = getLinerData().getForce( targtEdge ); - - new MineLinerBuilder( (Mine) this, targtEdge, pattern, force ); - } + // if amount is zero, then just refresh the liner: + + if ( amount < 0 ) { + while ( amount++ < 0 ) { + + new MineLinerBuilder( (Mine) this, edge, LinerPatterns.repair, false ); + + Bounds newBounds = new Bounds( getBounds(), edge, -1 ); + setBounds( newBounds ); + + new MineLinerBuilder( (Mine) this, edge, LinerPatterns.repair, false ); + } + } + else if ( amount > 0 ) { + new MineLinerBuilder( (Mine) this, edge, LinerPatterns.repair, false ); + + Bounds newBounds = new Bounds( getBounds(), edge, amount ); + setBounds( newBounds ); + } + + // Rebuild the liner if it exists: + for ( Edges targtEdge : Edges.values() ) { + + if ( getLinerData().hasEdge( targtEdge ) ) { + + LinerPatterns pattern = LinerPatterns.fromString( getLinerData().getEdge( targtEdge ) ); + boolean force = getLinerData().getForce( targtEdge ); + + new MineLinerBuilder( (Mine) this, targtEdge, pattern, force ); + } } // Finally trace the mine: @@ -2347,15 +1423,15 @@ else if ( amount > 0 ) { public void moveMine( Edges edge, int amount ) { - MineMover moveMine = new MineMover(); - moveMine.moveMine( (Mine) this, edge, amount ); + MineMover moveMine = new MineMover(); + moveMine.moveMine( (Mine) this, edge, amount ); } public void clearMine( MineResetType resetType ) { - MineTracerBuilder tracerBuilder = new MineTracerBuilder(); - tracerBuilder.clearMine( (Mine) this, resetType ); + MineTracerBuilder tracerBuilder = new MineTracerBuilder(); + tracerBuilder.clearMine( (Mine) this, resetType ); } @@ -2381,28 +1457,19 @@ private void addMineTargetPrisonBlock( PrisonBlockStatusData block, Location tar } } -// private void addMineTargetPrisonBlock( PrisonBlockStatusData block, int x, int y, int z, boolean isEdge ) { -// -// MineTargetPrisonBlock mtpb = new MineTargetPrisonBlock( block, getWorld().get(), x, y, z, isEdge ); -// -// getMineTargetPrisonBlocks().add( mtpb ); -// getMineTargetPrisonBlocksMap().put( mtpb.getBlockKey(), mtpb ); -// } private void clearMineTargetPrisonBlocks() { + + // Instead of clearing the collections, set them to null so that way if + // other reference exist, they will be able to continue to use them + // until the release the references. + + synchronized ( getMineStateMutex() ) { + + mineTargetPrisonBlocks = null; + mineTargetPrisonBlocksMap = null; + } - // Instead of clearing the collections, set them to null so that way if - // other reference exist, they will be able to continue to use them - // until the release the references. - - synchronized ( getMineStateMutex() ) { - - mineTargetPrisonBlocks = null; - mineTargetPrisonBlocksMap = null; - } - -// getMineTargetPrisonBlocks().clear(); -// getMineTargetPrisonBlocksMap().clear(); } @@ -2437,30 +1504,6 @@ public MineTargetPrisonBlock getTargetPrisonBlock( PrisonBlock block ) { } - -// public String getTargetPrisonBlockName( Block block ) { -// String results = "AIR"; -// -// if ( block != null ) { -// PrisonBlock pBlock = block.getPrisonBlock(); -// if ( pBlock != null ) { -// -// results = pBlock.getBlockName(); -// } -// -// if ( "AIR".equalsIgnoreCase( results ) ) { -// MineTargetPrisonBlock targetBlock = getTargetPrisonBlock( block ); -// -// if ( targetBlock != null ) { -// results = targetBlock.getPrisonBlock().getBlockName(); -// } -// } -// } -// -// return results; -// } - - public int getResetPage() { @@ -2617,6 +1660,5 @@ public boolean isMineSweeperSubmitted() { public void setMineSweeperSubmitted( boolean mineSweeperSubmitted ) { this.mineSweeperSubmitted = mineSweeperSubmitted; } - } diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineScheduler.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineScheduler.java index 3f3d94ee3..272c1237e 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineScheduler.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineScheduler.java @@ -46,7 +46,6 @@ public abstract class MineScheduler */ private transient List jobWorkflow; private transient Stack jobStack; -// private transient MineJob currentJob; private transient Integer taskId = null; private transient long mineResetStartTimestamp; @@ -69,11 +68,11 @@ public MineScheduler() { */ @Override protected void initialize() { - super.initialize(); - - // need to rebuild JobWorkflow if reset time ever changes: - setJobWorkflow( initializeJobWorkflow() ); - resetJobStack(); + super.initialize(); + + // need to rebuild JobWorkflow if reset time ever changes: + setJobWorkflow( initializeJobWorkflow() ); + resetJobStack(); } public enum JobType { @@ -280,7 +279,6 @@ protected List initializeJobWorkflow( double resetTime, boolean include if ( includeMessages ) { // Need to ensure that the reset warning times are sorted in ascending order: -// ArrayList rwTimes = PrisonMines.getInstance().getConfig().resetWarningTimes; Collections.sort( resetWarningTimes ); double total = 0; @@ -352,10 +350,10 @@ public void run() return; } - boolean skip = !forced && - isSkipResetEnabled() && - getPercentRemainingBlockCount() >= getSkipResetPercent() && - getSkipResetBypassCount() < getSkipResetBypassLimit(); + boolean skip = !forced && + isSkipResetEnabled() && + getPercentRemainingBlockCount() >= getSkipResetPercent() && + getSkipResetBypassCount() < getSkipResetBypassLimit(); // Output.get().logInfo( "Mine Reset: Run: Mine= %s action= %s skip= %s forced= %s ", // this.getName(), getCurrentJob().getAction().name(), @@ -395,9 +393,8 @@ public void run() MinePagedResetAsyncTask resetTask = new MinePagedResetAsyncTask( (Mine) this, MineResetType.normal, resetActions, resetScheduleType ); - resetTask.submitTaskAsync(); + resetTask.submitTaskAsync(); -// resetAsynchonously(); } else { incrementSkipResetBypassCount(); @@ -406,35 +403,11 @@ public void run() break; -// case RESET_SYNC: -// // synchronous reset. Will be phased out in the future? -// if ( !skip ) { -// -// List resetActions = getCurrentJob().getResetActions(); -// -// MinePagedResetAsyncTask resetTask = -// new MinePagedResetAsyncTask( (Mine) this, MineResetType.normal, resetActions ); -// -// resetTask.submitTaskAsync(); -// -//// resetSynchonously(); -// } else { -// incrementSkipResetBypassCount(); -// } -// -// break; default: break; } -// if ( getCurrentJob().getAction() == MineJobAction.RESET ) { -// resetSynchonously(); -// } else { -// // Send reset message: -// broadcastPendingResetMessageToAllPlayersWithRadius(getCurrentJob(), MINE_RESET_BROADCAST_RADIUS_BLOCKS ); -// } -// // this may be an issue for disabled resetTimes... may still need to be submitted? // disabled resets may not need to be submitted at all. @@ -466,9 +439,9 @@ private void checkWorld() "This is serious. &aworldName= " + getWorldName() ); } else { - World world = worldOptional.get(); - - setWorld( world ); + World world = worldOptional.get(); + + setWorld( world ); } } } @@ -585,34 +558,6 @@ public int processBlockBreakEventCommands( PrisonBlock prisonBlock, return blockEventsRan; } - -// /** -// *

This function checks if the block break event should execute a -// * given command or not. If it needs to, then it will submit them to run as -// * a task instead of running them in this thread. -// *

-// * -// * @param blockCount -// * @param player -// */ -// @Deprecated -// public void processBlockBreakEventCommands( int blockCount, Player player, -// BlockEventType eventType, String triggered ) { -// -// if ( getBlockEvents().size() > 0 ) { -// Random random = new Random(); -// -// for ( int i = 0; i < blockCount; i ++ ) { -// -// for ( MineBlockEvent blockEvent : getBlockEvents() ) { -// double chance = random.nextDouble() * 100; -// -// processBlockEventDetails( player, null, eventType, chance, blockEvent, triggered ); -// } -// -// } -// } -// } private int processBlockEventDetails( Player player, PrisonBlock prisonBlock, MineTargetPrisonBlock targetBlock, BlockEventType eventType, @@ -694,60 +639,6 @@ private int processBlockEventDetails( Player player, PrisonBlock prisonBlock, cmdTasks.add( cmdTask ); - -// cmdTask.submitCommandTask( player, blockEvent.getCommand(), blockEvent.getTaskMode() ); - -// { -// -// String formatted = blockEvent.getCommand() -// .replace( "{msg}", "prison utils msg {player} " ) -// .replace( "{broadcast}", "prison utils broadcast " ) -// .replace("{player}", player.getName()) -// .replace("{player_uid}", player.getUUID().toString()); -// -// // Split multiple commands in to a List of individual tasks: -// List tasks = new ArrayList<>( -// Arrays.asList( formatted.split( ";" ) )); -// -// -// if ( tasks.size() > 0 ) { -// -// String errorMessage = "BlockEvent: Player: " + player.getName(); -// -// boolean playerTask = blockEvent.getTaskMode() == TaskMode.inlinePlayer || -// blockEvent.getTaskMode() == TaskMode.syncPlayer; -// -// PrisonDispatchCommandTask task = -// new PrisonDispatchCommandTask( tasks, errorMessage, -// player, playerTask ); -// -// -// switch ( blockEvent.getTaskMode() ) -// { -// case inline: -// case inlinePlayer: -// // Don't submit, but run it here within this thread: -// task.run(); -// break; -// -// case sync: -// case syncPlayer: -// //case "async": // async will cause failures so run as sync: -// -// // submit task: -// @SuppressWarnings( "unused" ) -// int taskId = PrisonTaskSubmitter.runTaskLater(task, 0); -// break; -// -// default: -// break; -// } -// -// } -// -// -//// PrisonAPI.dispatchCommand(formatted); -// } } } @@ -787,9 +678,6 @@ public boolean checkZeroBlockReset() { * triggered by a player. * */ -// public void manualReset() { -// manualReset( MineResetScheduleType.FORCED ); -// } public void manualReset( MineResetScheduleType resetType ) { if ( !isVirtual() ) { @@ -861,40 +749,6 @@ private void manualReset( MineResetScheduleType resetType, double delayActionSec setMineResetStartTimestamp( System.currentTimeMillis() ); -// // Lock the mine's mutex if it's still minable. Otherwise skip it since the -// // state has been incremented by one already. -// if ( getMineStateMutex().isMinable() ) { -// -// getMineStateMutex().setMineStateResetStart(); -// } -// else if ( getMineStateMutex().getMineStateSn() > 1 ) { -// -// // synchronizing on the mutex this will allow only one thread to be -// // processed at a time, which will weed out extra threads from being -// // wrongfully shutdown. Based upon this "technique" the last thread to -// // be paused by this synchronized block will be the one that will actually -// // initiate the reset. -// if ( getMineStateMutex().getMineStateSn() > 1 ) { -// -// // This may be a double submission sinc the mineStateSn should only be 1 at this -// // point. So release this lock and shutdown this duplicate submission. -// getMineStateMutex().setMineStateResetFinished(); -// -// // duplicate reset request, so exit... -// return; -// } -// -// } - - - - // cancel existing job: - // Warning... do not cancel current tasks. It may be breaking the - // last block. If another thread is initiating a reset then it won't make it to - // this part of the code. -// if ( getTaskId() != null ) { -// PrisonTaskSubmitter.cancelTask( getTaskId() ); -// } // Clear jobStack and set currentJob to run the RESET with zero delay: getJobStack().clear(); diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineSweeperTask.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineSweeperTask.java index 8d174f640..5bff879f9 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineSweeperTask.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineSweeperTask.java @@ -21,8 +21,6 @@ public void run() { this.mine.submitAsyncTask( callbackAsync, 0 ); } - } - } diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineTasks.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineTasks.java index 282d3d05d..d9b0f1f81 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineTasks.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineTasks.java @@ -24,7 +24,6 @@ public abstract class MineTasks public MineTasks() { super(); - } @@ -41,31 +40,22 @@ public MineTasks() { */ @Override protected void initialize() { - super.initialize(); + super.initialize(); } - /** * This should be used to submit async tasks. * * @param callbackAsync */ -// @Override -// public int submitAsyncTask( PrisonRunnable callbackAsync ) { -// return submitAsyncTask( callbackAsync, 0L ); -// } @Override public int submitAsyncTask( PrisonRunnable callbackAsync, long delay ) { return Prison.get().getPlatform().getScheduler().runTaskLaterAsync( callbackAsync, getResetPagePageSubmitDelayTicks() + delay ); } -// @Override -// public int submitSyncTask( PrisonRunnable callbackSync ) { -// return submitSyncTask( callbackSync, 0L ); -// } @Override public int submitSyncTask( PrisonRunnable callbackSync, long delay ) { @@ -93,38 +83,39 @@ public int submitSyncTask( PrisonRunnable callbackSync, long delay ) { */ @Override public long teleportAllPlayersOut() { - long start = System.currentTimeMillis(); - - if ( isVirtual() ) { - return 0; - } - - World world = getBounds().getCenter().getWorld(); - - try { - if ( isEnabled() && world != null ) { - List players = (world.getPlayers() != null ? world.getPlayers() : - Prison.get().getPlatform().getOnlinePlayers()); - for (Player player : players) { - if ( getBounds().withinIncludeTopBottomOfMine(player.getLocation()) ) { - - teleportPlayerOut(player); - } - } - } - - } - catch (Exception e) { - Output.get().logError("&cMineReset: Failed to TP players out of mine. mine= " + - getName(), e); + long start = System.currentTimeMillis(); + + if ( isVirtual() ) { + return 0; + } + + World world = getBounds().getCenter().getWorld(); + + try { + if ( isEnabled() && world != null ) { + List players = (world.getPlayers() != null ? world.getPlayers() : + Prison.get().getPlatform().getOnlinePlayers()); + for (Player player : players) { + if ( getBounds().withinIncludeTopBottomOfMine(player.getLocation()) ) { + + teleportPlayerOut(player); + } + } + } + + } + catch (Exception e) { + Output.get().logError("&cMineReset: Failed to TP players out of mine. mine= " + + getName(), e); } - return System.currentTimeMillis() - start; + + return System.currentTimeMillis() - start; } @Override public void teleportPlayerOut(Player player) { - teleportPlayerOut( player, "spawn" ); + teleportPlayerOut( player, "spawn" ); } /** @@ -155,78 +146,56 @@ public void teleportPlayerOut(Player player) { */ @Override public Location teleportPlayerOut(Player player, String targetLocation) { - Location tpTargetLocation = null; - - if ( isVirtual() ) { - // ignore: - } - else - if ( !isEnabled() ) { - player.sendMessage( - String.format( "&7MineReset: Teleport failure: Mine is not enabled. " + - "Ensure world exists. mine= &3%s ", - getName() )); - } - else { -// Location altTp = alternativeTpLocation(); - tpTargetLocation = "spawn".equalsIgnoreCase( targetLocation ) && isHasSpawn() ? - getSpawn() : alternativeTpLocation(); - - // Player needs to stand on something. If block below feet is air, change it to a - // glass block: - Location targetGround = new Location( tpTargetLocation ); - targetGround.setY( tpTargetLocation.getBlockY() - 1 ); - - Block pBlock = targetGround.getBlockAt(); - if ( pBlock.isEmpty() ) { - pBlock.setPrisonBlock( PrisonBlock.GLASS );; + Location tpTargetLocation = null; + + if ( isVirtual() ) { + // ignore: + } + else + if ( !isEnabled() ) { + player.sendMessage( + String.format( "&7MineReset: Teleport failure: Mine is not enabled. " + + "Ensure world exists. mine= &3%s ", + getName() )); } - - player.teleport( tpTargetLocation ); - - - -// PrisonMines.getInstance().getMinesMessages().getLocalizable("teleported") -// .withReplacements(this.getName()).sendTo(player); - } - - return tpTargetLocation; + else { + tpTargetLocation = "spawn".equalsIgnoreCase( targetLocation ) && isHasSpawn() ? + getSpawn() : alternativeTpLocation(); + + // Player needs to stand on something. If block below feet is air, change it to a + // glass block: + Location targetGround = new Location( tpTargetLocation ); + targetGround.setY( tpTargetLocation.getBlockY() - 1 ); + + Block pBlock = targetGround.getBlockAt(); + if ( pBlock.isEmpty() ) { + pBlock.setPrisonBlock( PrisonBlock.GLASS );; + } + + player.teleport( tpTargetLocation ); + + } + + return tpTargetLocation; } @Override public void submitTeleportGlassBlockRemoval() { -// Location altTp = alternativeTpLocation(); - Location tpTargetLocation = isHasSpawn() ? getSpawn() : alternativeTpLocation(); - - Location glassBlockLocation = new Location( tpTargetLocation ); - int newY = tpTargetLocation.getBlockY() - 1; - glassBlockLocation.setY( newY ); - - - MineChangeBlockTask changeBlockTask = - new MineChangeBlockTask( glassBlockLocation, - PrisonBlock.AIR, PrisonBlock.GLASS ); - - int delayInTicks = 10; - PrisonTaskSubmitter.runTaskLater( changeBlockTask, delayInTicks ); + Location tpTargetLocation = isHasSpawn() ? getSpawn() : alternativeTpLocation(); + + Location glassBlockLocation = new Location( tpTargetLocation ); + int newY = tpTargetLocation.getBlockY() - 1; + glassBlockLocation.setY( newY ); + + + MineChangeBlockTask changeBlockTask = + new MineChangeBlockTask( glassBlockLocation, + PrisonBlock.AIR, PrisonBlock.GLASS ); + + int delayInTicks = 10; + PrisonTaskSubmitter.runTaskLater( changeBlockTask, delayInTicks ); - -// Block block = glassBlockLocation.getBlockAt(); -// if ( block != null ) { -// PrisonBlock prisonBlock = block.getPrisonBlock(); -// -// if ( prisonBlock != null && prisonBlock.equals( PrisonBlock.GLASS ) ) { -// // The glass block is under the player's feet so submit to remove it: -// -// MineChangeBlockTask changeBlockTask = -// new MineChangeBlockTask( glassBlockLocation, PrisonBlock.AIR ); -// -// int delayInTicks = 10; -// PrisonTaskSubmitter.runTaskLater( changeBlockTask, delayInTicks ); -// } -// } - } /** @@ -247,7 +216,7 @@ public Location alternativeTpLocation() { Location altTp = new Location( getBounds().getCenter() ); int y = getBounds().getyBlockMax() + 2; - altTp.setY( y ); + altTp.setY( y ); return altTp; } @@ -257,68 +226,62 @@ public Location alternativeTpLocation() @Override protected void broadcastResetMessageToAllPlayersWithRadius() { -// long start = System.currentTimeMillis(); - if ( isVirtual() || getResetTime() <= 0 ) { - // ignore: - } - else - if ( getNotificationMode() != MineNotificationMode.disabled ) { - World world = getBounds().getCenter().getWorld(); - - if ( world != null ) { - - boolean useWorld = getNotificationMode() != MineNotificationMode.server && - world != null && world.getPlayers() != null; - - List players = - useWorld ? - world.getPlayers() : - Prison.get().getPlatform().getOnlinePlayers(); - - for (Player player : players) { - - // Check for either mode: Within the mine, or by radius from mines center: - if ( - getNotificationMode() == MineNotificationMode.server || - - getNotificationMode() == MineNotificationMode.world && - getBounds().getMin().getWorld().getName().equalsIgnoreCase( - player.getLocation().getWorld().getName() ) || - - getNotificationMode() == MineNotificationMode.within && - getBounds().withinIncludeTopBottomOfMine(player.getLocation() ) || - - getNotificationMode() == MineNotificationMode.radius && - getBounds().within(player.getLocation(), getNotificationRadius()) ) { - - if ( !isUseNotificationPermission() || - isUseNotificationPermission() && - player.hasPermission( getMineNotificationPermissionName() ) ) { - - - PrisonMines.getInstance().getMinesMessages() - .getLocalizable("reset_message").withReplacements( getTag() ) - .sendTo(player); - -// player.sendMessage( "The mine " + getName() + " has just reset." ); - } - } - } - - } - - } + if ( isVirtual() || getResetTime() <= 0 ) { + // ignore: + } + else + if ( getNotificationMode() != MineNotificationMode.disabled ) { + World world = getBounds().getCenter().getWorld(); + + if ( world != null ) { + + boolean useWorld = getNotificationMode() != MineNotificationMode.server && + world != null && world.getPlayers() != null; + + List players = + useWorld ? + world.getPlayers() : + Prison.get().getPlatform().getOnlinePlayers(); + + for (Player player : players) { + + // Check for either mode: Within the mine, or by radius from mines center: + if ( + getNotificationMode() == MineNotificationMode.server || + + getNotificationMode() == MineNotificationMode.world && + getBounds().getMin().getWorld().getName().equalsIgnoreCase( + player.getLocation().getWorld().getName() ) || + + getNotificationMode() == MineNotificationMode.within && + getBounds().withinIncludeTopBottomOfMine(player.getLocation() ) || + + getNotificationMode() == MineNotificationMode.radius && + getBounds().within(player.getLocation(), getNotificationRadius()) ) { + + if ( !isUseNotificationPermission() || + isUseNotificationPermission() && + player.hasPermission( getMineNotificationPermissionName() ) ) { + + + PrisonMines.getInstance().getMinesMessages() + .getLocalizable("reset_message").withReplacements( getTag() ) + .sendTo(player); + + } + } + } + + } + + } -// long stop = System.currentTimeMillis(); - -// setStatsMessageBroadcastTimeMS( stop - start ); } @Override protected void broadcastSkipResetMessageToAllPlayersWithRadius() { -// long start = System.currentTimeMillis(); if ( isVirtual() || getResetTime() <= 0 ) { // ignore: @@ -367,7 +330,6 @@ else if ( PrisonMines.getInstance().getMinesMessages() .getLocalizable("skip_reset_message").withReplacements( getTag() ) .sendTo(player); -// player.sendMessage( "The mine " + getName() + " has just reset." ); } } } @@ -376,66 +338,61 @@ else if ( PrisonMines.getInstance().getMinesMessages() } -// long stop = System.currentTimeMillis(); - -// setStatsMessageBroadcastTimeMS( stop - start ); } @Override protected void broadcastPendingResetMessageToAllPlayersWithRadius(MineJob mineJob) { - if ( isVirtual() || getResetTime() <= 0) { - // ignore: - } - else - if ( getNotificationMode() != MineNotificationMode.disabled ) { - World world = getBounds().getCenter().getWorld(); - - if ( world != null ) { - - boolean useWorld = getNotificationMode() != MineNotificationMode.server && - world != null && world.getPlayers() != null; - - List players = - useWorld ? - world.getPlayers() : - Prison.get().getPlatform().getOnlinePlayers(); - - for (Player player : players) { - // Check for either mode: Within the mine, or by radius from mines center: - if ( - getNotificationMode() == MineNotificationMode.server || - - getNotificationMode() == MineNotificationMode.world && - getBounds().getMin().getWorld().getName().equalsIgnoreCase( - player.getLocation().getWorld().getName() ) || - - getNotificationMode() == MineNotificationMode.within && - getBounds().withinIncludeTopBottomOfMine(player.getLocation() ) || - - getNotificationMode() == MineNotificationMode.radius && - getBounds().within(player.getLocation(), getNotificationRadius()) ) { - - if ( !isUseNotificationPermission() || - isUseNotificationPermission() && - player.hasPermission( getMineNotificationPermissionName() ) ) { - - PrisonMines.getInstance().getMinesMessages() - .getLocalizable("reset_warning") - .withReplacements( getTag(), - Text.getTimeUntilString(Math.round(mineJob.getResetInSec() * 1000.0d)) ) - .sendTo(player); - -// player.sendMessage( "The mine " + getName() + " will reset in " + -// Text.getTimeUntilString(mineJob.getResetInSec() * 1000) ); - } - - - } - } - - } - } + if ( isVirtual() || getResetTime() <= 0) { + // ignore: + } + else + if ( getNotificationMode() != MineNotificationMode.disabled ) { + World world = getBounds().getCenter().getWorld(); + + if ( world != null ) { + + boolean useWorld = getNotificationMode() != MineNotificationMode.server && + world != null && world.getPlayers() != null; + + List players = + useWorld ? + world.getPlayers() : + Prison.get().getPlatform().getOnlinePlayers(); + + for (Player player : players) { + // Check for either mode: Within the mine, or by radius from mines center: + if ( + getNotificationMode() == MineNotificationMode.server || + + getNotificationMode() == MineNotificationMode.world && + getBounds().getMin().getWorld().getName().equalsIgnoreCase( + player.getLocation().getWorld().getName() ) || + + getNotificationMode() == MineNotificationMode.within && + getBounds().withinIncludeTopBottomOfMine(player.getLocation() ) || + + getNotificationMode() == MineNotificationMode.radius && + getBounds().within(player.getLocation(), getNotificationRadius()) ) { + + if ( !isUseNotificationPermission() || + isUseNotificationPermission() && + player.hasPermission( getMineNotificationPermissionName() ) ) { + + PrisonMines.getInstance().getMinesMessages() + .getLocalizable("reset_warning") + .withReplacements( getTag(), + Text.getTimeUntilString(Math.round(mineJob.getResetInSec() * 1000.0d)) ) + .sendTo(player); + + } + + + } + } + + } + } } } diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MinesConfig.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MinesConfig.java index 3489cff3f..59913cdd0 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MinesConfig.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MinesConfig.java @@ -29,41 +29,18 @@ */ public class MinesConfig implements FileIOData { -// /** -// * True if randomized blocks for mines should be cached for faster resets. False otherwise -// */ -// public boolean asyncReset = true; /** * True if reset warnings an reset broadcasts should be enabled. False otherwise */ public boolean resetMessages = true; -// /** -// * True if broadcasts should only be enabled in the worlds specified in the worlds list. -// * False otherwise. -// * -// * @see MinesConfig#worlds -// */ -// public boolean multiworld = false; - -// /** -// * True if only blocks that are air should be replaced. False otherwise -// */ -// public boolean fillMode = false; /** * The duration between mine resets in seconds. */ public int resetTime = Mine.MINE_RESET__TIME_SEC__DEFAULT; -// /** -// * The worlds that reset messages should be broadcasted to. Ignored if multiworld is disabled. -// * -// * @see MinesConfig#multiworld -// */ -// public ArrayList worlds = -// new ArrayList<>(Arrays.asList(new String[]{"plots", "mines"})); /** * The time between mine reset warnings. Ignored if resetMessages is disabled. diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/OnStartupRefreshBlockBreakCountSyncTask.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/OnStartupRefreshBlockBreakCountSyncTask.java index c9f048390..3c5376bf8 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/OnStartupRefreshBlockBreakCountSyncTask.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/OnStartupRefreshBlockBreakCountSyncTask.java @@ -17,8 +17,6 @@ public class OnStartupRefreshBlockBreakCountSyncTask private static OnStartupRefreshBlockBreakCountSyncTask instance; -// private List mines; - private MineReset mine; private int jobId = 0; @@ -41,8 +39,6 @@ public class OnStartupRefreshBlockBreakCountSyncTask private int countCurrentMine = 0; private int countTotalMines = 0; -// private boolean jobRunning = false; - private OnStartupRefreshBlockBreakCountSyncTask() { super(); @@ -61,9 +57,6 @@ public static OnStartupRefreshBlockBreakCountSyncTask getInstance() { return instance; } -// public OnStartupRefreshBlockBreakCountSyncTask(MineReset mine) { -// this.mine = mine; -// } public void submit( long delay ) { @@ -180,14 +173,12 @@ private void resubmit() { elapsedNanos = 0; delay = MineReset.MINE_RESET__AIR_COUNT_SUBMIT_GAP_TICKS; -// delay = 10; // Delay of 10 ticks, or 1/2 a second } if ( mine != null ) { // Must run synchronously!! setJobId( PrisonTaskSubmitter.runTaskLater( this, delay) ); -// setJobId( mine.submitSyncTask( this, delay ) ); } } @@ -210,11 +201,9 @@ public void run() { long elpased = (nanoEnd - nanoStart ); this.elapsedNanos += elpased; -// resubmit(); } } -// else // The 'this.mine.refreshAirCountSyncTaskBuildLocations()' is trivial... if ( mine == null ) { // No mine is available, either they are all processed, or none exist on @@ -278,7 +267,7 @@ public void run() { DecimalFormat iFmt = Prison.get().getDecimalFormatInt(); String message = String.format( "MineReset startup air-count: Mine [%3d of %3d]: %-10s " + - " blocks: %10s pages: [%3s: %3s] [%9s: %9s ms] <%b>", + " blocks: %10s pages: [%3s: %3s] [%9s: %9s ms]", countCurrentMine, countTotalMines, mine.getName(), @@ -286,8 +275,7 @@ public void run() { iFmt.format( pages - pagesStart ), iFmt.format( pages ), dFmt.format(elapsedMs), - dFmt.format(elapsedMsTotal), - Output.get().isDebug() + dFmt.format(elapsedMsTotal) ); Output.get().logInfo( message ); @@ -323,13 +311,6 @@ public void run() { resubmit(); } -// public List getMines() { -// return mines; -// } -// public void setMines(List mines) { -// this.mines = mines; -// } - public MineReset getMine() { return mine; } 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 1bce10fc5..c7aeb08f3 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 @@ -117,32 +117,6 @@ public static String getPrimaryEventTypes() { } -// public enum TaskMode { -// inline, -// inlinePlayer, -// -// sync, -// syncPlayer; -// -// public static TaskMode fromString( String taskMode ) { -// TaskMode results = inline; -// -// if ( taskMode != null ) { -// -// for ( TaskMode mode : values() ) { -// if ( mode.name().equalsIgnoreCase( taskMode ) ) { -// results = mode; -// -// break; -// } -// } -// } -// -// return results; -// } -// -// } - public MineBlockEvent( double chance, String permission, String command, TaskMode taskMode, BlockEventType eventType, String triggered ) { @@ -176,8 +150,6 @@ public String toSaveString() { } nFmt.format( getChance() ); -// DecimalFormat dFmt = Prison.get().getDecimalFormat("0.00000"); - String cmd = getCommand().replace( "|", ENCODED_PIPE ); return nFmt.format( getChance() ) + "|" + @@ -197,38 +169,6 @@ public static MineBlockEvent fromSaveString( String blockEventString, String min results = fromStringV1( blockEventString, mineName ); } -// if ( chancePermCommand != null && chancePermCommand.trim().length() > 0 ) { -// String[] cpc = chancePermCommand.split( "\\|" ); -// -// double chance = cpc.length >= 1 ? Double.parseDouble( cpc[0] ) : 0d; -// -// String permission = cpc.length >= 2 ? cpc[1] : ""; -// if ( permission == null || "none".equalsIgnoreCase( permission) ) { -// permission = ""; -// } -// -// String command = cpc.length >= 3 ? cpc[2] : ""; -// -// String mode = cpc.length >= 4 ? cpc[3] : "inline"; -// -// if ( !"sync".equalsIgnoreCase( mode ) && !"inline".equalsIgnoreCase( mode ) ) { -// mode = "sync"; -// } -//// boolean async = (asyncStr != null && -//// "true".equalsIgnoreCase( asyncStr ) ); -// -// BlockEventType eventType = cpc.length >= 5 ? BlockEventType.fromString( cpc[4] ) : -// BlockEventType.eventTypeAll; -// -// String triggered = cpc.length >= 6 && !"none".equals(cpc[5]) ? cpc[5] : null; -// -// -// if ( command != null && command.trim().length() > 0 ) { -// -// results = new MineBlockEvent( chance, permission, command, mode, eventType, triggered ); -// } -// } - return results; } @@ -254,7 +194,6 @@ private static MineBlockEvent fromStringV1( String chancePermCommand, String min chance = nDbl.doubleValue(); } -// chance = cpc.length >= 1 ? Double.parseDouble( cpc[0] ) : 0d; } catch ( ParseException | NumberFormatException e ) { Output.get().logError( "Failure parsing a mine " + mineName + @@ -404,28 +343,6 @@ else if ( getTriggered() != null && } } - -// // First check chance, since that's perhaps the quickest check: -// if ( chance <= getChance() && -// -// isValidBlock( targetBlock ) && -// -// // Make sure we have the correct eventTypes: -// (eventType == BlockEventType.TEXplosion && -// eventType == getEventType() && -// ( getTriggered() == null || -// getTriggered().equalsIgnoreCase( triggered )) || -// -// getEventType() == BlockEventType.all || -// getEventType() == eventType) ) { -// -// // The check for the player's perms will have to be done outside of this -// // function. -// -// results = true; -// } - - return results; } @@ -437,8 +354,6 @@ private boolean isValidBlock( MineTargetPrisonBlock targetBlock) { } private boolean hasBlockType( MineTargetPrisonBlock targetBlock ) { -// PrisonBlockTypes prisonBlockTypes = Prison.get().getPlatform().getPrisonBlockTypes(); -// PrisonBlock block = prisonBlockTypes.getBlockTypesByName( blockName ); return getPrisonBlocks().contains( targetBlock.getPrisonBlock() ); } @@ -508,14 +423,4 @@ public void setPrisonBlocks( Set prisonBlocks ) { this.prisonBlocks = prisonBlocks; } - - -// public boolean isInline() { -// return "inline".equalsIgnoreCase( getMode() ); -// } -// public boolean isSync() { -// return "sync".equalsIgnoreCase( getMode() ); -// } - - } 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 2e6430a58..d65a77de2 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 @@ -289,8 +289,6 @@ private void generatePattern( Edges edge ) { private void generatePattern( Edges edge, World world, int xMin, int xMax, int yMin, int yMax, int zMin, int zMax) { try { - // Output.get().logInfo( "MineRest.resetSynchonouslyInternal() " + getName() ); - // Output.get().logInfo( "### MineLinerBuilder - xMin=%d, xMax=%d, yMin=%d, yMax=%d, zMin=%d, zMax=%d ", // xMin, xMax, yMin, yMax, zMin, zMax); @@ -501,58 +499,6 @@ private boolean isLadderBlock( int curr, int min, int max ) { ( curr >= (min + mid - range) && curr <= (min + mid + range)); -// if ( getLadderType() == LadderType.normal ) { -// -// results = len <= 5; -// -// if ( len > 5 ) { -// -// -// if ( curr == (min + mid) ) { -// results = true; -// } -// else { -// results = isEven ? -// // if distance is even, then next ladder position is mid - 1 -// ( curr == min + mid + 1 ) : -// // If odd, then one above and below mid: -// ( curr == min + mid + 1 || curr == min + mid - 1); -// } -// -// } -// -// } -// else if ( getLadderType() == LadderType.wide ) { -// -// results = len <= 7; -// -// if ( len > 7 ) { -// -// -// if ( curr == (min + mid) ) { -// results = true; -// } -// else { -// results = isEven ? -// // if distance is even, then next ladder position is mid - 1 through mid + 2 -// ( curr >= (min + mid - range + 1) && curr <= (min + mid + range ) ) : -// -// // If odd, then one above and below mid: -// ( curr >= (min + mid - range) && curr <= (min + mid + range)); -// } -// -// } -// } - - -// Output.get().logInfo( "#### isLadderBlock: curr=%d min=%d max=%d " + -// " len=%d mid=%d " + -// "isEven=%s results=%s " + -// " (min+mid)=%d ", -// curr, min, max, len, mid, -// (isEven ? "true" : "false"), -// (results ? "true" : "false"), (min+mid) ); - } return results; @@ -981,33 +927,6 @@ protected void apply2Dto3DPattern( Edges edge, String[][] pattern2d ) } - -// public boolean isPatternValidForSpigotVersion() { -// boolean results = true; -// -// try { -// -// String v = Prison.get().getMinecraftVersion(); -// -// String versionStr = v.substring( v.indexOf( "(MC:" ) + 4, v.lastIndexOf( "." ) ); -// -// -// Output.get().logInfo( "#### MineLinerBuilder : " + -// getPattern() + " " + getPatternMinVersion() + " : " + -// "Prison Version: " + v + " " + versionStr ); -// -// double version = Double.parseDouble( versionStr ); -// -// if ( version < getPatternMinVersion() ) { -// -// } -// } -// catch ( NumberFormatException e ) { -// // ignore... just use all patterns -// } -// -// return results; -// } public List>> getPattern3d() { return pattern3d; 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 6f2059a17..1c9b4a49c 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 @@ -47,93 +47,17 @@ public static TracerType fromString( String type ) { public void clearMine( Mine mine, MineResetType resetType ) { - if ( mine == null ) { - Output.get().logError(" #### Null MINE? ###"); - } - - if ( mine.isVirtual() ) { - // Mine is virtual and cannot be reset. Just skip this with no error messages. - return; - } - -// MineResetType resetType = tracer ? MineResetType.tracer : MineResetType.clear; + if ( mine == null ) { + Output.get().logError(" #### Null MINE? ###"); + } + + if ( mine.isVirtual() ) { + // Mine is virtual and cannot be reset. Just skip this with no error messages. + return; + } MinePagedResetAsyncTask resetTask = new MinePagedResetAsyncTask( mine, resetType ); resetTask.submitTaskAsync(); } -// public void clearMine( Mine mine, boolean tracer ) { -// -// if ( mine == null ) { -// Output.get().logError(" #### Null MINE? ###"); -// } -// try { -// -// if ( mine.isVirtual() ) { -// // Mine is virtual and cannot be reset. Just skip this with no error messages. -// return; -// } -// -// -// // Output.get().logInfo( "MineRest.resetSynchonouslyInternal() " + getName() ); -// -// Optional worldOptional = mine.getWorld(); -// World world = worldOptional.get(); -// -// -// PrisonBlock blockAirPB = new PrisonBlock( "AIR" ); -//// BlockType blockAirBT = BlockType.AIR; -// -// PrisonBlock blockRedPB = new PrisonBlock( "PINK_STAINED_GLASS" ); -//// BlockType blockRedBT = BlockType.PINK_STAINED_GLASS; -// -//// PrisonBlock blockRedstonePB = new PrisonBlock( "REDSTONE_BLOCK" ); -//// BlockType blockRedstoneBT = BlockType.REDSTONE_BLOCK; -// -// -// -// -// -// // Reset the block break count before resetting the blocks: -//// setBlockBreakCount( 0 ); -//// Random random = new Random(); -// -// int yMin = mine.getBounds().getyBlockMin(); -// int yMax = mine.getBounds().getyBlockMax(); -// -// int xMin = mine.getBounds().getxBlockMin(); -// int xMax = mine.getBounds().getxBlockMax(); -// -// int zMin = mine.getBounds().getzBlockMin(); -// int zMax = mine.getBounds().getzBlockMax(); -// -// for (int y = yMax; y >= yMin; y--) { -//// for (int y = getBounds().getyBlockMin(); y <= getBounds().getyBlockMax(); y++) { -// for (int x = xMin; x <= xMax; x++) { -// for (int z = zMin; z <= zMax; z++) { -// Location targetBlock = new Location(world, x, y, z); -// -// boolean xEdge = x == xMin || x == xMax; -// boolean yEdge = y == yMin || y == yMax; -// boolean zEdge = z == zMin || z == zMax; -// -// boolean isEdge = xEdge && yEdge || xEdge && zEdge || -// yEdge && zEdge; -// -// -// targetBlock.getBlockAt().setPrisonBlock( -// tracer && isEdge ? blockRedPB : blockAirPB ); -// } -// } -// } -// -// -// } -// catch (Exception e) { -// Output.get().logError("&cFailed to clear mine " + mine.getName() + -// " Error: [" + e.getMessage() + "]", e); -// } -// } - - } 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 04f00f1a9..901b000d0 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 @@ -261,29 +261,8 @@ public void loadFromDbCollection( PrisonMines pMines ) { OnStartupRefreshBlockBreakCountSyncTask.getInstance().submit( submitDelay ); -// // When finished loading the mines, then if there are any worlds that -// // could not be loaded, dump the details: -// List unavailableWorlds = getUnavailableWorldsListings(); -// for ( String uWorld : unavailableWorlds ) { -// Output.get().logInfo( uWorld ); -// } - - -// // Submit all the loaded mines to run: -// int offset = 0; -// for ( Mine mine : mines ) -// { -// mine.submit(offset); -// offset += 5; -// } -// Output.get().logInfo("Mines are all queued to run auto resets."); } -// public void loadMine(String mineFile) throws IOException, MineException { -// Document document = coll.get(mineFile).orElseThrow(IOException::new); -// Mine m = new Mine(document); -// add(m, false, 0); -// } /** * Adds a {@link Mine} to this {@link MineManager} instance. @@ -294,7 +273,7 @@ public void loadFromDbCollection( PrisonMines pMines ) { * @return if the add was successful */ public boolean add(Mine mine) { - return add(mine, true, 0); + return add(mine, true, 0); } /** @@ -309,17 +288,17 @@ public boolean add(Mine mine) { * @return if the add was successful */ private boolean add(Mine mine, boolean save, int offsetTimingMs ) { - boolean results = false; + boolean results = false; - // not add if it already exists, or if the mine is null or does not have a valid name: + // not add if it already exists, or if the mine is null or does not have a valid name: if ( mine != null && mine.getName() != null && mine.getName().trim().length() > 0 && !getMines().contains(mine)) { - if ( save ) { - saveMine( mine ); - } - + if ( save ) { + saveMine( mine ); + } + results = getMines().add(mine); getMinesByName().put( mine.getName().toLowerCase(), mine ); @@ -331,24 +310,24 @@ private boolean add(Mine mine, boolean save, int offsetTimingMs ) { public boolean removeMine(String mineName){ - boolean results = false; - if ( mineName != null ) { - Mine mine = getMinesByName().get( mineName.toLowerCase() ); - if ( mine != null ) { - results = removeMine(mine); - } - } - - return results; + boolean results = false; + if ( mineName != null ) { + Mine mine = getMinesByName().get( mineName.toLowerCase() ); + if ( mine != null ) { + results = removeMine(mine); + } + } + + return results; } public boolean removeMine(Mine mine) { - boolean success = false; - if ( mine != null ) { - coll.delete( mine.getName() ); - getMinesByName().remove(mine.getName().toLowerCase()); - success = getMines().remove(mine); - } + boolean success = false; + if ( mine != null ) { + coll.delete( mine.getName() ); + getMinesByName().remove(mine.getName().toLowerCase()); + success = getMines().remove(mine); + } return success; } @@ -388,11 +367,11 @@ public void saveMines(){ public void saveMinesIfUnsavedBlockCounts() { - for (Mine m : getMines()){ - if ( m.hasUnsavedBlockCounts() ) { - saveMine( m ); - } - } + for (Mine m : getMines()){ + if ( m.hasUnsavedBlockCounts() ) { + saveMine( m ); + } + } } @@ -437,9 +416,7 @@ public void rename( Mine mine, String newName ) { * does not exist by the specified name. */ public Mine getMine(String mineName) { - return (mineName == null ? null : getMinesByName().get( mineName.toLowerCase() )); - - //return mines.stream().filter(mine -> mine.getName().equals(name)).findFirst(); + return (mineName == null ? null : getMinesByName().get( mineName.toLowerCase() )); } public List getMines() { @@ -447,44 +424,44 @@ public List getMines() { } public PrisonSortableResults getMines( MineSortOrder sortOrder ) { - return getMines( sortOrder, getMines() ); + return getMines( sortOrder, getMines() ); } protected PrisonSortableResults getMines( MineSortOrder sortOrder, List mines ) { - PrisonSortableResults results = new PrisonSortableResults( sortOrder ); - - - // if invalid, then that's invalid, so default to sortOrder: - if ( sortOrder == MineSortOrder.invalid ) { - sortOrder = MineSortOrder.sortOrder; - } - - - for ( Mine mine : mines ) { - if ( mine.getSortOrder() < 0 ) { - results.getExclude().add( mine ); - } - else { - results.getInclude().add( mine ); - } + PrisonSortableResults results = new PrisonSortableResults( sortOrder ); + + + // if invalid, then that's invalid, so default to sortOrder: + if ( sortOrder == MineSortOrder.invalid ) { + sortOrder = MineSortOrder.sortOrder; + } + + + for ( Mine mine : mines ) { + if ( mine.getSortOrder() < 0 ) { + results.getExclude().add( mine ); + } + else { + results.getInclude().add( mine ); + } } - - // Sort first by name, then by other means if needed: - results.getInclude().sort( (a, b) -> a.getName().compareToIgnoreCase( b.getName()) ); - results.getExclude().sort( (a, b) -> a.getName().compareToIgnoreCase( b.getName()) ); - - if ( sortOrder == MineSortOrder.sortOrder || sortOrder == MineSortOrder.xSortOrder ) { - results.getInclude().sort( (a, b) -> Integer.compare( a.getSortOrder(), b.getSortOrder()) ); - results.getExclude().sort( (a, b) -> Integer.compare( a.getSortOrder(), b.getSortOrder()) ); - } - - // for now hold off on sorting by total blocks mined. - else if ( sortOrder == MineSortOrder.active || sortOrder == MineSortOrder.xActive ) { - results.getInclude().sort( (a, b) -> Long.compare(b.getTotalBlocksMined(), a.getTotalBlocksMined()) ); - results.getExclude().sort( (a, b) -> Long.compare(b.getTotalBlocksMined(), a.getTotalBlocksMined()) ); - } - - return results; + + // Sort first by name, then by other means if needed: + results.getInclude().sort( (a, b) -> a.getName().compareToIgnoreCase( b.getName()) ); + results.getExclude().sort( (a, b) -> a.getName().compareToIgnoreCase( b.getName()) ); + + if ( sortOrder == MineSortOrder.sortOrder || sortOrder == MineSortOrder.xSortOrder ) { + results.getInclude().sort( (a, b) -> Integer.compare( a.getSortOrder(), b.getSortOrder()) ); + results.getExclude().sort( (a, b) -> Integer.compare( a.getSortOrder(), b.getSortOrder()) ); + } + + // for now hold off on sorting by total blocks mined. + else if ( sortOrder == MineSortOrder.active || sortOrder == MineSortOrder.xActive ) { + results.getInclude().sort( (a, b) -> Long.compare(b.getTotalBlocksMined(), a.getTotalBlocksMined()) ); + results.getExclude().sort( (a, b) -> Long.compare(b.getTotalBlocksMined(), a.getTotalBlocksMined()) ); + } + + return results; } @@ -736,30 +713,30 @@ public void assignAvailableWorld( String worldName ) { } public List getUnavailableWorldsListings() { - List results = new ArrayList<>(); - - if ( getUnavailableWorlds().size() > 0 ) { - results.add( "&cUnavailable Worlds: &3Deferred loading of mines." ); - - Set worlds = getUnavailableWorlds().keySet(); - - for ( String worldName : worlds ) { - int enabledCount = 0; - - List mines = getUnavailableWorlds().get( worldName ); - for ( Mine mine : mines ) { - if ( mine.isEnabled() ) { - enabledCount++; + List results = new ArrayList<>(); + + if ( getUnavailableWorlds().size() > 0 ) { + results.add( "&cUnavailable Worlds: &3Deferred loading of mines." ); + + Set worlds = getUnavailableWorlds().keySet(); + + for ( String worldName : worlds ) { + int enabledCount = 0; + + List mines = getUnavailableWorlds().get( worldName ); + for ( Mine mine : mines ) { + if ( mine.isEnabled() ) { + enabledCount++; + } } + results.add( + String.format( "&7 world: &3%s &7(&c%s mines enabled out &7of &c%s &7mines in the world) ", + worldName, Integer.toString( enabledCount ), + Integer.toString( mines.size() ))); } - results.add( - String.format( "&7 world: &3%s &7(&c%s mines enabled out &7of &c%s &7mines in the world) ", - worldName, Integer.toString( enabledCount ), - Integer.toString( mines.size() ))); - } - } - - return results; + } + + return results; } @@ -768,15 +745,14 @@ public List getUnavailableWorldsListings() { public String getTranslateMinesPlaceholder( PlaceholderIdentifier identifier ) { -// // placeholder Attributes: -// PlaceholderManager pman = Prison.get().getPlaceholderManager(); - - Player player = identifier.getPlayer(); - PlaceHolderKey placeHolderKey = identifier.getPlaceholderKey(); - - - Mine mine = null; + Player player = identifier.getPlayer(); + + PlaceHolderKey placeHolderKey = identifier.getPlaceholderKey(); + + + Mine mine = null; + if ( placeHolderKey.getPlaceholder().hasFlag( PlaceholderFlags.MINES ) || placeHolderKey.getPlaceholder().hasFlag( PlaceholderFlags.STATSMINES ) ) { @@ -791,11 +767,11 @@ public String getTranslateMinesPlaceholder( PlaceholderIdentifier identifier ) { } - PlaceholderAttributeBar attributeBar = identifier.getAttributeBar(); - PlaceholderAttributeNumberFormat attributeNFormat = identifier.getAttributeNFormat(); - PlaceholderAttributeText attributeText = identifier.getAttributeText(); - PlaceholderAttributeTime attributeTime = identifier.getAttributeTime(); - + PlaceholderAttributeBar attributeBar = identifier.getAttributeBar(); + PlaceholderAttributeNumberFormat attributeNFormat = identifier.getAttributeNFormat(); + PlaceholderAttributeText attributeText = identifier.getAttributeText(); + PlaceholderAttributeTime attributeTime = identifier.getAttributeTime(); + int sequence = identifier.getSequence(); @@ -1358,32 +1334,32 @@ else if ( attributeNFormat != null ) { public String getTranslatePlayerMinesPlaceHolder( UUID playerUuid, String playerName, String identifier ) { - String results = null; - - if ( playerUuid != null ) { - - List placeHolderKeys = getTranslatedPlaceHolderKeys(); - - - PlaceholderIdentifier phIdentifier = new PlaceholderIdentifier( identifier ); - phIdentifier.setPlayer(playerUuid, playerName); - - - - - for ( PlaceHolderKey placeHolderKey : placeHolderKeys ) { - - if ( phIdentifier.checkPlaceholderKey(placeHolderKey) ) { - - results = getTranslateMinesPlaceholder( phIdentifier ); - - break; - } - - } - } - - return results; + String results = null; + + if ( playerUuid != null ) { + + List placeHolderKeys = getTranslatedPlaceHolderKeys(); + + + PlaceholderIdentifier phIdentifier = new PlaceholderIdentifier( identifier ); + phIdentifier.setPlayer(playerUuid, playerName); + + + + + for ( PlaceHolderKey placeHolderKey : placeHolderKeys ) { + + if ( phIdentifier.checkPlaceholderKey(placeHolderKey) ) { + + results = getTranslateMinesPlaceholder( phIdentifier ); + + break; + } + + } + } + + return results; } @@ -1393,10 +1369,10 @@ private String getRemainingTimeBar( Mine mine, PlaceholderAttribute attribute ) PlaceholderAttributeBar attributeBar = ( attribute instanceof PlaceholderAttributeBar ? (PlaceholderAttributeBar) attribute : null ); - double timeRemaining = mine.getRemainingTimeSec(); - int time = mine.getResetTime(); - - return PlaceholderManagerUtils.getInstance(). + double timeRemaining = mine.getRemainingTimeSec(); + int time = mine.getResetTime(); + + return PlaceholderManagerUtils.getInstance(). getProgressBar( timeRemaining, ((double) time), true, attributeBar ); } @@ -1414,73 +1390,24 @@ private String getRemainingTimeBar( Mine mine, PlaceholderAttribute attribute ) */ @Override public List getTranslatedPlaceHolderKeys() { - if ( translatedPlaceHolderKeys == null ) { - translatedPlaceHolderKeys = new ArrayList<>(); - - TreeSet blockNames = new TreeSet<>(); - - List placeHolders = - PrisonPlaceHolders.getTypes( PlaceholderFlags.MINES ); - - placeHolders.addAll( PrisonPlaceHolders.getTypes( PlaceholderFlags.STATSMINES ) ); - - - for ( Mine mine : getMines() ) { - for ( PrisonPlaceHolders ph : placeHolders ) { - String key = ph.name().replace( - PlaceholderManager.PRISON_PLACEHOLDER_MINENAME_SUFFIX, "_" + mine.getName() ). - toLowerCase(); - - PlaceHolderKey placeholder = new PlaceHolderKey(key, ph, mine.getName() ); - if ( ph.getAlias() != null ) { - String aliasName = ph.getAlias().name().replace( - PlaceholderManager.PRISON_PLACEHOLDER_MINENAME_SUFFIX, "_" + mine.getName() ). - toLowerCase(); - placeholder.setAliasName( aliasName ); - } - translatedPlaceHolderKeys.add( placeholder ); - - // Getting too many placeholders... add back the extended prefix when looking up: - -// // Now generate a new key based upon the first key, but without the prison_ prefix: -// String key2 = key.replace( -// IntegrationManager.PRISON_PLACEHOLDER_PREFIX + "_", "" ); -// PlaceHolderKey placeholder2 = new PlaceHolderKey(key2, ph, mine.getName(), false ); -// translatedPlaceHolderKeys.add( placeholder2 ); - - // capture all of the possible blocks used within the mines: - for ( PrisonBlock block : mine.getPrisonBlocks() ) { - - String blockName = block.getBlockType() == PrisonBlockType.minecraft ? - block.getBlockName().toLowerCase() : - block.getBlockNameFormal().replace( ":", "-" ).toLowerCase(); - - if ( !blockNames.contains( blockName ) ) { - blockNames.add( blockName ); - } - } - } - } - - - // Next we need to register all the PLAYERMINES. The mines are dynamic, based upon which one - // the player is in. So this is just a simple registration. - List placeHoldersPM = - PrisonPlaceHolders.getTypes( PlaceholderFlags.MINEPLAYERS ); - - for ( PrisonPlaceHolders ph : placeHoldersPM ) { - String key = ph.name().toLowerCase(); - - // There is a special condition when a MINEPLAYERS placeholder may have a suffix of - // _minename so they need to be expanded the same as a MINES placeholder. - if ( key.endsWith( PlaceholderManager.PRISON_PLACEHOLDER_MINENAME_SUFFIX ) ) { - - for ( Mine mine : getMines() ) { - String mineKey = ph.name().replace( + if ( translatedPlaceHolderKeys == null ) { + translatedPlaceHolderKeys = new ArrayList<>(); + + TreeSet blockNames = new TreeSet<>(); + + List placeHolders = + PrisonPlaceHolders.getTypes( PlaceholderFlags.MINES ); + + placeHolders.addAll( PrisonPlaceHolders.getTypes( PlaceholderFlags.STATSMINES ) ); + + + for ( Mine mine : getMines() ) { + for ( PrisonPlaceHolders ph : placeHolders ) { + String key = ph.name().replace( PlaceholderManager.PRISON_PLACEHOLDER_MINENAME_SUFFIX, "_" + mine.getName() ). toLowerCase(); - PlaceHolderKey placeholder = new PlaceHolderKey(mineKey, ph, mine.getName() ); + PlaceHolderKey placeholder = new PlaceHolderKey(key, ph, mine.getName() ); if ( ph.getAlias() != null ) { String aliasName = ph.getAlias().name().replace( PlaceholderManager.PRISON_PLACEHOLDER_MINENAME_SUFFIX, "_" + mine.getName() ). @@ -1488,73 +1415,116 @@ public List getTranslatedPlaceHolderKeys() { placeholder.setAliasName( aliasName ); } translatedPlaceHolderKeys.add( placeholder ); - } -// PlaceHolderKey placeholder = new PlaceHolderKey(key, ph ); -// if ( ph.getAlias() != null ) { -// String aliasName = ph.getAlias().name().toLowerCase(); -// placeholder.setAliasName( aliasName ); -// } -// translatedPlaceHolderKeys.add( placeholder ); - } - else { + + // Getting too many placeholders... add back the extended prefix when looking up: + + // // Now generate a new key based upon the first key, but without the prison_ prefix: + // String key2 = key.replace( + // IntegrationManager.PRISON_PLACEHOLDER_PREFIX + "_", "" ); + // PlaceHolderKey placeholder2 = new PlaceHolderKey(key2, ph, mine.getName(), false ); + // translatedPlaceHolderKeys.add( placeholder2 ); + + // capture all of the possible blocks used within the mines: + for ( PrisonBlock block : mine.getPrisonBlocks() ) { + + String blockName = block.getBlockType() == PrisonBlockType.minecraft ? + block.getBlockName().toLowerCase() : + block.getBlockNameFormal().replace( ":", "-" ).toLowerCase(); + + if ( !blockNames.contains( blockName ) ) { + blockNames.add( blockName ); + } + } + } + } + + + // Next we need to register all the PLAYERMINES. The mines are dynamic, based upon which one + // the player is in. So this is just a simple registration. + List placeHoldersPM = + PrisonPlaceHolders.getTypes( PlaceholderFlags.MINEPLAYERS ); + + for ( PrisonPlaceHolders ph : placeHoldersPM ) { + String key = ph.name().toLowerCase(); - PlaceHolderKey placeholder = new PlaceHolderKey(key, ph ); - if ( ph.getAlias() != null ) { - String aliasName = ph.getAlias().name().toLowerCase(); - placeholder.setAliasName( aliasName ); + // There is a special condition when a MINEPLAYERS placeholder may have a suffix of + // _minename so they need to be expanded the same as a MINES placeholder. + if ( key.endsWith( PlaceholderManager.PRISON_PLACEHOLDER_MINENAME_SUFFIX ) ) { + + for ( Mine mine : getMines() ) { + String mineKey = ph.name().replace( + PlaceholderManager.PRISON_PLACEHOLDER_MINENAME_SUFFIX, "_" + mine.getName() ). + toLowerCase(); + + PlaceHolderKey placeholder = new PlaceHolderKey(mineKey, ph, mine.getName() ); + if ( ph.getAlias() != null ) { + String aliasName = ph.getAlias().name().replace( + PlaceholderManager.PRISON_PLACEHOLDER_MINENAME_SUFFIX, "_" + mine.getName() ). + toLowerCase(); + placeholder.setAliasName( aliasName ); + } + translatedPlaceHolderKeys.add( placeholder ); + } + // PlaceHolderKey placeholder = new PlaceHolderKey(key, ph ); + // if ( ph.getAlias() != null ) { + // String aliasName = ph.getAlias().name().toLowerCase(); + // placeholder.setAliasName( aliasName ); + // } + // translatedPlaceHolderKeys.add( placeholder ); + } + else { + + PlaceHolderKey placeholder = new PlaceHolderKey(key, ph ); + if ( ph.getAlias() != null ) { + String aliasName = ph.getAlias().name().toLowerCase(); + placeholder.setAliasName( aliasName ); + } + translatedPlaceHolderKeys.add( placeholder ); } - translatedPlaceHolderKeys.add( placeholder ); } - } - - - - // Next we need to register all the PLAYERMINES. The mines are dynamic, based upon which one - // the player is in. So this is just a simple registration. - List placeHoldersBN = - PrisonPlaceHolders.getTypes( PlaceholderFlags.PLAYERBLOCKS ); - - for ( PrisonPlaceHolders bn : placeHoldersBN ) { - String key = bn.name().toLowerCase(); - // There is a special condition when a MINEPLAYERS placeholder may have a suffix of - // _minename so they need to be expanded the same as a MINES placeholder. - if ( key.endsWith( PlaceholderManager.PRISON_PLACEHOLDER_PLAYERBLOCK_SUFFIX ) ) { + + + // Next we need to register all the PLAYERMINES. The mines are dynamic, based upon which one + // the player is in. So this is just a simple registration. + List placeHoldersBN = + PrisonPlaceHolders.getTypes( PlaceholderFlags.PLAYERBLOCKS ); + + for ( PrisonPlaceHolders bn : placeHoldersBN ) { + String key = bn.name().toLowerCase(); - for ( String blockName : blockNames ) { - String mineKey = bn.name().replace( - PlaceholderManager.PRISON_PLACEHOLDER_PLAYERBLOCK_SUFFIX, "__" + blockName ). - toLowerCase(); + // There is a special condition when a MINEPLAYERS placeholder may have a suffix of + // _minename so they need to be expanded the same as a MINES placeholder. + if ( key.endsWith( PlaceholderManager.PRISON_PLACEHOLDER_PLAYERBLOCK_SUFFIX ) ) { - PlaceHolderKey placeholder = new PlaceHolderKey(mineKey, bn, blockName ); - if ( bn.getAlias() != null ) { - String aliasName = bn.getAlias().name().replace( + for ( String blockName : blockNames ) { + String mineKey = bn.name().replace( PlaceholderManager.PRISON_PLACEHOLDER_PLAYERBLOCK_SUFFIX, "__" + blockName ). toLowerCase(); + + PlaceHolderKey placeholder = new PlaceHolderKey(mineKey, bn, blockName ); + if ( bn.getAlias() != null ) { + String aliasName = bn.getAlias().name().replace( + PlaceholderManager.PRISON_PLACEHOLDER_PLAYERBLOCK_SUFFIX, "__" + blockName ). + toLowerCase(); + placeholder.setAliasName( aliasName ); + } + translatedPlaceHolderKeys.add( placeholder ); + } + } + else { + + PlaceHolderKey placeholder = new PlaceHolderKey(key, bn ); + if ( bn.getAlias() != null ) { + String aliasName = bn.getAlias().name().toLowerCase(); placeholder.setAliasName( aliasName ); } translatedPlaceHolderKeys.add( placeholder ); } -// PlaceHolderKey placeholder = new PlaceHolderKey(key, ph ); -// if ( ph.getAlias() != null ) { -// String aliasName = ph.getAlias().name().toLowerCase(); -// placeholder.setAliasName( aliasName ); -// } -// translatedPlaceHolderKeys.add( placeholder ); - } - else { - - PlaceHolderKey placeholder = new PlaceHolderKey(key, bn ); - if ( bn.getAlias() != null ) { - String aliasName = bn.getAlias().name().toLowerCase(); - placeholder.setAliasName( aliasName ); - } - translatedPlaceHolderKeys.add( placeholder ); } - } - - } - return translatedPlaceHolderKeys; + + } + return translatedPlaceHolderKeys; } /** @@ -1564,18 +1534,18 @@ public List getTranslatedPlaceHolderKeys() { *

*/ public void resetTranslatedPlaceHolderKeys() { - translatedPlaceHolderKeys = null; + translatedPlaceHolderKeys = null; } @Override public void reloadPlaceholders() { - // clear the class variable so they will regenerate: - translatedPlaceHolderKeys = null; - - // Regenerate the translated placeholders: - getTranslatedPlaceHolderKeys(); + // clear the class variable so they will regenerate: + translatedPlaceHolderKeys = null; + + // Regenerate the translated placeholders: + getTranslatedPlaceHolderKeys(); } diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/tasks/MinePagedResetAsyncTask.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/tasks/MinePagedResetAsyncTask.java index 66a3f2263..bd9fc4e83 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/tasks/MinePagedResetAsyncTask.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/tasks/MinePagedResetAsyncTask.java @@ -73,9 +73,6 @@ public MinePagedResetAsyncTask( Mine mine, MineResetType resetType ) { } -// public void submitTaskSync() { -// submitTaskAsync(); -// } public void submitTaskAsync() { // Prevent the task from being submitted if it is a virtual mine: @@ -199,7 +196,6 @@ public void run() { for ( int i = position; i < endIndex; i++ ) { subList.add( targetBlocks.get( i ) ); } -// targetBlocks.subList( position, endIndex ) ); List tBlocks = new ArrayList<>(); for (MineTargetPrisonBlock mtpb : subList ) { diff --git a/prison-mines/src/test/java/tech/mcprison/prison/mines/data/PrisonSortableMinesTest.java b/prison-mines/src/test/java/tech/mcprison/prison/mines/data/PrisonSortableMinesTest.java index 6b9d26292..6f7a33697 100644 --- a/prison-mines/src/test/java/tech/mcprison/prison/mines/data/PrisonSortableMinesTest.java +++ b/prison-mines/src/test/java/tech/mcprison/prison/mines/data/PrisonSortableMinesTest.java @@ -29,13 +29,6 @@ public void testGetSortedSet() Mine b = new Mine( MineUnitTestUsage.TRUE, "b" ); // note lower case 'b' Mine c = new Mine( MineUnitTestUsage.TRUE, "C" ); -// Mine a = new Mine(); -// a.setName( "A" ); -// Mine b = new Mine(); -// b.setName( "b" ); -// Mine c = new Mine(); -// c.setName( "C" ); - List unsortedList = new ArrayList<>(); unsortedList.add( b ); unsortedList.add( c ); diff --git a/prison-mines/src/test/java/tech/mcprison/prison/mines/managers/MineManagerTest.java b/prison-mines/src/test/java/tech/mcprison/prison/mines/managers/MineManagerTest.java index 58ea9cc4f..0e089cedb 100644 --- a/prison-mines/src/test/java/tech/mcprison/prison/mines/managers/MineManagerTest.java +++ b/prison-mines/src/test/java/tech/mcprison/prison/mines/managers/MineManagerTest.java @@ -23,15 +23,6 @@ private List getTestMines() { Mine c = new Mine( MineUnitTestUsage.TRUE, "C" ); Mine d = new Mine( MineUnitTestUsage.TRUE, "D" ); -// Mine a = new Mine(); -// a.setName( "A" ); -// Mine b = new Mine(); -// b.setName( "b" ); -// Mine c = new Mine(); -// c.setName( "C" ); -// Mine d = new Mine(); -// d.setName( "D" ); - mines.add( d ); mines.add( b ); mines.add( a ); From 347fbfc59cea3ab41280abfd6257c3a3540daf87 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 6 Mar 2026 11:48:42 -0500 Subject: [PATCH 303/323] Prison Cleanup: prison-ranks: Removed obsolete and unneeded comments and fix indentation where needed. --- docs/changelog_v3.3.x.md | 3 +- .../mcprison/prison/ranks/ChatHandler.java | 39 +- .../prison/ranks/FirstJoinHandler.java | 17 +- .../ranks/FirstJoinHandlerMessages.java | 4 +- .../mcprison/prison/ranks/PrisonRanks.java | 307 +-- .../prison/ranks/PrisonRanksMessages.java | 10 +- .../prison/ranks/RankConversionAgent.java | 98 +- .../tech/mcprison/prison/ranks/RankUtil.java | 827 +++---- .../mcprison/prison/ranks/RankupResults.java | 51 +- .../ranks/commands/CommandCommands.java | 139 +- .../commands/CommandCommandsMessages.java | 20 +- .../ranks/commands/FailedRankCommands.java | 3 - .../prison/ranks/commands/LadderCommands.java | 279 +-- .../ranks/commands/LadderCommandsPerms.java | 299 +-- .../prison/ranks/commands/RankUpCommand.java | 974 +++----- .../ranks/commands/RankUpCommandMessages.java | 237 +- .../prison/ranks/commands/RanksCommands.java | 1697 +++++--------- .../ranks/commands/RanksCommandsMessages.java | 12 +- .../ranks/commands/RanksCommandsPerms.java | 312 +-- .../data/PrisonSortableLaddersRanks.java | 6 - .../prison/ranks/data/RankFactory.java | 36 - .../prison/ranks/data/RankLadderFactory.java | 130 +- .../prison/ranks/data/RankPlayerFactory.java | 628 +++--- .../RankPlayerSortableLadderRankBalance.java | 5 - .../prison/ranks/data/TopNPlayers.java | 145 +- .../prison/ranks/data/TopNPlayersData.java | 11 - .../prison/ranks/events/FirstJoinEvent.java | 12 - .../prison/ranks/events/RankUpEvent.java | 10 - .../prison/ranks/managers/LadderManager.java | 156 +- .../prison/ranks/managers/PlayerManager.java | 1997 +++++++---------- .../ranks/managers/PlayerManagerMessages.java | 3 - .../prison/ranks/managers/RankManager.java | 798 +++---- .../PlayerNewFileNameCheckAsyncTask.java | 103 - 33 files changed, 3302 insertions(+), 6066 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 89012a7af..7cb12df79 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -18,8 +18,9 @@ These change logs represent the work that has been going on within prison. +* **Prison Cleanup: prison-ranks: Removed obsolete and unneeded comments and fix indentation where needed.** -* **Prison Cleanup: Mines: Removed obsolete and unneeded comments and fix indentation where needed.** +* **Prison Cleanup: prison-mines: Removed obsolete and unneeded comments and fix indentation where needed.** * **General cleanup: these are works in progress (wip) that have not been finalized.** If it's source, its been moved to a package with .wip.in the name. These may be deleted in the future or they could be used. diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/ChatHandler.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/ChatHandler.java index 0400dc7f3..1c3ce52e7 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/ChatHandler.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/ChatHandler.java @@ -13,54 +13,27 @@ */ public class ChatHandler { - /* - * Constructor - */ public ChatHandler() { Prison.get().getEventBus().register(this); - - // This is pushed back in to the place holder integrations: -// Optional placeholderIntegration = Prison.get().getIntegrationManager().getForType(IntegrationType.PLACEHOLDER); -// if (placeholderIntegration.isPresent()) { -// PlaceholderIntegration integration = ((PlaceholderIntegration) placeholderIntegration.get()); -// -// PlayerManager pm = PrisonRanks.getInstance().getPlayerManager(); -// for ( PrisonPlaceHolders placeHolder : PrisonPlaceHolders.values() ) { -// if ( !placeHolder.isSuppressed() ) { -// integration.registerPlaceholder(placeHolder.name(), -// player -> Text.translateAmpColorCodes( -// pm.getTranslatePlayerPlaceHolder( player.getUUID(), placeHolder.name() ) -// )); -// } -// } - -//// integration.registerPlaceholder("PRISON_RANK", -//// player -> Text.translateAmpColorCodes(getPrefix(player.getUUID()))); -// } } - /* - * Listeners - */ @Subscribe public void onPlayerChat(PlayerChatEvent e) { - String newFormat = e.getFormat(); + String newFormat = e.getFormat(); // Output.get().logDebug( "ChatHandler.onPlayerChat: before: %s", newFormat.replace( "%", "^" ) ); - Player player = e.getPlayer(); - - String results = Prison.get().getPlatform().getPlaceholders() - .placeholderTranslateText( player.getUUID(), player.getName(), newFormat ); + Player player = e.getPlayer(); + + String results = Prison.get().getPlatform().getPlaceholders() + .placeholderTranslateText( player.getUUID(), player.getName(), newFormat ); // Output.get().logDebug( "ChatHandler.onPlayerChat: after: %s", results.replace( "%", "^" ) ); - e.setFormat( results ); + e.setFormat( results ); } - - } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/FirstJoinHandler.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/FirstJoinHandler.java index a84d4be9e..93b4076eb 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/FirstJoinHandler.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/FirstJoinHandler.java @@ -31,29 +31,16 @@ public class FirstJoinHandler extends FirstJoinHandlerMessages { - /* - * Constructor - */ - public FirstJoinHandler() { Prison.get().getEventBus().register(this); } - /* - * Listeners - */ - @Subscribe public void onFirstJoin(FirstJoinEvent event) { + @Subscribe + public void onFirstJoin(FirstJoinEvent event) { RankPlayer player = event.getPlayer(); PrisonRanks.getInstance().getPlayerManager().checkPlayerDefaultRank(player); - -// // Try to perform the first join processing to give them the default rank: -// RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); -// rankPlayerFactory.firstJoin( player ); -// -// PrisonRanks.getInstance().getPlayerManager().savePlayer(player); - } } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/FirstJoinHandlerMessages.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/FirstJoinHandlerMessages.java index 4cd3cc3fd..7893df761 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/FirstJoinHandlerMessages.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/FirstJoinHandlerMessages.java @@ -4,8 +4,8 @@ public class FirstJoinHandlerMessages { public String firstJoinWarningNoRanksOnServer() { return PrisonRanks.getInstance().getRanksMessages() - .getLocalizable( "ranks_firstJoinHandler__no_ranks_on_server" ) - .localize(); + .getLocalizable( "ranks_firstJoinHandler__no_ranks_on_server" ) + .localize(); } protected String firstJoinErrorCouldNotSavePlayer() { 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 4b5281292..3a3091013 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 @@ -56,10 +56,6 @@ public class PrisonRanks extends PrisonRanksMessages { public static final String MODULE_NAME = ModuleManager.MODULE_NAME_RANKS; -// public static final String MODULE_NAME = "Ranks"; - /* - * Fields & Constants - */ private static PrisonRanks instance; private RankManager rankManager; @@ -73,10 +69,6 @@ public class PrisonRanks private LocaleManager localeManager; - /* - * Constructor - */ - public PrisonRanks(String version) { super(MODULE_NAME, version, 3); @@ -86,22 +78,19 @@ public PrisonRanks(String version) { @Override public String getBaseCommands() { - return "/ranks /rankup /rankupMax /prestige /prestiges"; + return "/ranks /rankup /rankupMax /prestige /prestiges"; } - /* - * Methods - */ public static PrisonRanks getInstance() { - if ( instance == null ) { - synchronized (PrisonRanks.class) { - if ( instance == null ) { - instance = new PrisonRanks( "disabled" ); - instance.setEnabled( false ); - } + if ( instance == null ) { + synchronized (PrisonRanks.class) { + if ( instance == null ) { + instance = new PrisonRanks( "disabled" ); + instance.setEnabled( false ); + } } - } + } return instance; } @@ -146,7 +135,7 @@ public void enable() { rankManager.loadRanks(); } catch (IOException e) { - getStatus().setStatus(ModuleStatus.Status.FAILED); + getStatus().setStatus(ModuleStatus.Status.FAILED); getStatus().setMessage( prisonRanksFailureLoadingRankStatusMsg( e.getMessage() ) ); @@ -154,14 +143,12 @@ public void enable() { } // Load up the ladders - - ladderManager = new LadderManager(initCollection("ladders"), this); try { ladderManager.loadLadders( getRankManager() ); } catch (IOException e) { - getStatus().setStatus(ModuleStatus.Status.FAILED); + getStatus().setStatus(ModuleStatus.Status.FAILED); getStatus().setMessage( prisonRanksFailureLoadingLadderStatusMsg( e.getMessage() ) ); @@ -170,45 +157,27 @@ public void enable() { ladderManager.createDefaultLadder(); -// // Set the rank relationships: -// rankManager.connectRanks(); - - - - // NOTE: The following is not needed since the ladders are already hooked up to the ranks. -// for ( Rank rank : rankManager.getRanks() ) { -// -// if ( rank.getLadder() == null ) { -// // Hook up the ladder if it has not been setup yet: -// RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder( rank ); -// -// rank.setLadder( ladder ); -// } -// } - // Verify that all ranks that use currencies have valid currencies: rankManager.identifyAllRankCurrencies( getPrisonStartupDetails() ); // Load up the players - - playerManager = new PlayerManager(initCollection("players")); try { - playerManager.loadAllPlayers(); + playerManager.loadAllPlayers(); } catch (IOException e) { - getStatus().setStatus(ModuleStatus.Status.FAILED); + getStatus().setStatus(ModuleStatus.Status.FAILED); getStatus().setMessage( prisonRanksFailureLoadingPlayersStatusMsg( e.getMessage() ) ); logStartupMessageError( prisonRanksFailureLoadingPlayersMsg( e.getMessage() ) ); - getStatus().addMessage( prisonRanksFailedLoadingPlayersMsg( e.getMessage() )); - logStartupMessageError( prisonRanksFailedToLoadPlayFileMsg( e.getMessage() )); + getStatus().addMessage( prisonRanksFailedLoadingPlayersMsg( e.getMessage() )); + logStartupMessageError( prisonRanksFailedToLoadPlayFileMsg( e.getMessage() )); } @@ -259,8 +228,6 @@ public void enable() { for (String msg : rankDetails) { Output.get().logInfo(msg); } -// boolean includeAll = true; -// PrisonRanks.getInstance().getRankManager().ranksByLadders( includeAll ); @@ -274,52 +241,51 @@ public void enable() { // Check all players to see if any need to join: RanksStartupPlayerValidationsAsyncTask.submitTaskSync( this ); -// checkAllPlayersForJoin(); } public boolean reloadRanksAndLadders() { - boolean success = false; - - try { - - // New temp RankManager to reload ranks: - RankManager rManager = new RankManager(initCollection("ranks")); - - rManager.reloadAllRanks(); - - // Load up the ladders - - // New temp LadderManager to reload ladders: - LadderManager lManager = new LadderManager(initCollection("ladders"), this); - - // NOTE: This instance of the LadderManager requires the new temp instance of the rank manager: - lManager.reloadAllLadders( rManager ); - - - // Now replace all rank data and ladder data with the newly loaded data: - getRankManager().setLoadedRanks( rManager.getRanks() ); - getRankManager().setRanksByName( rManager.getRanksByName() ); - getRankManager().setRanksById( rManager.getRanksById() ); - - getLadderManager().setLoadedLadders( lManager.getLoadedLadders() ); - - - // Must reload all players now, so they are properly aligned with the ranks and ladders: - getPlayerManager().reloadAllPlayers(); - - - } catch (IOException e) { - String msg = String.format( - "PrisonRanks: reloadRanksAndLadders: Failed. [%s]", - e.getMessage()); - - Output.get().logInfo( msg ); - } - - return success; + boolean success = false; + + try { + + // New temp RankManager to reload ranks: + RankManager rManager = new RankManager(initCollection("ranks")); + + rManager.reloadAllRanks(); + + // Load up the ladders + + // New temp LadderManager to reload ladders: + LadderManager lManager = new LadderManager(initCollection("ladders"), this); + + // NOTE: This instance of the LadderManager requires the new temp instance of the rank manager: + lManager.reloadAllLadders( rManager ); + + + // Now replace all rank data and ladder data with the newly loaded data: + getRankManager().setLoadedRanks( rManager.getRanks() ); + getRankManager().setRanksByName( rManager.getRanksByName() ); + getRankManager().setRanksById( rManager.getRanksById() ); + + getLadderManager().setLoadedLadders( lManager.getLoadedLadders() ); + + + // Must reload all players now, so they are properly aligned with the ranks and ladders: + getPlayerManager().reloadAllPlayers(); + + + } catch (IOException e) { + String msg = String.format( + "PrisonRanks: reloadRanksAndLadders: Failed. [%s]", + e.getMessage()); + + Output.get().logInfo( msg ); + } + + return success; } /** @@ -347,7 +313,6 @@ public void checkAllPlayersForJoin() // If there is a default rank on the default ladder, then // check to see if there are any players not in prison: add them: RankLadder defaultLadder = getLadderManager().getLadderDefault(); -// RankLadder defaultLadder = getLadderManager().getLadder( LadderManager.LADDER_DEFAULT ); if ( defaultLadder != null && defaultLadder.getRanks().size() > 0 ) { int addedPlayers = 0; @@ -358,28 +323,9 @@ public void checkAllPlayersForJoin() // NOTE: The Platform.getOfflinePlayers() only returns the playerManager.getPlayers() because // bukkit can seriously lag the server and kill it. // List players = Prison.get().getPlatform().getOfflinePlayers(); -// -// String msg = String.format( -// "PrisonRanks: checkAllPlayersForJoin: Prison has %s players. Bukkit has %s. " -// + "Any player who is not in Prison will have to join prison to be added to prison.", -// Prison.get().getDecimalFormatInt().format( rPlayers.size() ), -// Prison.get().getDecimalFormatInt().format( players.size() ) -// ); -// -// Output.get().logInfo( msg ); + - // Prison will no longer add offline players. They must join to be added. -// for ( Player player : players ) { -// -// // getPlayer() will add a player who does not exist: -// RankPlayer rPlayer = playerManager.getPlayer( player ); -// if ( rPlayer != null ) { -// if ( rPlayer.checkName( player.getName() ) ) { -// playerManager.savePlayer( rPlayer ); -// addedPlayers++; -// } -// } -// } + // Prison will no longer add offline players. They must join to be added. Causes massive lag on huge servers! RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); @@ -400,25 +346,9 @@ public void checkAllPlayersForJoin() for ( RankPlayer rPlayer : rPlayers ) { -// @SuppressWarnings( "unused" ) -// String rp = rPlayer.toString(); - -// Rank rankOnDefault = null; PlayerRank pRank = rankPlayerFactory.getRank( rPlayer, defaultLadder ); -// if ( pRank != null ) { -// -// rankOnDefault = pRank.getRank(); -// -//// Output.get().logInfo( "#### %s ladder = %s isRankNull= %s rank= %s %s [%s]" , -//// rPlayer.getName(), -//// defaultLadder.getName(), -//// (rankOnDefault == null ? "true" : "false"), (rankOnDefault == null ? "null" : rankOnDefault.getName()), -//// (rankOnDefaultStr == null ? "true" : "false"), (rankOnDefaultStr == null ? "null" : rankOnDefaultStr.getName()), -//// rp ); -// -// } if ( pRank == null || pRank.getRank() == null ) { rankupCommands.setPlayerRank( rPlayer, defaultRank ); @@ -471,7 +401,7 @@ public void deferredStartup() { */ @Override public void disable() { - setEnabled( false ); + setEnabled( false ); } @@ -485,85 +415,38 @@ private Collection initCollection(String collName) { return collectionOptional.orElseThrow(RuntimeException::new); } -// /** -// * A default ladder is absolutely necessary on the server, so let's create it if it doesn't exist, this also create the prestiges ladder. -// */ -// private void createDefaultLadder() { -// if ( ladderManager.getLadder(LadderManager.LADDER_DEFAULT) == null ) { -// RankLadder rankLadder = ladderManager.createLadder(LadderManager.LADDER_DEFAULT); -// -// if ( rankLadder == null ) { -// -// String failureMsg = prisonRanksFailureCreateDefaultLadderMsg(); -// -// Output.get().logError( failureMsg ); -// super.getStatus().toFailed( failureMsg ); -// return; -// } -// -// if ( !ladderManager.save( rankLadder ) ) { -// -// String failureMsg = prisonRanksFailureSavingDefaultLadderMsg(); -// -// Output.get().logError( failureMsg ); -// super.getStatus().toFailed( failureMsg ); -// } -// } -// -// if ( ladderManager.getLadder(LadderManager.LADDER_PRESTIGES) == null ) { -// RankLadder rankLadder = ladderManager.createLadder(LadderManager.LADDER_PRESTIGES); -// -// if ( rankLadder == null ) { -// -// String failureMsg = prisonRanksFailureCreatePrestigeLadderMsg(); -// -// Output.get().logError( failureMsg ); -// super.getStatus().toFailed( failureMsg ); -// return; -// } -// -// if ( !ladderManager.save( rankLadder ) ) { -// -// String failureMsg = prisonRanksFailureSavingPrestigeLadderMsg(); -// -// Output.get().logError( failureMsg ); -// super.getStatus().toFailed( failureMsg ); -// } -// } -// -// } -// private void logStartupMessageError( String message ) { - logStartupMessage( LogLevel.ERROR, message ); + logStartupMessage( LogLevel.ERROR, message ); } private void logStartupMessage( String message ) { - logStartupMessage( LogLevel.INFO, message ); + logStartupMessage( LogLevel.INFO, message ); } + private void logStartupMessage( LogLevel logLevel, String message ) { - Output.get().log( message, logLevel ); - - getPrisonStartupDetails().add( message ); + Output.get().log( message, logLevel ); + + getPrisonStartupDetails().add( message ); } public List getPrisonStartupDetails() { - return prisonStartupDetails; + return prisonStartupDetails; } public void setPrisonStartupDetails( List prisonStartupDetails ){ - this.prisonStartupDetails = prisonStartupDetails; + this.prisonStartupDetails = prisonStartupDetails; } public RankManager getRankManager() { - if ( rankManager == null && !isEnabled() ) { - rankManager = new RankManager(); - } + if ( rankManager == null && !isEnabled() ) { + rankManager = new RankManager(); + } return rankManager; } @@ -573,9 +456,9 @@ public LadderManager getLadderManager() { public PlayerManager getPlayerManager() { - if ( playerManager == null && !isEnabled() ) { - playerManager = new PlayerManager( null ); - } + if ( playerManager == null && !isEnabled() ) { + playerManager = new PlayerManager( null ); + } return playerManager; } @@ -584,7 +467,7 @@ public RankLadder getDefaultLadder() { } public RankLadder getPrestigesLadder() { - return getLadderManager().getLadder(LadderManager.LADDER_PRESTIGES); + return getLadderManager().getLadder(LadderManager.LADDER_PRESTIGES); } public Database getDatabase() { @@ -592,41 +475,41 @@ public Database getDatabase() { } public int getRankCount() { - int rankCount = getRankManager() == null ||getRankManager().getRanks() == null ? 0 : + int rankCount = getRankManager() == null ||getRankManager().getRanks() == null ? 0 : getRankManager().getRanks().size(); - return rankCount; + return rankCount; } private int getLadderRankCount( String ladderName ) { - int rankCount = 0; - - if ( getLadderManager() != null && getLadderManager().getLadders() != null ) { - RankLadder ladder = getLadderManager().getLadder( ladderName ); - if ( ladder != null ) { - rankCount = ladder.getRanks().size(); - } - } - return rankCount; + int rankCount = 0; + + if ( getLadderManager() != null && getLadderManager().getLadders() != null ) { + RankLadder ladder = getLadderManager().getLadder( ladderName ); + if ( ladder != null ) { + rankCount = ladder.getRanks().size(); + } + } + return rankCount; } public int getDefaultLadderRankCount() { - return getLadderRankCount( LadderManager.LADDER_DEFAULT ); + return getLadderRankCount( LadderManager.LADDER_DEFAULT ); } public int getPrestigesLadderRankCount() { - return getLadderRankCount( LadderManager.LADDER_PRESTIGES ); + return getLadderRankCount( LadderManager.LADDER_PRESTIGES ); } public int getladderCount() { - int ladderCount = getLadderManager() == null || getLadderManager().getLadders() == null ? 0 : + int ladderCount = getLadderManager() == null || getLadderManager().getLadders() == null ? 0 : getLadderManager().getLadders().size(); - return ladderCount; + return ladderCount; } public int getPlayersCount() { - int playersCount = getPlayerManager() == null || getPlayerManager().getPlayers() == null ? 0 : + int playersCount = getPlayerManager() == null || getPlayerManager().getPlayers() == null ? 0 : getPlayerManager().getPlayers().size(); - return playersCount; + return playersCount; } public LocaleManager getRanksMessages() { @@ -645,12 +528,12 @@ public LocaleManager getRanksMessages() { * @return */ public int getElementCount() { - int results = isEnabled() ? 0 : -1; - - if ( isEnabled() ) { - results = getRankCount(); - } - - return results; + int results = isEnabled() ? 0 : -1; + + if ( isEnabled() ) { + results = getRankCount(); + } + + return results; } } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/PrisonRanksMessages.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/PrisonRanksMessages.java index d62a5dc8d..54213f8a7 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/PrisonRanksMessages.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/PrisonRanksMessages.java @@ -14,8 +14,8 @@ public PrisonRanksMessages( String name, String version, int target ) protected String prisonRanksFailureNoEconomyStatusMsg() { return PrisonRanks.getInstance().getRanksMessages() - .getLocalizable( "ranks_prisonRanks__failure_no_economy_status" ) - .localize(); + .getLocalizable( "ranks_prisonRanks__failure_no_economy_status" ) + .localize(); } protected String prisonRanksFailureNoEconomyMsg( String integrationDebug ) { @@ -137,7 +137,7 @@ public String prisonRanksFailureCreateDefaultLadderMsg() { String msgCreate = PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_prisonRanks__failure_with_ladder_create" ) .localize(); - String msgDefault = PrisonRanks.getInstance().getRanksMessages() + String msgDefault = PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_prisonRanks__failure_with_ladder_default" ) .localize(); @@ -176,11 +176,11 @@ public String prisonRanksFailureCreatePrestigeLadderMsg() { String msgCreate = PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_prisonRanks__failure_with_ladder_create" ) .localize(); - String msgDefault = PrisonRanks.getInstance().getRanksMessages() + String msgDefault = PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_prisonRanks__failure_with_ladder_prestiges" ) .localize(); - return PrisonRanks.getInstance().getRanksMessages() + return PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_prisonRanks__failure_with_ladder" ) .withReplacements( msgCreate, diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/RankConversionAgent.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/RankConversionAgent.java index ea2c494a3..aa9380c5d 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/RankConversionAgent.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/RankConversionAgent.java @@ -10,97 +10,13 @@ public class RankConversionAgent implements ConversionAgent { @Override public ConversionResult convert() { - // NOTE this is obsolete: - -// File oldFolder = new File(PrisonAPI.getPluginDirectory().getParent(), "Prison.old"); -// File ranksFolder = new File(oldFolder, "ranks"); -// -// File alreadyConverted = new File(ranksFolder, ".converted"); -// if (alreadyConverted.exists()) { -// return ConversionResult.failure(getName(), -// "Already converted. Delete the '/plugins/Prison.old/ranks' folder."); -// } -// -// String[] ranksJson = ranksFolder.list((dir, name) -> name.endsWith(".json")); -// -// try { -// -// if (ranksJson != null) { -// for (String rankJson : ranksJson) { -// File rankFile = new File(ranksFolder, rankJson); -// String json = new String(Files.readAllBytes(rankFile.toPath())); -// -// JsonObject obj = JsonParser.parseString(json).getAsJsonObject(); -// String name = obj.getAsJsonPrimitive("name").getAsString(); -// double price = obj.getAsJsonPrimitive("price").getAsDouble(); -// String prefix = obj.getAsJsonPrimitive("prefix").getAsString(); -// if (!prefix.contains("[")) { -// prefix = "&3[" + prefix; -// } -// if (!prefix.contains("]")) { -// prefix = prefix + "&3]"; -// } -// -// if(PrisonRanks.getInstance().getRankManager().getRank(name) != null) { -// break; // Already added -// } -// -// RankLadder rankLadder = -// PrisonRanks.getInstance().getLadderManager().getLadder("default"); -// if ( rankLadder == null ) { -// break; // Idek how this is possible. -// } -// -// Optional ourRank = -// PrisonRanks.getInstance().getRankManager().createRank(name, prefix, price); -// if (!ourRank.isPresent()) { -// Output.get().logWarn(String.format("Could not convert rank '%s'", name)); -// break; // It failed -// } -// -//// try { -// PrisonRanks.getInstance().getRankManager().saveRank(ourRank.get()); -//// } catch (IOException e) { -//// String nonNullName = name == null ? "null" : name; -//// PrisonRanks.getInstance().getErrorManager().throwError( -//// new Error("while converting ranks") -//// .appendStackTrace("while saving rank " + nonNullName, e)); -//// break; // Skip this... -//// } -// -// rankLadder.addRank(ourRank.get()); -// try { -// PrisonRanks.getInstance().getLadderManager().saveLadder( rankLadder ); -// } catch (IOException e) { -// PrisonRanks.getInstance().getErrorManager().throwError( -// new Error("while converting ranks") -// .appendStackTrace("while saving default ladder", e)); -// break; // Skip this... -// } -// -// } -// -// Output.get().logInfo("Notice: While we converted your ranks data, Prison 3 no longer ties itself to the permissions plugin." -// + "That means that if you want users to change permissions groups when they rank up, you'll have to use rank-up commands."); -// Output.get().logInfo("For more information, see this article:&b https://github.com/MC-Prison/Prison/wiki/Ranks-Guidebook#rank-up-commands"); -// -// alreadyConverted.createNewFile(); -// return new ConversionResult(getName(), ConversionResult.Status.Success, -// "Converted " + ranksJson.length + " ranks."); -// } else { -// alreadyConverted.createNewFile(); -// return new ConversionResult(getName(), ConversionResult.Status.Success, -// "Converted 0 ranks."); -// } -// } catch (IOException e) { -// PrisonRanks.getInstance().getErrorManager().throwError( -// new Error("while converting ranks").appendStackTrace("while loading ranks", e)); -// return ConversionResult.failure(getName(), "IOException, check console for details."); -// } - - return new ConversionResult("Rank Conversion Failure", ConversionResult.Status.Failure, - "To upgrade ranks to v3.1.1 format, please first upgrade to prison v3.1.1. " + - "Then upgrade to a newer version of prison."); + // NOTE this is obsolete: + + // commented out code was removed. See history in git. + + return new ConversionResult("Rank Conversion Failure", ConversionResult.Status.Failure, + "To upgrade ranks to v3.1.1 format, please first upgrade to prison v3.1.1. " + + "Then upgrade to a newer version of prison."); } @Override public String getName() { diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/RankUtil.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/RankUtil.java index bca8680d6..b59936bfa 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/RankUtil.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/RankUtil.java @@ -202,7 +202,7 @@ public static PromoteForceCharge fromString( String forceCharge ) { } public RankUtil() { - super(); + super(); } @@ -210,7 +210,7 @@ public RankUtil() { public RankupResults rankupPlayer(Player player, RankPlayer rankPlayer, String ladderName, String playerName, List cmdTasks ) { - return rankupPlayer(RankupCommands.rankup, player, rankPlayer, ladderName, null, + return rankupPlayer(RankupCommands.rankup, player, rankPlayer, ladderName, null, playerName, null, PromoteForceCharge.charge_player, cmdTasks ); } @@ -218,7 +218,7 @@ public RankupResults promotePlayer(Player player, RankPlayer rankPlayer, String String playerName, String executorName, PromoteForceCharge pForceCharge, List cmdTasks ) { - return rankupPlayer(RankupCommands.promote, player, rankPlayer, ladderName, null, + return rankupPlayer(RankupCommands.promote, player, rankPlayer, ladderName, null, playerName, executorName, pForceCharge, cmdTasks ); } @@ -226,7 +226,7 @@ public RankupResults demotePlayer(Player player, RankPlayer rankPlayer, String l String playerName, String executorName, PromoteForceCharge pForceCharge, List cmdTasks ) { - return rankupPlayer(RankupCommands.demote, player, rankPlayer, ladderName, null, + return rankupPlayer(RankupCommands.demote, player, rankPlayer, ladderName, null, playerName, executorName, pForceCharge, cmdTasks ); } @@ -234,10 +234,10 @@ public RankupResults setRank(Player player, RankPlayer rankPlayer, String ladder String playerName, String executorName, List cmdTasks ) { - RankupCommands rankupCmd = "FirstJoinEvent".equalsIgnoreCase( executorName ) ? + RankupCommands rankupCmd = "FirstJoinEvent".equalsIgnoreCase( executorName ) ? RankupCommands.firstJoin : RankupCommands.setrank; - return rankupPlayer( rankupCmd, player, rankPlayer, ladderName, rankName, + return rankupPlayer( rankupCmd, player, rankPlayer, ladderName, rankName, playerName, executorName, PromoteForceCharge.no_charge, cmdTasks ); } @@ -260,81 +260,79 @@ private RankupResults rankupPlayer(RankupCommands command, Player player, RankPl String rankName, String playerName, String executorName, PromoteForceCharge pForceCharge, List cmdTasks ) { - RankupResults results = new RankupResults(command, rankPlayer, executorName, ladderName, rankName); - - switch ( command ) { - case rankup: - results.addTransaction(RankupTransactions.tring_to_rankup); - break; - - case promote: - results.addTransaction(RankupTransactions.tring_to_promote); - break; - - case demote: - results.addTransaction(RankupTransactions.trying_to_demote); - break; - - case setrank: - results.addTransaction(RankupTransactions.trying_to_setrank); - break; - - case firstJoin: - results.addTransaction(RankupTransactions.trying_to_firstJoin); - break; - - default: - break; - } - - switch ( pForceCharge ) { - case no_charge: - results.addTransaction( RankupTransactions.bypassing_cost_for_player ); - break; - - case charge_player: - results.addTransaction( RankupTransactions.costs_paid_by_player ); - break; - - case refund_player: - results.addTransaction( RankupTransactions.costs_refunded_to_player ); - - break; - - default: - break; + RankupResults results = new RankupResults(command, rankPlayer, executorName, ladderName, rankName); + + switch ( command ) { + case rankup: + results.addTransaction(RankupTransactions.tring_to_rankup); + break; + + case promote: + results.addTransaction(RankupTransactions.tring_to_promote); + break; + + case demote: + results.addTransaction(RankupTransactions.trying_to_demote); + break; + + case setrank: + results.addTransaction(RankupTransactions.trying_to_setrank); + break; + + case firstJoin: + results.addTransaction(RankupTransactions.trying_to_firstJoin); + break; + + default: + break; + } + + switch ( pForceCharge ) { + case no_charge: + results.addTransaction( RankupTransactions.bypassing_cost_for_player ); + break; + + case charge_player: + results.addTransaction( RankupTransactions.costs_paid_by_player ); + break; + + case refund_player: + results.addTransaction( RankupTransactions.costs_refunded_to_player ); + + break; + + default: + break; } -// Player prisonPlayer = rankPlayer; -// Player prisonPlayer = PrisonAPI.getPlayer(player.uid).orElse(null); - if( player == null ) { - results.addTransaction( RankupStatus.RANKUP_FAILURE_COULD_NOT_LOAD_PLAYER, RankupTransactions.failed_player ); - return results; - } - + if( player == null ) { + results.addTransaction( RankupStatus.RANKUP_FAILURE_COULD_NOT_LOAD_PLAYER, RankupTransactions.failed_player ); + return results; + } + // If ladderName is null, then assign it the default ladder: if ( ladderName == null ) { - ladderName = LadderManager.LADDER_DEFAULT; - results.addTransaction(RankupTransactions.assigned_default_ladder); + ladderName = LadderManager.LADDER_DEFAULT; + results.addTransaction(RankupTransactions.assigned_default_ladder); } - try { - rankupPlayerInternal(results, command, player, rankPlayer, ladderName, - rankName, pForceCharge, cmdTasks ); - } catch (Exception e ) { - results.addTransaction( RankupTransactions.failure_exception_caught_check_server_logs ); - - Output.get().logError( rankUtilFailureInternalMsg( e.getMessage() ), e ); - } - - // Log the results: - logTransactionResults(results); - - return results; + try { + rankupPlayerInternal(results, command, player, rankPlayer, ladderName, + rankName, pForceCharge, cmdTasks ); + } catch (Exception e ) { + results.addTransaction( RankupTransactions.failure_exception_caught_check_server_logs ); + + Output.get().logError( rankUtilFailureInternalMsg( e.getMessage() ), e ); + } + + // Log the results: + logTransactionResults(results); + + return results; } @@ -350,13 +348,13 @@ private void rankupPlayerInternal(RankupResults results, String rankName, PromoteForceCharge pForceCharge, List cmdTasks ) { - Output.get().logDebug( DebugTarget.rankup, "Rankup: rankupPlayerInternal: "); + Output.get().logDebug( DebugTarget.rankup, "Rankup: rankupPlayerInternal: "); RankLadder ladder = !PrisonRanks.getInstance().isEnabled() ? null : PrisonRanks.getInstance().getLadderManager().getLadder(ladderName); if( ladder == null ) { - results.addTransaction( RankupStatus.RANKUP_FAILURE_COULD_NOT_LOAD_LADDER, RankupTransactions.failed_ladder ); - return; + results.addTransaction( RankupStatus.RANKUP_FAILURE_COULD_NOT_LOAD_LADDER, RankupTransactions.failed_ladder ); + return; } results.setLadder( ladder ); @@ -378,16 +376,6 @@ private void rankupPlayerInternal(RankupResults results, results.addTransaction( RankupTransactions.player_has_no_rank_on_ladder ); } -// if ( originalRank == null && ladder.getName().equals( "default" ) ) { -// -// // Only default ladder should be logged as an error if there is no rank: -// results.addTransaction( RankupStatus.RANKUP_FAILURE_NO_PLAYERRANK, -// RankupTransactions.failure_orginal_playerRank_does_not_exist ); -// return; -// } - -// Optional currentRankOptional = player.getRank(ladder); -// Rank originalRank = currentRankOptional.orElse( null ); results.addTransaction( RankupTransactions.orginal_rank ); results.setPlayerRankOriginal( originalRank ); @@ -403,45 +391,45 @@ private void rankupPlayerInternal(RankupResults results, if ( results.getStatus() != RankupStatus.IN_PROGRESS ) { - // Failed while calculatingTargetRank so return now: - return; + // Failed while calculatingTargetRank so return now: + return; } // Process the remove rank request if ( command == RankupCommands.setrank && "-remove-".equalsIgnoreCase( rankName ) ) { - results.addTransaction(RankupTransactions.attempting_to_delete_ladder_from_player); - - if (LadderManager.LADDER_DEFAULT.equalsIgnoreCase( ladderName ) ) { - results.addTransaction(RankupTransactions.cannot_delete_default_ladder); - } - else { - boolean success = rankPlayerFactory.removeLadder( rankPlayer, ladder.getName() ); - - if ( success ) { - if ( savePlayerRank( results, rankPlayer ) ) { - - results.addTransaction( RankupStatus.RANKUP_LADDER_REMOVED, - RankupTransactions.ladder_was_removed_from_player ); - - return; - } - } - } - - results.addTransaction( RankupStatus.RANKUP_FAILURE_REMOVING_LADDER, - RankupTransactions.could_not_delete_ladder ); - - return; + results.addTransaction(RankupTransactions.attempting_to_delete_ladder_from_player); + + if (LadderManager.LADDER_DEFAULT.equalsIgnoreCase( ladderName ) ) { + results.addTransaction(RankupTransactions.cannot_delete_default_ladder); + } + else { + boolean success = rankPlayerFactory.removeLadder( rankPlayer, ladder.getName() ); + + if ( success ) { + if ( savePlayerRank( results, rankPlayer ) ) { + + results.addTransaction( RankupStatus.RANKUP_LADDER_REMOVED, + RankupTransactions.ladder_was_removed_from_player ); + + return; + } + } + } + + results.addTransaction( RankupStatus.RANKUP_FAILURE_REMOVING_LADDER, + RankupTransactions.could_not_delete_ladder ); + + return; } // Target rank is still null, so something failed so terminate: if ( targetRank == null ) { - results.addTransaction( RankupStatus.RANKUP_FAILURE_UNABLE_TO_ASSIGN_RANK, - RankupTransactions.failed_unable_to_assign_rank ); - return; + results.addTransaction( RankupStatus.RANKUP_FAILURE_UNABLE_TO_ASSIGN_RANK, + RankupTransactions.failed_unable_to_assign_rank ); + return; } @@ -456,30 +444,22 @@ private void rankupPlayerInternal(RankupResults results, // ??? Why not use targetRank here? Isn't that always non-null? if ( originalRank == null ) { - Rank nextRank = ladder.getLowestRank().orElse( null ); -// Rank nextRank = PrisonRanks.getInstance().getDefaultLadder().getLowestRank().orElse( null ); - - pRankNext = rankPlayer.createPlayerRank(nextRank); + Rank nextRank = ladder.getLowestRank().orElse( null ); + + pRankNext = rankPlayer.createPlayerRank(nextRank); } else { - pRankNext = rankPlayer.calculateTargetPlayerRank( targetRank ); + pRankNext = rankPlayer.calculateTargetPlayerRank( targetRank ); } -// originalRank.getTargetPlayerRankForPlayer( rankPlayer, targetRank ); -// new PlayerRank( targetRank, originalRank.getRankMultiplier() ); // If player does not have a rank on this ladder, then grab the first rank on the ladder since they need // to be added to the ladder. if ( pRankNext == null ) { - results.addTransaction( RankupStatus.RANKUP_FAILURE_RANK_DOES_NOT_EXIST, - RankupTransactions.failed_rank_not_in_ladder ); - return; - - -// pRankNext = rankPlayerFactory.createPlayerRank( targetRank ); - -// pRankNext = originalRank.getTargetPlayerRankForPlayer( rankPlayer, ladder.getLowestRank().get() ); + results.addTransaction( RankupStatus.RANKUP_FAILURE_RANK_DOES_NOT_EXIST, + RankupTransactions.failed_rank_not_in_ladder ); + return; } @@ -487,7 +467,6 @@ private void rankupPlayerInternal(RankupResults results, results.setTargetRank( targetRank ); -// String currency = ""; double nextRankCost = pRankNext == null || pRankNext.getRankCost() == null ? 0.0d : pRankNext.getRankCost(); @@ -504,11 +483,9 @@ private void rankupPlayerInternal(RankupResults results, if ( rankupEvent.isCanceled() ) { - - results.addTransaction( RankupStatus.RANKUP_EVENT_CANCELED, - RankupTransactions.failed_rankup_event_canceled_outside_of_prison ); - return; - + results.addTransaction( RankupStatus.RANKUP_EVENT_CANCELED, + RankupTransactions.failed_rankup_event_canceled_outside_of_prison ); + return; } @@ -591,7 +568,7 @@ else if ( pForceCharge == PromoteForceCharge.refund_player) { } else { - results.addTransaction( RankupTransactions.zero_cost_to_player ); + results.addTransaction( RankupTransactions.zero_cost_to_player ); } // Actually apply the new rank here: @@ -604,41 +581,41 @@ else if ( pForceCharge == PromoteForceCharge.refund_player) { if ( newRank != null && (newRank.equals( originalRank ) || !targetRank.equals( newRank.getRank() )) ) { - results.setUnexpectedRank( newRank.getRank() ); - - results.addTransaction( RankupStatus.RANKUP_FAILURE_UNABLE_TO_ASSIGN_RANK, - RankupTransactions.failed_rankup_validation__target_rank_is_not_expected ); - - boolean success = false; - - // Refund charges and payments: - if ( pForceCharge == PromoteForceCharge.charge_player) { - - results.addTransaction( RankupTransactions.player_balance_refund_increased); - success = rankPlayer.addBalanceBypassCache( results.getOriginalRank().getCurrency(), currentRankCost ); - } - else if ( pForceCharge == PromoteForceCharge.refund_player) { - - - results.addTransaction( RankupTransactions.player_balance_refund_decreased ); - success = rankPlayer.removeBalanceBypassCache( targetRank.getCurrency(), nextRankCost ); - } else { - // Should never hit this code!! - } - - if ( !success ) { - // unable to reverse rankup costs or refunds - results.addTransaction( RankupTransactions.economy_failed_to_reverse_player_rankup_cost ); - } - - return; + results.setUnexpectedRank( newRank.getRank() ); + + results.addTransaction( RankupStatus.RANKUP_FAILURE_UNABLE_TO_ASSIGN_RANK, + RankupTransactions.failed_rankup_validation__target_rank_is_not_expected ); + + boolean success = false; + + // Refund charges and payments: + if ( pForceCharge == PromoteForceCharge.charge_player) { + + results.addTransaction( RankupTransactions.player_balance_refund_increased); + success = rankPlayer.addBalanceBypassCache( results.getOriginalRank().getCurrency(), currentRankCost ); + } + else if ( pForceCharge == PromoteForceCharge.refund_player) { + + + results.addTransaction( RankupTransactions.player_balance_refund_decreased ); + success = rankPlayer.removeBalanceBypassCache( targetRank.getCurrency(), nextRankCost ); + } else { + // Should never hit this code!! + } + + if ( !success ) { + // unable to reverse rankup costs or refunds + results.addTransaction( RankupTransactions.economy_failed_to_reverse_player_rankup_cost ); + } + + return; } if ( !savePlayerRank( results, rankPlayer ) ) { - return; + return; } // Now, we'll run the rank up commands. @@ -655,20 +632,20 @@ else if ( pForceCharge == PromoteForceCharge.refund_player) { for ( int row = 0; row < rankupCommands.size(); row++ ) { - String cmd = rankupCommands.get( row ); - if ( cmd != null && - ( !cmd.contains( "{firstJoin}" ) || - cmd.contains( "{firstJoin}" ) && command == RankupCommands.firstJoin ) ) { - - PlayerRank opRank = results.getPlayerRankOriginal(); - PlayerRank tpRank = results.getPlayerRankTarget(); - - Rank oRank = results.getOriginalRank(); - Rank tRank = results.getTargetRank(); - - if ( command == RankupCommands.firstJoin && cmd.contains( "{firstJoin}" ) ) { - cmd = cmd.replace( "{firstJoin}", "" ); - } + String cmd = rankupCommands.get( row ); + if ( cmd != null && + ( !cmd.contains( "{firstJoin}" ) || + cmd.contains( "{firstJoin}" ) && command == RankupCommands.firstJoin ) ) { + + PlayerRank opRank = results.getPlayerRankOriginal(); + PlayerRank tpRank = results.getPlayerRankTarget(); + + Rank oRank = results.getOriginalRank(); + Rank tRank = results.getTargetRank(); + + if ( command == RankupCommands.firstJoin && cmd.contains( "{firstJoin}" ) ) { + cmd = cmd.replace( "{firstJoin}", "" ); + } PrisonCommandTaskData cmdTask = new PrisonCommandTaskData( command.name(), cmd, row ); @@ -701,20 +678,9 @@ else if ( pForceCharge == PromoteForceCharge.refund_player) { cmdTasks.add( cmdTask ); - // Comment this out to stack the rank commands: - // cmdTask.submitCommandTask( prisonPlayer ); - - -// String formatted = cmd.replace("{player}", prisonPlayer.getName()) -// .replace("{player_uid}", rankPlayer.getUUID().toString()); - -// Prison.get().getPlatform().logPlain( -// String.format( "RankUtil.rankupPlayerInternal: Rank Command: [%s]", -// formatted )); - -// PrisonAPI.dispatchCommand(formatted); - count++; - } + + count++; + } } results.setRankupCommandsExecuted( count ); results.addTransaction( RankupTransactions.rankupCommandsCompleted ); @@ -728,20 +694,12 @@ else if ( pForceCharge == PromoteForceCharge.refund_player) { // Sort the Top ranked list: -// rankPlayer.forcePlayerToRecalculateRankScore(); TopNPlayers.getInstance().updatePlayerData(rankPlayer); -// results.addTransaction( RankupTransactions.fireRankupEvent ); -// -// // Nothing can cancel a RankUpEvent: -// RankUpEvent rankupEvent = new RankUpEvent(rankPlayer, originalRank, targetRank, nextRankCost); -// Prison.get().getEventBus().post(rankupEvent); - - if ( RankupCommands.demote == command ) { - results.addTransaction( RankupStatus.DEMOTE_SUCCESS, RankupTransactions.demote_successful ); + results.addTransaction( RankupStatus.DEMOTE_SUCCESS, RankupTransactions.demote_successful ); } else { @@ -754,49 +712,42 @@ else if ( pForceCharge == PromoteForceCharge.refund_player) { private boolean savePlayerRank( RankupResults results, RankPlayer rankPlayer ) { boolean success = false; -// try { - PrisonRanks.getInstance().getPlayerManager().savePlayer(rankPlayer); - - results.addTransaction( - RankupTransactions.successfully_saved_player_rank_data ); - - success = true; -// } -// catch (IOException e) { -// -// Output.get().logError( rankUtilFailureSavingPlayerMsg( e.getMessage() ), e ); -// -// results.addTransaction( RankupStatus.RANKUP_FAILURE_COULD_NOT_SAVE_PLAYER_FILE, -// RankupTransactions.failure_cannot_save_player_file ); -// } - + PrisonRanks.getInstance().getPlayerManager().savePlayer(rankPlayer); + + results.addTransaction( + RankupTransactions.successfully_saved_player_rank_data ); + + success = true; + return success; } private Rank calculateTargetRank(RankupCommands command, RankupResults results, // Rank originalRank, // RankLadder ladder, String ladderName, - String rankName ) { - Rank targetRank = null; + String rankName ) { + + Rank targetRank = null; // For all commands except for setrank, if the player does not have a current rank, then // set it to the default and skip all other rank processing: - // NOTE: With new processing using PlayerRank, not sure if the default rank should be set to anything... - // I'm thinking no... + // NOTE: With new processing using PlayerRank, not sure if the default rank should be set to anything... + // I'm thinking no... if ( results.getOriginalRank() == null && ( command == RankupCommands.rankup || command == RankupCommands.promote || command == RankupCommands.demote )) { - // Set the default rank: + + // Set the default rank: Optional lowestRank = results.getLadder().getLowestRank(); -// Optional lowestRank = ladder.getByPosition(0); + if (!lowestRank.isPresent()) { - results.addTransaction( RankupStatus.RANKUP_NO_RANKS, - RankupTransactions.no_ranks_found_on_ladder ); - return targetRank; + results.addTransaction( RankupStatus.RANKUP_NO_RANKS, + RankupTransactions.no_ranks_found_on_ladder ); + return targetRank; } results.addTransaction( RankupTransactions.set_to_default_rank ); targetRank = lowestRank.get(); @@ -806,7 +757,7 @@ private Rank calculateTargetRank(RankupCommands command, RankupResults results, } if ( results.getOriginalRank() == null ) { - results.addTransaction( RankupTransactions.original_rank_is_null ); + results.addTransaction( RankupTransactions.original_rank_is_null ); } @@ -815,267 +766,209 @@ private Rank calculateTargetRank(RankupCommands command, RankupResults results, // If default ladder and rank is null at this point, that means use the "default" rank: if ( command == RankupCommands.setrank || command == RankupCommands.firstJoin ) { - if ( "-remove-".equalsIgnoreCase( rankName ) ) { - - // process the -remove- rank after this function returns: - return targetRank; - } - - else if (LadderManager.LADDER_DEFAULT.equalsIgnoreCase( results.getLadder().getName() ) && rankName == null ) { - Optional lowestRank = results.getLadder().getLowestRank(); - if ( lowestRank.isPresent() ) { - targetRank = lowestRank.get(); - rankName = targetRank.getName(); - - results.addTransaction(RankupTransactions.assigned_default_rank); + if ( "-remove-".equalsIgnoreCase( rankName ) ) { + + // process the -remove- rank after this function returns: + return targetRank; + } + + else if (LadderManager.LADDER_DEFAULT.equalsIgnoreCase( results.getLadder().getName() ) && rankName == null ) { + Optional lowestRank = results.getLadder().getLowestRank(); + if ( lowestRank.isPresent() ) { + targetRank = lowestRank.get(); + rankName = targetRank.getName(); + + results.addTransaction(RankupTransactions.assigned_default_rank); + } + } - - } - - if ( targetRank == null && rankName != null ) { - - targetRank = PrisonRanks.getInstance().getRankManager().getRank( rankName ); - - if ( targetRank != null ) { - - if ( !results.getLadder().containsRank( targetRank )) { - results.addTransaction( RankupStatus.RANKUP_FAILURE_RANK_IS_NOT_IN_LADDER, - RankupTransactions.failed_rank_not_in_ladder ); - return targetRank; - } - } else { - results.addTransaction( RankupStatus.RANKUP_FAILURE_RANK_DOES_NOT_EXIST, - RankupTransactions.failed_rank_not_found ); - return targetRank; - } - } else { - results.addTransaction( RankupTransactions.failed_setrank ); - - // Got a problem... if using setrank and no rankName is provided, this is a problem - // But it should never get this far if that is the situation - } + + if ( targetRank == null && rankName != null ) { + + targetRank = PrisonRanks.getInstance().getRankManager().getRank( rankName ); + + if ( targetRank != null ) { + + if ( !results.getLadder().containsRank( targetRank )) { + results.addTransaction( RankupStatus.RANKUP_FAILURE_RANK_IS_NOT_IN_LADDER, + RankupTransactions.failed_rank_not_in_ladder ); + return targetRank; + } + } else { + results.addTransaction( RankupStatus.RANKUP_FAILURE_RANK_DOES_NOT_EXIST, + RankupTransactions.failed_rank_not_found ); + return targetRank; + } + } else { + results.addTransaction( RankupTransactions.failed_setrank ); + + // Got a problem... if using setrank and no rankName is provided, this is a problem + // But it should never get this far if that is the situation + } } if ( targetRank == null ) { - if ( command == RankupCommands.rankup || command == RankupCommands.promote ) { - // Trying to promote: -// nextRankOptional = ladder.getNext(ladder.getPositionOfRank(currentRankOptional.get())); - - if ( results.getOriginalRank().getRankNext() == null ) { - // We're already at the highest rank. - results.addTransaction( RankupStatus.RANKUP_HIGHEST, - RankupTransactions.no_higher_rank_found ); - return targetRank; - } - targetRank = results.getOriginalRank().getRankNext(); - results.addTransaction( RankupTransactions.set_to_next_higher_rank ); - - } else if ( command == RankupCommands.demote ) { - // Trying to demote: -// nextRankOptional = ladder.getPrevious(ladder.getPositionOfRank(currentRankOptional.get())); - - if ( results.getOriginalRank().getRankPrior() == null ) { - // We're already at the lowest rank. - results.addTransaction( RankupStatus.RANKUP_LOWEST, - RankupTransactions.no_lower_rank_found ); - return targetRank; - } - targetRank = results.getOriginalRank().getRankPrior(); - results.addTransaction( RankupTransactions.set_to_prior_lower_rank ); - } + if ( command == RankupCommands.rankup || command == RankupCommands.promote ) { + // Trying to promote: + + if ( results.getOriginalRank().getRankNext() == null ) { + // We're already at the highest rank. + results.addTransaction( RankupStatus.RANKUP_HIGHEST, + RankupTransactions.no_higher_rank_found ); + return targetRank; + } + targetRank = results.getOriginalRank().getRankNext(); + results.addTransaction( RankupTransactions.set_to_next_higher_rank ); + + } else if ( command == RankupCommands.demote ) { + // Trying to demote: + + if ( results.getOriginalRank().getRankPrior() == null ) { + // We're already at the lowest rank. + results.addTransaction( RankupStatus.RANKUP_LOWEST, + RankupTransactions.no_lower_rank_found ); + return targetRank; + } + targetRank = results.getOriginalRank().getRankPrior(); + results.addTransaction( RankupTransactions.set_to_prior_lower_rank ); + } } return targetRank; } - -// public static int doubleToInt(Object d) { -// return Math.toIntExact(Math.round((double) d)); -// } -// -// public static long doubleToLong(Object d) { -// return Math.round((double) d); -// } - - private void logTransactionResults( RankupResults results ) { - StringBuilder sb = new StringBuilder(); - DecimalFormat dFmt = Prison.get().getDecimalFormat("#,##0.00"); - DecimalFormat iFmt = Prison.get().getDecimalFormatInt(); - - Rank oRank = results.getOriginalRank(); - PlayerRank opRank = results.getPlayerRankOriginal(); - - Rank tRank = results.getTargetRank(); - PlayerRank tpRank = results.getPlayerRankTarget(); - - for ( RankupTransactions rt : RankupTransactions.values() ) { - - // Log the entry if it exists in the results: - if ( results.getTransactions().contains( rt ) ) { - if ( sb.length() > 0 ) { - sb.append( " " ); - } - - // Log the transaction: - sb.append( rt.name() ); - - // If the transaction has supporting data, log it too: - switch ( rt ) { - case orginal_rank: - sb.append( "=" ); - sb.append( oRank == null ? "" : oRank.getName() ); - - break; - - case custom_currency: - sb.append( "=" ); - sb.append( tRank == null || tRank.getCurrency() == null ? "" : tRank.getCurrency() ); - - break; - - case specified_currency_not_found: - sb.append( "=" ); - sb.append( tRank == null || tRank.getCurrency() == null ? "" : tRank.getCurrency() ); - - break; - - case player_balance_initial: - sb.append( "=" ); - sb.append( dFmt.format( results.getBalanceInitial() ) ); - - break; - - case player_balance_decreased: - sb.append( "=" ); - sb.append( tpRank == null ? "" : dFmt.format( tpRank.getRankCost() ) ); - - break; - - case player_balance_increased: - sb.append( "=" ); - sb.append( opRank == null ? "" : dFmt.format( opRank.getRankCost() ) ); - - break; - - case player_balance_final: - sb.append( "=" ); - sb.append( dFmt.format( results.getBalanceFinal() ) ); - - break; - - case accuracy_out_of_range: - sb.append( "=" ); - DecimalFormat sFmt = Prison.get().getDecimalFormat("#,##0.00000000"); - sb.append( sFmt.format( results.getRankupCostFinalAccuracy() ) ); - - break; - - case rankupCommandsStart: - sb.append( "=" ); - sb.append( iFmt.format( results.getRankupCommandsAvailable() ) ); - - break; - - case rankupCommandsCompleted: - sb.append( "=" ); - sb.append( iFmt.format( results.getRankupCommandsExecuted() ) ); - - break; - - case failed_rankup_validation__target_rank_is_not_expected: - - default: - break; - } - } - } + StringBuilder sb = new StringBuilder(); + DecimalFormat dFmt = Prison.get().getDecimalFormat("#,##0.00"); + DecimalFormat iFmt = Prison.get().getDecimalFormatInt(); + + Rank oRank = results.getOriginalRank(); + PlayerRank opRank = results.getPlayerRankOriginal(); + + Rank tRank = results.getTargetRank(); + PlayerRank tpRank = results.getPlayerRankTarget(); + for ( RankupTransactions rt : RankupTransactions.values() ) { + + // Log the entry if it exists in the results: + if ( results.getTransactions().contains( rt ) ) { + if ( sb.length() > 0 ) { + sb.append( " " ); + } + + // Log the transaction: + sb.append( rt.name() ); + + // If the transaction has supporting data, log it too: + switch ( rt ) { + case orginal_rank: + sb.append( "=" ); + sb.append( oRank == null ? "" : oRank.getName() ); + + break; + + case custom_currency: + sb.append( "=" ); + sb.append( tRank == null || tRank.getCurrency() == null ? "" : tRank.getCurrency() ); + + break; + + case specified_currency_not_found: + sb.append( "=" ); + sb.append( tRank == null || tRank.getCurrency() == null ? "" : tRank.getCurrency() ); + + break; + + case player_balance_initial: + sb.append( "=" ); + sb.append( dFmt.format( results.getBalanceInitial() ) ); + + break; + + case player_balance_decreased: + sb.append( "=" ); + sb.append( tpRank == null ? "" : dFmt.format( tpRank.getRankCost() ) ); + + break; + + case player_balance_increased: + sb.append( "=" ); + sb.append( opRank == null ? "" : dFmt.format( opRank.getRankCost() ) ); + + break; + + case player_balance_final: + sb.append( "=" ); + sb.append( dFmt.format( results.getBalanceFinal() ) ); + + break; + + case accuracy_out_of_range: + sb.append( "=" ); + DecimalFormat sFmt = Prison.get().getDecimalFormat("#,##0.00000000"); + sb.append( sFmt.format( results.getRankupCostFinalAccuracy() ) ); + + break; + + case rankupCommandsStart: + sb.append( "=" ); + sb.append( iFmt.format( results.getRankupCommandsAvailable() ) ); + + break; + + case rankupCommandsCompleted: + sb.append( "=" ); + sb.append( iFmt.format( results.getRankupCommandsExecuted() ) ); + + break; + + case failed_rankup_validation__target_rank_is_not_expected: + + default: + break; + } + } + } - // Add in the prefix for the log entry: - String prefix = String.format( - "Rankup: command=%s player=%s executor=%s status=%s " + - "ladderName=%s rankName=%s " + - "originalRank=(%s%s%s) targetRank=(%s%s%s) " + - "runtime=%s ms message=[%s] ", - - results.getCommand().name(), - results.getRankPlayer().getName(), - (results.getExecutor() == null ? "(see player)" : results.getExecutor()), - (results.getStatus() == null ? "" : results.getStatus().name()), - - (results.getLadderName() == null ? "" : results.getLadderName() ), - (results.getRankName() == null ? "" : results.getRankName() ), - - - (oRank == null ? "none" : oRank.getName()), - (opRank == null ? "" : " " + dFmt.format( opRank.getRankCost() )), - (oRank == null || oRank.getCurrency() == null ? "" : " " + oRank.getCurrency()), - - (tRank == null ? "none" : tRank.getName()), - (tpRank == null || tpRank.getRankCost() == null ? - "" : " " + dFmt.format( tpRank.getRankCost())), - (tRank == null || tRank.getCurrency() == null ? "" : " " + tRank.getCurrency()), - - iFmt.format( results.getElapsedTime() ), - (results.getMessage() == null ? "" : results.getMessage()) - ); - sb.insert( 0, prefix ); + // Add in the prefix for the log entry: + String prefix = String.format( + "Rankup: command=%s player=%s executor=%s status=%s " + + "ladderName=%s rankName=%s " + + "originalRank=(%s%s%s) targetRank=(%s%s%s) " + + "runtime=%s ms message=[%s] ", + + results.getCommand().name(), + results.getRankPlayer().getName(), + (results.getExecutor() == null ? "(see player)" : results.getExecutor()), + (results.getStatus() == null ? "" : results.getStatus().name()), + + (results.getLadderName() == null ? "" : results.getLadderName() ), + (results.getRankName() == null ? "" : results.getRankName() ), + + + (oRank == null ? "none" : oRank.getName()), + (opRank == null ? "" : " " + dFmt.format( opRank.getRankCost() )), + (oRank == null || oRank.getCurrency() == null ? "" : " " + oRank.getCurrency()), + + (tRank == null ? "none" : tRank.getName()), + (tpRank == null || tpRank.getRankCost() == null ? + "" : " " + dFmt.format( tpRank.getRankCost())), + (tRank == null || tRank.getCurrency() == null ? "" : " " + tRank.getCurrency()), + + iFmt.format( results.getElapsedTime() ), + (results.getMessage() == null ? "" : results.getMessage()) + ); + + sb.insert( 0, prefix ); - Output.get().logInfo( sb.toString() ); + Output.get().logInfo( sb.toString() ); } - -// @Deprecated -// public static class RankUpResult { -// -// private RankupStatus status; -// private Rank rank; -// private String message; -// -// public RankUpResult(RankupStatus status, Rank rank, String message) { -// this.status = status; -// this.rank = rank; -// this.message = message; -// } -// -// public RankUpResult(RankupStatus status, Rank rank) { -// this(status, rank, null); -// } -// -// public RankUpResult(RankupStatus status) { -// this(status, null, null); -// } -// -// -// public RankupStatus getStatus() { -// return status; -// } -// public void setStatus( RankupStatus status ) { -// this.status = status; -// } -// -// public Rank getRank() { -// return rank; -// } -// public void setRank( Rank rank ) { -// this.rank = rank; -// } -// -// public String getMessage() { -// return message; -// } -// public void setMessage( String message ) { -// this.message = message; -// } -// } - - } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/RankupResults.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/RankupResults.java index f934bd2ab..41a245bf1 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/RankupResults.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/RankupResults.java @@ -17,7 +17,6 @@ public class RankupResults { private RankupCommands command; RankPlayer rankPlayer; -// private String player; private String executor; private RankupStatus status; @@ -51,12 +50,12 @@ public RankupResults(RankupCommands command, RankPlayer rankPlayer, String execu this.status = RankupStatus.IN_PROGRESS; - this.transactions = new ArrayList<>(); - - this.command = command; - - this.rankPlayer = rankPlayer; -// this.player = playerName; + this.transactions = new ArrayList<>(); + + this.command = command; + + this.rankPlayer = rankPlayer; + this.executor = executorName; this.ladderName = ladderName; @@ -69,22 +68,22 @@ public RankupResults(RankupCommands command, RankPlayer rankPlayer, String execu public RankupResults addTransaction( RankupStatus status, RankupTransactions transaction ) { - setStatus( status ); - getTransactions().add( transaction ); - this.timestampStop = System.currentTimeMillis(); - return this; + setStatus( status ); + getTransactions().add( transaction ); + this.timestampStop = System.currentTimeMillis(); + return this; } public RankupResults addTransaction( RankupTransactions transaction ) { - getTransactions().add( transaction ); - this.timestampStop = System.currentTimeMillis(); - return this; + getTransactions().add( transaction ); + this.timestampStop = System.currentTimeMillis(); + return this; } public long getElapsedTime() { - long elapsed = getTimestampStart() - getTimestampStop(); - - return ( elapsed < 0 ? 0 : elapsed); + long elapsed = getTimestampStart() - getTimestampStop(); + + return ( elapsed < 0 ? 0 : elapsed); } @@ -102,14 +101,6 @@ public void setRankPlayer( RankPlayer rankPlayer ) { this.rankPlayer = rankPlayer; } -// public String getPlayer() { -// return player; -// } -// public void setPlayer( String player ) { -// this.player = player; -// } - - public RankLadder getLadder() { return ladder; } @@ -164,20 +155,10 @@ public PlayerRank getPlayerRankTarget() { getOriginalRank() != null && getOriginalRank().getRankNext() != null && targetRank != null ) { -// RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); - -// PlayerRank pRank = rankPlayerFactory.createPlayerRank( getOriginalRank() ); // This calculates the target rank, and takes in to consideration the player's existing rank: playerRankTarget = rankPlayer.calculateTargetPlayerRank( targetRank ); -// playerRankTarget = pRank.getTargetPlayerRankForPlayer( rankPlayer, targetRank ); -// playerRankTarget = PlayerRank.getTargetPlayerRankForPlayer( rankPlayer, targetRank ); - -// PlayerRank pRank = rankPlayer.getRank( originalRank.getLadder() ); -// PlayerRank pRankNext = new PlayerRank( targetRank, pRank.getRankMultiplier() ); - -// playerRankTarget = pRankNext; } return playerRankTarget; } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/CommandCommands.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/CommandCommands.java index 57c40c769..9c250f532 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/CommandCommands.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/CommandCommands.java @@ -50,29 +50,29 @@ public void commandAdd(CommandSender sender, } if ( command.contains( "%" ) ) { - ranksCommandAddCannotUsePercentSymbols( sender ); - return; + ranksCommandAddCannotUsePercentSymbols( sender ); + return; } if ( rankName != null && "placeholders".equalsIgnoreCase( rankName ) ) { - String placeholders = - - PrisonCommandTaskData.CustomPlaceholders.listPlaceholders( - PrisonCommandTaskData.CommandEnvironment.all_commands ) + " " + - - PrisonCommandTaskData.CustomPlaceholders.listPlaceholders( - PrisonCommandTaskData.CommandEnvironment.rank_commands ); - - String message = ranksCommandAddPlaceholdersMsg( placeholders ); - - sender.sendMessage( message ); - return; + String placeholders = + + PrisonCommandTaskData.CustomPlaceholders.listPlaceholders( + PrisonCommandTaskData.CommandEnvironment.all_commands ) + " " + + + PrisonCommandTaskData.CustomPlaceholders.listPlaceholders( + PrisonCommandTaskData.CommandEnvironment.rank_commands ); + + String message = ranksCommandAddPlaceholdersMsg( placeholders ); + + sender.sendMessage( message ); + return; } Rank rank = PrisonRanks.getInstance().getRankManager().getRank(rankName); if ( rank == null ) { - rankDoesNotExistMsg( sender, rankName ); + rankDoesNotExistMsg( sender, rankName ); return; } @@ -108,13 +108,13 @@ public void commandRemove(CommandSender sender, Integer row) { if ( row == null || row <= 0 ) { - rankRowNumberMustBeGreaterThanZero( sender, row ); - return; + rankRowNumberMustBeGreaterThanZero( sender, row ); + return; } Rank rank = PrisonRanks.getInstance().getRankManager().getRank(rankName); if ( rank == null) { - rankDoesNotExistMsg( sender, rankName ); + rankDoesNotExistMsg( sender, rankName ); return; } @@ -123,20 +123,20 @@ public void commandRemove(CommandSender sender, } if ( row > rank.getRankUpCommands().size() ) { - rankRowNumberTooHigh( sender, rank.getRankUpCommands().size(), row ); - return; + rankRowNumberTooHigh( sender, rank.getRankUpCommands().size(), row ); + return; } String oldCommand = rank.getRankUpCommands().remove( (int) row - 1 ); if ( oldCommand != null ) { - - PrisonRanks.getInstance().getRankManager().saveRank( rank ); - - ranksCommandRemoveSuccessMsg( sender, oldCommand, rank.getName() ); + + PrisonRanks.getInstance().getRankManager().saveRank( rank ); + + ranksCommandRemoveSuccessMsg( sender, oldCommand, rank.getName() ); } else { - ranksCommandRemoveFailedMsg( sender ); + ranksCommandRemoveFailedMsg( sender ); } // Redisplay the the rank command list: @@ -152,12 +152,12 @@ public void commandList(CommandSender sender, Rank rank = PrisonRanks.getInstance().getRankManager().getRank(rankName); if ( rank == null ) { - rankDoesNotExistMsg( sender, rankName ); + rankDoesNotExistMsg( sender, rankName ); return; } if (rank.getRankUpCommands() == null || rank.getRankUpCommands().size() == 0) { - ranksCommandListContainsNoneMsg( sender, rank.getName() ); + ranksCommandListContainsNoneMsg( sender, rank.getName() ); return; } @@ -176,7 +176,7 @@ protected ChatDisplay commandListDetails( Rank rank, boolean noRemoves ) ChatDisplay display = new ChatDisplay( ranksCommandListCmdHeaderMsg( title )); if ( !noRemoves ) { - display.addText( ranksCommandListClickCmdToRemoveMsg() ); + display.addText( ranksCommandListClickCmdToRemoveMsg() ); } BulletedListComponent.BulletedListBuilder builder = new BulletedListComponent.BulletedListBuilder(); @@ -184,18 +184,18 @@ protected ChatDisplay commandListDetails( Rank rank, boolean noRemoves ) int rowNumber = 1; for (String command : rank.getRankUpCommands()) { - RowComponent row = new RowComponent(); - - row.addTextComponent( " &3Row: &d%d ", rowNumber++ ); + RowComponent row = new RowComponent(); + + row.addTextComponent( " &3Row: &d%d ", rowNumber++ ); FancyMessage msg = new FancyMessage("&3/" + command); row.addFancy( msg ); if ( !noRemoves ) { - FancyMessage msgRemove = new FancyMessage( " &4Remove&3" ) - .suggest("/ranks command remove " + rank.getName() + " " + (rowNumber - 1) ) - .tooltip( ranksCommandListClickToRemoveMsg() ); - row.addFancy( msgRemove ); + FancyMessage msgRemove = new FancyMessage( " &4Remove&3" ) + .suggest("/ranks command remove " + rank.getName() + " " + (rowNumber - 1) ) + .tooltip( ranksCommandListClickToRemoveMsg() ); + row.addFancy( msgRemove ); } builder.add( row ); @@ -224,37 +224,38 @@ public void commandLadderAdd(CommandSender sender, @Arg(name = "command", description = "The command to add without / prefix. Will be ran as a console command.") @Wildcard String command) { + if (command.startsWith("/")) { command = command.replaceFirst("/", ""); } if ( command.contains( "%" ) ) { - ranksCommandAddCannotUsePercentSymbols( sender ); - return; + ranksCommandAddCannotUsePercentSymbols( sender ); + return; } if ( ladderName != null && "placeholders".equalsIgnoreCase( ladderName ) ) { - String placeholders = PrisonCommandTaskData.CustomPlaceholders.listPlaceholders( - PrisonCommandTaskData.CommandEnvironment.all_commands ) + " " + - - PrisonCommandTaskData.CustomPlaceholders.listPlaceholders( - PrisonCommandTaskData.CommandEnvironment.rank_commands ); - - String message = ladderCommandAddPlaceholdersMsg( placeholders ); - - sender.sendMessage( message ); - return; + String placeholders = PrisonCommandTaskData.CustomPlaceholders.listPlaceholders( + PrisonCommandTaskData.CommandEnvironment.all_commands ) + " " + + + PrisonCommandTaskData.CustomPlaceholders.listPlaceholders( + PrisonCommandTaskData.CommandEnvironment.rank_commands ); + + String message = ladderCommandAddPlaceholdersMsg( placeholders ); + + sender.sendMessage( message ); + return; } RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder( ladderName ); if ( ladder == null ) { - ladderDoesNotExistMsg( sender, ladderName ); + ladderDoesNotExistMsg( sender, ladderName ); return; } if (ladder.getRankUpCommands() == null) { - ladder.setRankUpCommands( new ArrayList<>() ); + ladder.setRankUpCommands( new ArrayList<>() ); } @@ -286,13 +287,13 @@ public void commandLadderRemove(CommandSender sender, Integer row) { if ( row == null || row <= 0 ) { - rankRowNumberMustBeGreaterThanZero( sender, row ); - return; + rankRowNumberMustBeGreaterThanZero( sender, row ); + return; } RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder(ladderName); if ( ladder == null) { - ladderDoesNotExistMsg( sender, ladderName ); + ladderDoesNotExistMsg( sender, ladderName ); return; } @@ -301,20 +302,20 @@ public void commandLadderRemove(CommandSender sender, } if ( row > ladder.getRankUpCommands().size() ) { - rankRowNumberTooHigh( sender, ladder.getRankUpCommands().size(), row ); - return; + rankRowNumberTooHigh( sender, ladder.getRankUpCommands().size(), row ); + return; } String oldCommand = ladder.getRankUpCommands().remove( (int) row - 1 ); if ( oldCommand != null ) { - PrisonRanks.getInstance().getLadderManager().save( ladder ); - - ladderCommandRemoveSuccessMsg( sender, oldCommand, ladder.getName() ); + PrisonRanks.getInstance().getLadderManager().save( ladder ); + + ladderCommandRemoveSuccessMsg( sender, oldCommand, ladder.getName() ); } else { - ladderCommandRemoveFailedMsg( sender ); + ladderCommandRemoveFailedMsg( sender ); } // Redisplay the the rank command list: @@ -329,12 +330,12 @@ public void commandLadderList(CommandSender sender, RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder( ladderName ); if ( ladder == null ) { - ladderDoesNotExistMsg( sender, ladderName ); + ladderDoesNotExistMsg( sender, ladderName ); return; } if (ladder.getRankUpCommands() == null || ladder.getRankUpCommands().size() == 0) { - ladderCommandListContainsNoneMsg( sender, ladder.getName() ); + ladderCommandListContainsNoneMsg( sender, ladder.getName() ); return; } @@ -350,7 +351,7 @@ protected ChatDisplay commandLadderListDetail( RankLadder ladder, boolean noRemo { ChatDisplay display = new ChatDisplay( ladderCommandListCmdHeaderMsg( ladder.getName() )); if ( !noRemoves ) { - display.addText( ranksCommandListClickCmdToRemoveMsg() ); + display.addText( ranksCommandListClickCmdToRemoveMsg() ); } BulletedListComponent.BulletedListBuilder builder = @@ -358,20 +359,20 @@ protected ChatDisplay commandLadderListDetail( RankLadder ladder, boolean noRemo int rowNumber = 1; for (String command : ladder.getRankUpCommands()) { - - RowComponent row = new RowComponent(); - - row.addTextComponent( " &3Row: &d%d ", rowNumber++ ); + + RowComponent row = new RowComponent(); + + row.addTextComponent( " &3Row: &d%d ", rowNumber++ ); FancyMessage msg = new FancyMessage("&3/" + command); row.addFancy( msg ); if ( !noRemoves ) { - FancyMessage msgRemove = new FancyMessage( " &4Remove&3" ) - .suggest("/ranks ladder command remove " + ladder.getName() + " " + (rowNumber - 1) ) - .tooltip( ranksCommandListClickToRemoveMsg() ); - row.addFancy( msgRemove ); + FancyMessage msgRemove = new FancyMessage( " &4Remove&3" ) + .suggest("/ranks ladder command remove " + ladder.getName() + " " + (rowNumber - 1) ) + .tooltip( ranksCommandListClickToRemoveMsg() ); + row.addFancy( msgRemove ); } builder.add( row ); diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/CommandCommandsMessages.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/CommandCommandsMessages.java index 8d12ab51a..3a85fb33e 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/CommandCommandsMessages.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/CommandCommandsMessages.java @@ -113,19 +113,19 @@ protected String ranksCommandListAddNewCommandToolTipMsg() { protected void rankRowNumberMustBeGreaterThanZero( CommandSender sender, Integer row ) { PrisonRanks.getInstance().getRanksMessages() - .getLocalizable( "ranks_commandCommands__command_row_number_must_be_greater_than_zero" ) - .withReplacements( - Integer.toString( row ) ) - .sendTo( sender ); + .getLocalizable( "ranks_commandCommands__command_row_number_must_be_greater_than_zero" ) + .withReplacements( + Integer.toString( row ) ) + .sendTo( sender ); } protected void rankRowNumberTooHigh( CommandSender sender, Integer maxValue, Integer row ) { - PrisonRanks.getInstance().getRanksMessages() - .getLocalizable( "ranks_commandCommands__command_row_number_too_high" ) - .withReplacements( - Integer.toString( maxValue ), - Integer.toString( row ) ) - .sendTo( sender ); + PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( "ranks_commandCommands__command_row_number_too_high" ) + .withReplacements( + Integer.toString( maxValue ), + Integer.toString( row ) ) + .sendTo( sender ); } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/FailedRankCommands.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/FailedRankCommands.java index 5c03dbe8b..79efc168d 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/FailedRankCommands.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/FailedRankCommands.java @@ -58,9 +58,6 @@ public void failedRanks( CommandSender sender ) { display.send( player ); } -// if ( sender.isPlayer() ) { -// display.send( sender ); -// } } 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 2669bbed3..e4f7cb3ba 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 @@ -32,7 +32,7 @@ public void ladderAdd(CommandSender sender, @Arg(name = "ladderName") String lad RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder(ladderName); if ( ladder != null ) { - ladderAddAlreadyExistsMsg( sender, ladderName ); + ladderAddAlreadyExistsMsg( sender, ladderName ); return; } @@ -40,7 +40,7 @@ public void ladderAdd(CommandSender sender, @Arg(name = "ladderName") String lad if ( rankLadder == null ) { - ladderAddCreationErrorMsg( sender, ladderName ); + ladderAddCreationErrorMsg( sender, ladderName ); return; } @@ -48,17 +48,17 @@ public void ladderAdd(CommandSender sender, @Arg(name = "ladderName") String lad if ( PrisonRanks.getInstance().getLadderManager().save(rankLadder) ) { - Prison.get().getPlatform().getPlaceholders().reloadPlaceholders(); - - - ladderAddCreatedMsg( sender, ladderName ); + Prison.get().getPlatform().getPlaceholders().reloadPlaceholders(); + + + ladderAddCreatedMsg( sender, ladderName ); } else { - ladderAddCreationErrorMsg( sender, ladderName ); - - ladderAddCouldNotSaveMsg( sender ); + ladderAddCreationErrorMsg( sender, ladderName ); + + ladderAddCouldNotSaveMsg( sender ); } } @@ -68,30 +68,30 @@ public void ladderRemove(CommandSender sender, @Arg(name = "ladderName") String RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder(ladderName); if ( ladder == null ) { - ladderDoesNotExistsMsg( sender, ladderName ); + ladderDoesNotExistsMsg( sender, ladderName ); return; } if (ladder.getName().equalsIgnoreCase( LadderManager.LADDER_DEFAULT )) { - ladderDeleteCannotDeleteDefaultMsg( sender ); - return; + ladderDeleteCannotDeleteDefaultMsg( sender ); + return; } if (ladder.getName().equalsIgnoreCase( LadderManager.LADDER_PRESTIGES )) { - ladderDeleteCannotDeletePrestigesMsg( sender ); - return; + ladderDeleteCannotDeletePrestigesMsg( sender ); + return; } if ( ladder.getRanks().size() > 0 ) { - ladderDeleteCannotDeleteWithRanksMsg( sender ); - return; + ladderDeleteCannotDeleteWithRanksMsg( sender ); + return; } if ( PrisonRanks.getInstance().getLadderManager().removeLadder(ladder) ) { - ladderDeletedMsg( sender, ladderName ); + ladderDeletedMsg( sender, ladderName ); } else { - ladderErrorMsg( sender ); + ladderErrorMsg( sender ); } } @@ -99,49 +99,8 @@ public void ladderRemove(CommandSender sender, @Arg(name = "ladderName") String onlyPlayers = false, permissions = "ranks.ladder") public void ladderList(CommandSender sender) { - ChatDisplay display = getLadderList(); + 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); } @@ -187,69 +146,9 @@ public ChatDisplay getLadderList() { display.addComponent(list.build()); - return display; + return display; } -// @Command(identifier = "ranks ladder listranks", description = "Lists the ranks within a ladder.", -// onlyPlayers = false, permissions = "ranks.ladder") -// public void ladderInfo( -// CommandSender sender, -// @Arg(name = "ladderName", def = "default", -// description = "The ladder name to display the ranks on. " + -// "Defaults to the default ladder") String ladderName -// -// ) { -// RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder(ladderName); -// -// if ( ladder == null ) { -// ladderDoesNotExistsMsg( sender, ladderName ); -// return; -// } -// -// ChatDisplay display = new ChatDisplay(ladder.getName()); -// display.addText( ladderHasRankMsg() ); -// -// BulletedListComponent.BulletedListBuilder builder = -// new BulletedListComponent.BulletedListBuilder(); -// -// boolean first = true; -// for (Rank rank : ladder.getRanks()) { -//// Rank rank = PrisonRanks.getInstance().getRankManager().getRank(rankPos.getRankId()); -// if ( rank == null ) { -// continue; -// } -// -//// Optional rankOptional = -//// PrisonRanks.getInstance().getRankManager().getRankOptional(rankPos.getRankId()); -//// if(!rankOptional.isPresent()) { -//// continue; // Skip it -//// } -// -// boolean defaultRank = ("default".equalsIgnoreCase( ladderName ) && first); -// -// String defaultRankValue = ladderDefaultRankMsg(); -// -// builder.add("&3(#%s) &8- &3%s (rankId: %s%s%s) %s", -// Integer.toString( rank.getPosition() ), -// rank.getName(), -// -// Integer.toString( rank.getId() ), -// (rank.getRankPrior() == null ? "" : " -"), -// (rank.getRankNext() == null ? "" : " +"), -// -// (defaultRank ? defaultRankValue : "") -// ); -// first = false; -// } -// -// String seeRanksList = ladderSeeRanksListMsg(); -// -// builder.add( seeRanksList ); -// -// display.addComponent(builder.build()); -// -// display.send(sender); -// } @Command(identifier = "ranks ladder moveRank", description = "Moves a rank to a new " + "ladder position or a new ladder.", @@ -263,16 +162,16 @@ public void ladderMoveRank(CommandSender sender, description = "Position where you want the rank to be moved to. " + "0 is the first position in the ladder.") int position) { - ladderMoveRankNoticeMsg( sender ); - - ladderRemoveRank( sender, rankName ); - - // If '*no-ladder*' then don't try to reassign it to another ladder: - if ( !ladderName.equalsIgnoreCase( "*no-ladder*" ) ) { - - ladderAddRank(sender, ladderName, rankName, position ); - } - + ladderMoveRankNoticeMsg( sender ); + + ladderRemoveRank( sender, rankName ); + + // If '*no-ladder*' then don't try to reassign it to another ladder: + if ( !ladderName.equalsIgnoreCase( "*no-ladder*" ) ) { + + ladderAddRank(sender, ladderName, rankName, position ); + } + } // @Command(identifier = "ranks ladder addrank", description = "Adds a rank to a ladder, or move a rank.", @@ -286,19 +185,19 @@ public void ladderAddRank(CommandSender sender, RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder(ladderName); if ( ladder == null ) { - ladderDoesNotExistsMsg( sender, ladderName ); + ladderDoesNotExistsMsg( sender, ladderName ); return; } Rank rank = PrisonRanks.getInstance().getRankManager().getRank(rankName); // Optional rank = PrisonRanks.getInstance().getRankManager().getRankOptional(rankName); if ( rank == null ) { - ladderRankDoesNotExistMsg( sender, rankName ); + ladderRankDoesNotExistMsg( sender, rankName ); return; } if (ladder.containsRank( rank )) { - ladderAlreadyHasRankMsg( sender, ladderName, rankName ); + ladderAlreadyHasRankMsg( sender, ladderName, rankName ); return; } @@ -310,7 +209,7 @@ public void ladderAddRank(CommandSender sender, if ( PrisonRanks.getInstance().getLadderManager().save(ladder) ) { - Prison.get().getPlatform().getPlaceholders().reloadPlaceholders(); + Prison.get().getPlatform().getPlaceholders().reloadPlaceholders(); // Recalculate the ladder's base rank cost multiplier: @@ -321,9 +220,9 @@ public void ladderAddRank(CommandSender sender, } else { - ladderErrorAddingMsg( sender ); - - ladderErrorSavingMsg( sender ); + ladderErrorAddingMsg( sender ); + + ladderErrorSavingMsg( sender ); } } @@ -334,31 +233,23 @@ public void ladderRemoveRank(CommandSender sender, // "But note, this is ignored and the real ladder used is the ladder tied to the rank.") String ladderName, // @Arg(name = "rankName") String rankName) { -// RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder(ladderName); - -// if ( ladder == null ) { -// ladderDoesNotExistsMsg( sender, ladderName ); -// return; -// } Rank rank = PrisonRanks.getInstance().getRankManager().getRank(rankName); -// Optional rank = PrisonRanks.getInstance().getRankManager().getRankOptional(rankName); if ( rank == null ) { - ladderRankDoesNotExistMsg( sender, rankName ); + ladderRankDoesNotExistMsg( sender, rankName ); return; } RankLadder ladder = rank.getLadder(); if ( ladder == null ) { - Output.get().logInfo( - "The rank %s has no ladder, so ladder cannot be removed.", - rank.getName() ); - return; + Output.get().logInfo( + "The rank %s has no ladder, so ladder cannot be removed.", + rank.getName() ); + return; } ladder.removeRank( rank ); -// ladder.removeRank(ladder.getPositionOfRank(rank)); if ( PrisonRanks.getInstance().getLadderManager().save(ladder) ) { @@ -377,8 +268,8 @@ public void ladderRemoveRank(CommandSender sender, ladderRemovedRankFromLadderMsg( sender, rankName, ladder.getName() ); } else { - ladderErrorRemovingingMsg( sender ); - ladderErrorSavingMsg( sender ); + ladderErrorRemovingingMsg( sender ); + ladderErrorSavingMsg( sender ); } } @@ -453,11 +344,6 @@ public void ladderSetRankCostMultiplier( CommandSender sender, return; } -// if ( rankCostMultiplier < -100d || rankCostMultiplier > 100d ) { -// -// ladderSetRankCostMultiplierOutOfRangeMsg( sender, rankCostMultiplier ); -// return; -// } double oldRankCostMultiplier = ladder.getRankCostMultiplierPerRank() * 100; @@ -581,73 +467,56 @@ public void ladderResetRankCosts(CommandSender sender, RankLadder ladder = lm.getLadder(ladderName); if ( ladder == null ) { - ladderDoesNotExistsMsg( sender, ladderName ); + ladderDoesNotExistsMsg( sender, ladderName ); return; } if ( exponent <= 0 ) { - sender.sendMessage("Error: ranks ladder resetRankCosts: Exponent parameter must be greater than zero."); - return; + sender.sendMessage("Error: ranks ladder resetRankCosts: Exponent parameter must be greater than zero."); + 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." ); - + 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 = 1; for (Rank rank : ladder.getRanks() ) { - double cost = Math.pow(initialCost * i++ * addMult, exponent ); - - if ( rank.getRawRankCost() != cost ) { - rank.setRawRankCost( cost ); - - rm.saveRank( rank ); - - ranksChanged++; - } + double cost = Math.pow(initialCost * i++ * addMult, exponent ); + + 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 ); + // 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/LadderCommandsPerms.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/LadderCommandsPerms.java index 5f578064a..3a7ef03f7 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/LadderCommandsPerms.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/LadderCommandsPerms.java @@ -7,309 +7,12 @@ public abstract class LadderCommandsPerms extends LadderCommandsMessages { - public LadderCommandsPerms( String cmdGroup ) { super( cmdGroup ); } + // About 5 commented out methods were removed. See hithub history for details. -// NOT USED: -// @Command(identifier = "ranks ladder perms list", description = "Lists ladder permissions", -// onlyPlayers = false, permissions = "ranks.set") -// public void ladderPermsList(CommandSender sender, -// @Arg(name = "ladderName", def = "default", -// description = "Ladder name to list the permissions.") String ladderName -// ){ -// sender.sendMessage( "&cWarning: &3This feature is not yet functional." ); -// -// RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder(ladderName); -// -// if ( ladder == null ) { -// ladderDoesNotExistsMsg( sender, ladderName ); -// return; -// } -// -// if ( ladder.getPermissions() == null ||ladder.getPermissions().size() == 0 && -// ladder.getPermissionGroups() == null && ladder.getPermissionGroups().size() == 0 ) { -// -// PrisonRanks.getInstance().getRanksMessages() -// .getLocalizable( "ranks_LadderCommands__ladder_has_no_perms" ) -// .withReplacements( -// ladder.getName() ) -// .sendTo( sender ); -// return; -// } -// -// -// -// ChatDisplay display = new ChatDisplay("Ladder Permissions and Groups for " + ladder.getName()); -// display.addText("&8Click the 'Remove' tag to remove it."); -// display.addText(" &3Placeholders: &7{rank}&3 - Rank Name"); -// display.addText(" &3All Ladder perms will be applied automatically to all ladder ranks."); -// -// BulletedListComponent.BulletedListBuilder builder = -// new BulletedListComponent.BulletedListBuilder(); -// -// -// int rowNumber = 1; -// -// if ( ladder.getPermissions().size() > 0 ) { -// builder.add( "&7Permissions:" ); -// } -// for (String perm : ladder.getPermissions() ) { -// -// RowComponent row = new RowComponent(); -// -// row.addTextComponent( " &3Row: &d%d ", rowNumber++ ); -// -// FancyMessage msgPermission = new FancyMessage( String.format( "&7%s ", perm ) ) -// .command( "/ranks ladder perms edit " + ladder.getName() + " " + rowNumber + " " ) -// .tooltip("Permission - Click to Edit"); -// row.addFancy( msgPermission ); -// -// -// FancyMessage msgRemove = new FancyMessage( String.format( " &cRemove " ) ) -// .command( "/ranks ladder perms remove " + ladder.getName() + " " + rowNumber + " " ) -// .tooltip("Remove Permission - Click to Delete"); -// row.addFancy( msgRemove ); -// -// builder.add( row ); -// } -// -// if ( ladder.getPermissionGroups().size() > 0 ) { -// builder.add( "&7Permission Groups:" ); -// } -// for (String permGroup : ladder.getPermissionGroups() ) { -// -// RowComponent row = new RowComponent(); -// -// row.addTextComponent( " &3Row: &d%d ", rowNumber++ ); -// -// FancyMessage msgPermission = new FancyMessage( String.format( "&7%s ", permGroup ) ) -// .command( "/ranks ladder perms edit " + ladder.getName() + " " + rowNumber + " " ) -// .tooltip("Permission Group - Click to Edit"); -// row.addFancy( msgPermission ); -// -// -// FancyMessage msgRemove = new FancyMessage( String.format( " &cRemove " ) ) -// .command( "/ranks ladder perms remove " + ladder.getName() + " " + rowNumber + " " ) -// .tooltip("Remove Permission Group - Click to Delete"); -// row.addFancy( msgRemove ); -// -// builder.add( row ); -// } -// -// -// display.addComponent(builder.build()); -// display.addComponent(new FancyMessageComponent( -// new FancyMessage("&7[&a+&7] Add Permission") -// .suggest("/ranks ladder perms addPerm " + ladder.getName() + " [perm] /") -// .tooltip("&7Add a new Permission."))); -// display.addComponent(new FancyMessageComponent( -// new FancyMessage("&7[&a+&7] Add Permission Group") -// .suggest("/ranks ladder perms addPermGroup " + ladder.getName() + " [permGroup] /") -// .tooltip("&7Add a new Permission Group."))); -// -// display.send(sender); -// -// } - - -//NOT USED: -// @Command(identifier = "ranks ladder perms addPerm", -// description = "Add a ladder permission. Valid placeholder: {rank}.", -// onlyPlayers = false, permissions = "ranks.set") -// public void ladderPermsAddPerm(CommandSender sender, -// @Arg(name = "ladderName", def = "default", -// description = "Ladder name to add the permission to.") String ladderName, -// @Arg(name = "permission", description = "Permission") String permission -// ){ -// sender.sendMessage( "&cWarning: &3This feature is not yet functional." ); -// -// RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder(ladderName); -// -// if ( ladder == null ) { -// Output.get().sendError(sender, "The ladder '%s' doesn't exist.", ladderName); -// return; -// } -// -// if ( permission == null || permission.trim().isEmpty() ) { -// -// Output.get().sendInfo(sender, "&3The &7permission &3parameter is required." ); -// return; -// } -// -// -// if ( ladder.hasPermission( permission ) ) { -// -// Output.get().sendInfo(sender, "&3The permission &7%s &3already exists.", permission ); -// return; -// } -// -// ladder.getPermissions().add( permission ); -// -// boolean saved = PrisonRanks.getInstance().getLadderManager().save( ladder ); -// -// if ( saved ) { -// -// Output.get().sendInfo(sender, "&3The permission &7%s &3was successfully added " + -// "to the ladder &7%s&3.", permission, ladder.getName() ); -// } -// else { -// -// Output.get().sendInfo(sender, "&cFailure: &3The permission &7%s &3was unable to " + -// "be saved to the ladder &7%s&3. See the console for additional informatio.", -// permission, ladder.getName() ); -// } -// -// ladderPermsList( sender, ladder.getName() ); -// } - -//NOT USED: -// @Command(identifier = "ranks ladder perms addGroup", -// description = "Add a ladder permission group. Valid placeholder: {rank}.", -// onlyPlayers = false, permissions = "ranks.set") -// public void ladderPermsAddGroup(CommandSender sender, -// @Arg(name = "ladderName", def = "default", -// description = "Ladder name to add the permission group to.") String ladderName, -// @Arg(name = "permissionGroup", description = "Permission Group") String permissionGroup -// ){ -// sender.sendMessage( "&cWarning: &3This feature is not yet functional." ); -// -// RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder(ladderName); -// -// if ( ladder == null ) { -// Output.get().sendError(sender, "The ladder '%s' doesn't exist.", ladderName); -// return; -// } -// -// if ( permissionGroup == null || permissionGroup.trim().isEmpty() ) { -// -// Output.get().sendInfo(sender, "&3The &7permissionGroup &3parameter is required." ); -// return; -// } -// -// -// if ( ladder.hasPermissionGroup( permissionGroup ) ) { -// -// Output.get().sendInfo(sender, "&3The permission group &7%s &3already exists.", -// permissionGroup ); -// return; -// } -// -// ladder.getPermissionGroups().add( permissionGroup ); -// -// boolean saved = PrisonRanks.getInstance().getLadderManager().save( ladder ); -// -// if ( saved ) { -// -// Output.get().sendInfo(sender, "&3The permission group &7%s &3was successfully added " + -// "to the ladder &7%s&3.", permissionGroup, ladder.getName() ); -// } -// else { -// -// Output.get().sendInfo(sender, "&cFailure: &3The permission group &7%s &3was unable to " + -// "be saved to the ladder &7%s&3. See the console for additional information.", -// permissionGroup, ladder.getName() ); -// } -// -// ladderPermsList( sender, ladder.getName() ); -// } - -// Since we are strictly dealing with a single value for perms, editing makes no sense; -// just delete the 'bad' perm and re-add it. -// @Command(identifier = "ranks ladder perms edit", description = "Lists ladder permissions", -// onlyPlayers = false, permissions = "ranks.set") -// public void ladderPermsEdit(CommandSender sender, -// @Arg(name = "ladderName", def = "default", -// description = "Ladder name to list the permissions.") String ladderName, -// @Arg(name = "row") Integer row -// ){ -// sender.sendMessage( "&cWarning: &3This feature is not yet functional." ); -// -// Optional ladderOptional = -// PrisonRanks.getInstance().getLadderManager().getLadder(ladderName); -// if (!ladderOptional.isPresent()) { -// Output.get().sendError(sender, "The ladder '%s' doesn't exist.", ladderName); -// return; -// } -// -// RankLadder ladder = ladderOptional.get(); -// -// } - - -//NOT USED: -// @Command(identifier = "ranks ladder perms remove", description = "Lists ladder permissions", -// onlyPlayers = false, permissions = "ranks.set") -// public void ladderPermsRemove(CommandSender sender, -// @Arg(name = "ladderName", def = "default", -// description = "Ladder name to list the permissions.") String ladderName, -// @Arg(name = "row") Integer row -// ){ -// sender.sendMessage( "&cWarning: &3This feature is not yet functional." ); -// -// RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder(ladderName); -// -// if ( ladder == null ) { -// Output.get().sendError(sender, "The ladder '%s' doesn't exist.", ladderName); -// return; -// } -// -// boolean dirty = false; -// String removedPerm = ""; -// boolean permGroup = false; -// -// if ( row == null || row <= 0 ) { -// sender.sendMessage( -// String.format("&7Please provide a valid row number greater than zero. " + -// "Was row=[&b%d&7]", -// (row == null ? "null" : row) )); -// return; -// } -// -// if ( row <= ladder.getPermissions().size() ) { -// removedPerm = ladder.getPermissions().remove( row - 1 ); -// dirty = true; -// } -// else { -// // Remove from row the size of permissions so the row will align to the permissionGroups. -// row -= ladder.getPermissions().size(); -// -// if ( row <= ladder.getPermissionGroups().size() ) { -// -// removedPerm = ladder.getPermissions().remove( row - 1 ); -// dirty = true; -// permGroup = true; -// } -// } -// -// if ( dirty ) { -// boolean saved = PrisonRanks.getInstance().getLadderManager().save( ladder ); -// -// if ( saved ) { -// -// Output.get().sendInfo(sender, "&3The permission%s &7%s &3was successfully removed " + -// "to the ladder &7%s&3.", -// ( permGroup ? " group" : "" ), -// removedPerm, ladder.getName() ); -// } -// else { -// -// Output.get().sendInfo(sender, "&cFailure: &3The permission%s &7%s &3was unable to " + -// "be saved to the ladder &7%s&3. See the console for additional information.", -// ( permGroup ? " group" : "" ), -// removedPerm, ladder.getName() ); -// } -// } -// else { -// Output.get().sendInfo(sender, "&3The permission on row &7%s &3was unable to be removed " + -// "from the &7%s &3ladder. " + -// "Is that a valid row number?", -// Integer.toString( row ), ladder.getName() ); -// } -// } - } 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 f831ca2c2..c12862f9a 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 @@ -76,54 +76,50 @@ public void rankUpMax(CommandSender sender, @Arg(name = "ladder", description = "The ladder to rank up on.", def = "default") String ladder ) { - String perms = "ranks.rankupmax."; - String permsLadder = perms + ladder; + String perms = "ranks.rankupmax."; + String permsLadder = perms + ladder; boolean isPrestigesEnabled = Prison.get().getPlatform().getConfigBooleanFalse( "prestiges" ) || Prison.get().getPlatform().getConfigBooleanFalse( "prestige.enabled" ); boolean isLadderPrestiges = ladder.equalsIgnoreCase(LadderManager.LADDER_PRESTIGES); -// boolean isLadderDefault = ladder.equalsIgnoreCase(LadderManager.LADDER_DEFAULT); RankPlayer rPlayer = sender.getRankPlayer(); - if ( (isPrestigesEnabled && isLadderPrestiges || - !isLadderPrestiges ) && - sender.hasPermission( permsLadder) - ) { - Output.get().logDebug( DebugTarget.rankup, - "Rankup: cmd '/rankupmax %s' Passed perm check: %s", - ladder, permsLadder ); - - boolean success = false; - - List cmdTasks = new ArrayList<>(); - StringBuilder sbRanks = new StringBuilder(); - - - RankupModes mode = RankupModes.MAX_RANKS; - - if ( !LadderManager.LADDER_PRESTIGES.equalsIgnoreCase( ladder ) && - !LadderManager.LADDER_DEFAULT.equalsIgnoreCase( ladder )) { - - success = rankUpPrivate(sender, rPlayer, ladder, mode, perms, cmdTasks, sbRanks ); - } - else { - - // Run rankupmax on the default ladder only: - success = rankUpPrivate(sender, rPlayer, LadderManager.LADDER_DEFAULT, mode, perms, cmdTasks, sbRanks ); - - // If they specified the prestiges ladder, then try to prestige that one rank: - if ( success && LadderManager.LADDER_PRESTIGES.equalsIgnoreCase( ladder ) ) { - - success = rankUpPrivate(sender, rPlayer, LadderManager.LADDER_PRESTIGES, RankupModes.ONE_RANK, perms, cmdTasks, sbRanks ); - } - } - + if ( (isPrestigesEnabled && isLadderPrestiges || + !isLadderPrestiges ) && + sender.hasPermission( permsLadder) + ) { + Output.get().logDebug( DebugTarget.rankup, + "Rankup: cmd '/rankupmax %s' Passed perm check: %s", + ladder, permsLadder ); + + boolean success = false; + + List cmdTasks = new ArrayList<>(); + StringBuilder sbRanks = new StringBuilder(); + + + RankupModes mode = RankupModes.MAX_RANKS; + + if ( !LadderManager.LADDER_PRESTIGES.equalsIgnoreCase( ladder ) && + !LadderManager.LADDER_DEFAULT.equalsIgnoreCase( ladder )) { + + success = rankUpPrivate(sender, rPlayer, ladder, mode, perms, cmdTasks, sbRanks ); + } + else { + + // Run rankupmax on the default ladder only: + success = rankUpPrivate(sender, rPlayer, LadderManager.LADDER_DEFAULT, mode, perms, cmdTasks, sbRanks ); + + // If they specified the prestiges ladder, then try to prestige that one rank: + if ( success && LadderManager.LADDER_PRESTIGES.equalsIgnoreCase( ladder ) ) { + + success = rankUpPrivate(sender, rPlayer, LadderManager.LADDER_PRESTIGES, RankupModes.ONE_RANK, perms, cmdTasks, sbRanks ); + } + } + -// RankPlayer rPlayer = sender.getRankPlayer(); -// Player player = getPlayerByName( sender.getName()); -// Player player = getPlayer( sender, null ); // submit cmdTasks if ( cmdTasks.size() > 0 ) { @@ -143,16 +139,12 @@ public void rankUpMax(CommandSender sender, rankUpMax( sender, ladder ); } } - else { -// RankPlayer rPlayer = sender.getRankPlayer(); -// Player player = getPlayerByName( sender.getName() ); -// Player player = getPlayer( sender, null ); - Output.get().logDebug( DebugTarget.rankup, - "Rankup: Failed: cmd '/rankupmax %s' Does not have the permission ranks.rankupmax.%s", - ladder, ladder ); - rankupMaxNoPermissionMsg( sender, "ranks.rankupmax." + ladder, rPlayer ); -// rankupMaxNoPermissionMsg( sender, "ranks.rankupmax." + ladder, player.getRankPlayer() ); - } + else { + Output.get().logDebug( DebugTarget.rankup, + "Rankup: Failed: cmd '/rankupmax %s' Does not have the permission ranks.rankupmax.%s", + ladder, ladder ); + rankupMaxNoPermissionMsg( sender, "ranks.rankupmax." + ladder, rPlayer ); + } } @@ -195,8 +187,8 @@ else if ( isPlayer ) { // NOTE: If this is being ran from the console, the a 'playerName' parameter must be supplied: else if ( !isPlayer && playerName.length() == 0 ) { - Output.get().logInfo( rankupCannotRunFromConsoleMsg() ); - return; + Output.get().logInfo( rankupCannotRunFromConsoleMsg() ); + return; } @@ -207,54 +199,11 @@ else if ( !isPlayer && playerName.length() == 0 ) { getRankPlayer(sender, null, playerName); if ( rPlayer == null ) { - rankupInvalidPlayerNameMsg( sender, playerName ); - return; + rankupInvalidPlayerNameMsg( sender, playerName ); + return; } -// Player player = getPlayerByName( playerName ); -// -// if ( player == null ) { -// rankupInvalidPlayerNameMsg( sender, playerName ); -// return; -// } - -// RankPlayer rPlayer = getRankPlayer(sender, null, playerName); - -// boolean isConfirmed = ( confirm != null && confirm.toLowerCase().contains("confirm") ); -// if ( !isConfirmed && playerName != null && playerName.toLowerCase().equals( "confirm" ) ) { -// isConfirmed = true; -// playerName = ""; -// } -// else if ( !isConfirmed && ladder != null && ladder.toLowerCase().equals( "confirm" ) ) { -// isConfirmed = true; -// ladder = ""; -// } - - - -// boolean isConfirmationEnabled = Prison.get().getPlatform().getConfigBooleanFalse( "ranks.confirmation-enabled" ); -// if ( isConfirmationEnabled && !isConfirmed ) { -// if ( isConfirmGUI && isPlayer ) { -// -// // call the gui prestige confirmation: -//// callGuiPrestigeConfirmation( sender, ); -// String guiConfirmParms = -// prestigeConfirmationGUIMsg( sender, rPlayer, nextRank, isResetDefaultLadder, isResetMoney ); -// -// String guiConfirmCmd = "gui prestigeConfirm " + guiConfirmParms; -//// Output.get().logInfo( guiConfirmCmd ); -// -// submitCmdTask( rPlayer, guiConfirmCmd ); -// -// } -// else { -// -// prestigeConfirmationMsg( sender, rPlayer, nextRank, isResetDefaultLadder, isResetMoney, isPlayer ); -// } -// return; -// } - boolean isLadderDefault = ladder.equalsIgnoreCase(LadderManager.LADDER_DEFAULT); boolean isLadderPrestiges = ladder.equalsIgnoreCase(LadderManager.LADDER_PRESTIGES); @@ -291,52 +240,39 @@ else if ( !isPlayer && playerName.length() == 0 ) { ); - if ( isDefaultBypassPermCheck || - isPrestigeBypassPermCheck || - - isLadderDefault && hasDefaultPerm || - - isPrestigesEnabled && isLadderPrestiges && - hasLadderPerm || - - - !isLadderDefault && !isLadderPrestiges && - hasLadderPerm - - ) { - - Output.get().logDebug( DebugTarget.rankup, - "Rankup: cmd '/rankup %s%s' Passed perm check: %s [%s]]", - ladder, - ( playerName.length() == 0 ? "" : " " + playerName ), - permsLadder, - permsCheck ); - - -// Output.get().logDebug( DebugTarget.rankup, -// "Rankup: cmd '/rankup %s%s' Processing %s", -// ladder, -// ( playerName.length() == 0 ? "" : " " + playerName ), -// permsLadder -// ); - - List cmdTasks = new ArrayList<>(); - - rankUpPrivate(sender, rPlayer, ladder, RankupModes.ONE_RANK, perms, cmdTasks, null ); -// rankUpPrivate(sender, playerName, ladder, RankupModes.ONE_RANK, perms, cmdTasks, null ); - - // submit cmdTasks -// Player player = getPlayerByName( sender, playerName ); -// Player player = getPlayer( sender, playerName ); - submitCmdTasks( rPlayer, cmdTasks ); + if ( isDefaultBypassPermCheck || + isPrestigeBypassPermCheck || + + isLadderDefault && hasDefaultPerm || + + isPrestigesEnabled && isLadderPrestiges && + hasLadderPerm || + + + !isLadderDefault && !isLadderPrestiges && + hasLadderPerm + + ) { + + Output.get().logDebug( DebugTarget.rankup, + "Rankup: cmd '/rankup %s%s' Passed perm check: %s [%s]]", + ladder, + ( playerName.length() == 0 ? "" : " " + playerName ), + permsLadder, + permsCheck ); + + List cmdTasks = new ArrayList<>(); + + rankUpPrivate(sender, rPlayer, ladder, RankupModes.ONE_RANK, perms, cmdTasks, null ); + + submitCmdTasks( rPlayer, cmdTasks ); } - else { -// Player player = getPlayer( sender, playerName ); - Output.get().logDebug( DebugTarget.rankup, - "Rankup: Failed: cmd '/rankup %s' Does not have the permission %s. [%s]", - ladder, permsLadder, permsCheck ); - rankupMaxNoPermissionMsg( sender, permsLadder, rPlayer ); - } + else { + Output.get().logDebug( DebugTarget.rankup, + "Rankup: Failed: cmd '/rankup %s' Does not have the permission %s. [%s]", + ladder, permsLadder, permsCheck ); + rankupMaxNoPermissionMsg( sender, permsLadder, rPlayer ); + } } @@ -359,7 +295,7 @@ public void prestigeCmd(CommandSender sender, "this can only be provided by a non-player such as console or ran from a script. " + "Players cannot run Prestige for other players.") String playerName, - @Arg(name = "confirm", def = "", + @Arg(name = "confirm", def = "", description = "If confirmations are enabled, then the prestige command " + "must be repeated with the addition of 'confirm'. If the prestige command is ran by a " + "non-player, such as console or from script, then the confirmation will be skipped, or " @@ -383,8 +319,8 @@ public void prestigeCmd(CommandSender sender, if ( !isPlayer && playerName.length() == 0 ) { - Output.get().logInfo( rankupCannotRunFromConsoleMsg() ); - return; + Output.get().logInfo( rankupCannotRunFromConsoleMsg() ); + return; } RankPlayer rPlayer = isPlayer ? @@ -392,16 +328,13 @@ public void prestigeCmd(CommandSender sender, getRankPlayer(sender, null, playerName); if ( rPlayer == null ) { - rankupInvalidPlayerNameMsg( sender, playerName ); - return; + rankupInvalidPlayerNameMsg( sender, playerName ); + return; } - - boolean isPrestigesEnabled = Prison.get().getPlatform().getConfigBooleanFalse( "prestiges" ) || Prison.get().getPlatform().getConfigBooleanFalse( "prestige.enabled" ); - boolean hasPrestigePerm = sender.hasPermission( "ranks.user" ) || sender.hasPermission( "ranks.rankup.prestiges"); @@ -421,21 +354,11 @@ public void prestigeCmd(CommandSender sender, String perms = "ranks.rankup."; -// String permsLadder = perms + LadderManager.LADDER_PRESTIGES; -// boolean hasPermsLadder = sender.hasPermission(permsLadder); -// boolean usePerms = Prison.get().getPlatform().getConfigBooleanFalse( "enable__ranks_rankup_prestiges__permission" ); -// boolean hasAcessToPrestige = usePerms && hasPermsLadder || !usePerms; - -// boolean isPrestigesEnabled = Prison.get().getPlatform().getConfigBooleanFalse( "prestiges" ) || -// Prison.get().getPlatform().getConfigBooleanFalse( "prestige.enabled" ); boolean isResetDefaultLadder = Prison.get().getPlatform().getConfigBooleanFalse( "prestige.resetDefaultLadder" ); boolean isResetMoney = Prison.get().getPlatform().getConfigBooleanFalse( "prestige.resetMoney" ); boolean isConfirmationEnabled = Prison.get().getPlatform().getConfigBooleanFalse( "prestige.confirmation-enabled" ); boolean isConfirmGUI = Prison.get().getPlatform().getConfigBooleanFalse( "prestige.prestige-confirm-gui" ); - //boolean isforceSellall = Prison.get().getPlatform().getConfigBooleanFalse( "prestige.force-sellall" ); - -// boolean isLadderPrestiges = ladder.equalsIgnoreCase(LadderManager.LADDER_PRESTIGES); PlayerRank nextRank = rPlayer.getNextPlayerRank(); Rank nRank = nextRank == null ? null : nextRank.getRank(); @@ -470,7 +393,6 @@ public void prestigeCmd(CommandSender sender, if ( isConfirmGUI && isPlayer ) { // call the gui prestige confirmation: -// callGuiPrestigeConfirmation( sender, ); String guiConfirmParms = prestigeConfirmationGUIMsg( sender, rPlayer, nextRank, isResetDefaultLadder, isResetMoney ); @@ -488,70 +410,35 @@ public void prestigeCmd(CommandSender sender, } if ( isPrestigeBypassPermCheck || - isPrestigesEnabled && hasPrestigePerm ) { - Output.get().logDebug( DebugTarget.rankup, - "Rankup: cmd '/prestige %s%s' [%s]", - (playerName.length() == 0 ? "" : " " + playerName ), - (confirm == null ? "" : " " + confirm ), - permsCheck ); - - - List cmdTasks = new ArrayList<>(); - - String ladder = nRank.getLadder().getName(); - rankUpPrivate(sender, rPlayer, ladder, RankupModes.ONE_RANK, perms, cmdTasks, null ); -// rankUpPrivate(sender, playerName, ladder, RankupModes.ONE_RANK, perms, cmdTasks, null ); - - // submit cmdTasks -// Player player = getPlayer( sender, playerName ); - submitCmdTasks( rPlayer, cmdTasks ); + Output.get().logDebug( DebugTarget.rankup, + "Rankup: cmd '/prestige %s%s' [%s]", + (playerName.length() == 0 ? "" : " " + playerName ), + (confirm == null ? "" : " " + confirm ), + permsCheck ); + + + List cmdTasks = new ArrayList<>(); + + String ladder = nRank.getLadder().getName(); + rankUpPrivate(sender, rPlayer, ladder, RankupModes.ONE_RANK, perms, cmdTasks, null ); + + // submit cmdTasks + submitCmdTasks( rPlayer, cmdTasks ); } else { -// Player player = getPlayer( sender, playerName ); - Output.get().logDebug( DebugTarget.rankup, - "Rankup: Failed: cmd '/prestige %s%s' Does not have the permission %s. [%s]", - (playerName.length() == 0 ? "" : " " + playerName ), - (confirm == null ? "" : " " + confirm ), - permsCheck ); - - //prestigeNoPermissionMsg( sender, "ranks.rankup.prestiges", player.getRankPlayer() ); - } + Output.get().logDebug( DebugTarget.rankup, + "Rankup: Failed: cmd '/prestige %s%s' Does not have the permission %s. [%s]", + (playerName.length() == 0 ? "" : " " + playerName ), + (confirm == null ? "" : " " + confirm ), + permsCheck ); + + } } -// private boolean rankUpPrivateX(CommandSender sender, -// String playerName, -// String ladder, RankupModes mode, -// String permission, -// List cmdTasks, -// StringBuilder sbRanks ) { -// -// boolean rankupSuccess = false; -// -// if ( sender.isPlayer() ) { -// playerName = ""; -// } -// -// if ( !sender.isPlayer() && playerName.length() == 0 ) { -// Output.get().logInfo( rankupCannotRunFromConsoleMsg() ); -// return false; -// } -// -// -// // Player will always be the player since they have to be online and must be a player: -// Player player = getPlayerByName( playerName ); -// -// if ( player == null ) { -// rankupInvalidPlayerNameMsg( sender, playerName ); -// return false; -// } -// -// -// return rankupSuccess; -// } private boolean rankUpPrivate(CommandSender sender, RankPlayer rankPlayer, @@ -563,72 +450,13 @@ private boolean rankUpPrivate(CommandSender sender, boolean rankupSuccess = false; - // RETRIEVE THE LADDER -// // Perms have already been checked on the RankupModes.MAX_RANKS: -// if ( mode != RankupModes.MAX_RANKS ) { -// -// boolean isPrestigesEnabled = Prison.get().getPlatform().getConfigBooleanFalse( "prestiges" ) || -// Prison.get().getPlatform().getConfigBooleanFalse( "prestige.enabled" ); -// -// boolean isLadderPrestiges = ladder.equalsIgnoreCase(LadderManager.LADDER_PRESTIGES); -// boolean isLadderDefault = ladder.equalsIgnoreCase(LadderManager.LADDER_DEFAULT); -// -// String permCheck = permission + ladder.toLowerCase(); -// -// // This player has to have permission to rank up on this ladder, but -// // ignore if either the default or prestiges ladder. This only is to check for -// // other ladders. -// if (!( isLadderPrestiges && isPrestigesEnabled ) && -// !isLadderDefault && -// !sender.hasPermission( permCheck )) { -// -// Output.get().logDebug( DebugTarget.rankup, -// "Rankup: rankUpPrivate: failed rankup perm check. Missing perm: %s", -// permCheck ); -// -// rankupMaxNoPermissionMsg( sender, permCheck ); -// return false; -// } -// -// } - - - // if ( mode == null ) { - Output.get().logInfo( rankupInternalFailureMsg() ); - return false; + Output.get().logInfo( rankupInternalFailureMsg() ); + return false; } - -// if ( sender.isPlayer() ) { -// playerName = ""; -// } -// -// if ( !sender.isPlayer() && playerName.length() == 0 ) { -// Output.get().logInfo( rankupCannotRunFromConsoleMsg() ); -// return false; -// } -// -// -// // Player will always be the player since they have to be online and must be a player: -// Player player = getPlayer( sender, playerName ); -// -// if ( player == null ) { -// rankupInvalidPlayerNameMsg( sender, playerName ); -// return false; -// } - - - - - //UUID playerUuid = player.getUUID(); -// RankPlayer rankPlayer = -// player == null ? -// sender.getRankPlayer() : -// player instanceof RankPlayer ? (RankPlayer) player : -// player.getRankPlayer(); - + // RETRIEVE THE LADDER ladder = confirmLadder( sender, ladder, rankPlayer ); if ( ladder == null ) { @@ -640,30 +468,26 @@ private boolean rankUpPrivate(CommandSender sender, RankLadder targetLadder = lm.getLadder( ladder ); if ( targetLadder == null ){ - rankupErrorNoLadderMsg( sender, ladder ); - return false; - } - - if (!targetLadder.getLowestRank().isPresent()){ - rankupErrorNoRankOnLadderMsg( sender, ladder ); - return false; - } + rankupErrorNoLadderMsg( sender, ladder ); + return false; + } + + if (!targetLadder.getLowestRank().isPresent()){ + rankupErrorNoRankOnLadderMsg( sender, ladder ); + return false; + } - - - PlayerRank rankCurrent = rankPlayer.getPlayerRank(ladder); // 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, rankPlayer ); - return false; + rankupAtLastRankMsg(sender, rankPlayer ); + 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 @@ -672,59 +496,44 @@ private boolean rankUpPrivate(CommandSender sender, if ( targetLadder.isDefault() || targetLadder.isPrestiges() ) { - playerRankTarget = rankPlayer.getNextPlayerRank(); - - // If the nextRank is null or the ladder does not match selected ladder, then exit: - if ( playerRankTarget == null || playerRankTarget.getRank() == null ) { - - if ( Output.get().isDebug() ) { - Output.get().logInfo( - "RankUp ladder= %s currentRank= %s " - + "No next default or prestige rank. At end of both ladders?", - ladder, rankCurrent.getRank().getName() ); - } - - return false; - } + playerRankTarget = rankPlayer.getNextPlayerRank(); + + // If the nextRank is null or the ladder does not match selected ladder, then exit: + if ( playerRankTarget == null || playerRankTarget.getRank() == null ) { + + if ( Output.get().isDebug() ) { + Output.get().logInfo( + "RankUp ladder= %s currentRank= %s " + + "No next default or prestige rank. At end of both ladders?", + ladder, rankCurrent.getRank().getName() ); + } + + return false; + } } - RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); - - // If ranking up on neither default or prestige ladders: if ( !targetLadder.isDefault() && !targetLadder.isPrestiges() ) { - - PlayerRank playerRankCurrent = rankPlayerFactory.getRank( rankPlayer, ladder ); -// PlayerRank playerRankCurrent = rankPlayer.getPlayerRankDefault(); - - - // If the player does not have a rank on the current ladder, then assign the - // default rank for the ladder to be their next rank. - if ( playerRankCurrent == null ) { - - playerRankTarget = rankPlayer.calculateTargetPlayerRank( - targetLadder.getLowestRank().get() ); - -// playerRankTarget = rankPlayerFactory.createPlayerRank( -// targetLadder.getLowestRank().get() ); - } - else { - - playerRankTarget = rankPlayer.calculateTargetPlayerRank( playerRankCurrent.getRank() ); -// playerRankTarget = playerRankCurrent.getTargetPlayerRankForPlayer( rankPlayer, -// playerRankCurrent.getRank() ); - } + PlayerRank playerRankCurrent = rankPlayerFactory.getRank( rankPlayer, ladder ); + + // If the player does not have a rank on the current ladder, then assign the + // default rank for the ladder to be their next rank. + if ( playerRankCurrent == null ) { + + playerRankTarget = rankPlayer.calculateTargetPlayerRank( + targetLadder.getLowestRank().get() ); + } + else { + + playerRankTarget = rankPlayer.calculateTargetPlayerRank( playerRankCurrent.getRank() ); + } } - - - - Output.get().logDebug( DebugTarget.rankup, @@ -786,47 +595,33 @@ private boolean rankUpPrivate(CommandSender sender, if (rankPlayer != null ) { - // Performs the actual rankup here: - RankupResults results = new RankUtil().rankupPlayer(rankPlayer, rankPlayer, ladder, - sender.getName(), cmdTasks ); -// RankupResults results = new RankUtil().rankupPlayer(player, rankPlayer, ladder, -// sender.getName(), cmdTasks ); - - - processResults( sender, rankPlayer.getName(), results, null, ladder, currency, sbRanks, mode ); - - // If the last rankup attempt was successful and they are trying to rankup as many times as possible: - // Note they used to restrict rankupmax from working on prestige ladder... - if (results.getStatus() == RankupStatus.RANKUP_SUCCESS && mode == RankupModes.MAX_RANKS ) { -// if (results.getStatus() == RankupStatus.RANKUP_SUCCESS && mode == RankupModes.MAX_RANKS && -// !ladder.equals(LadderManager.LADDER_PRESTIGES)) { - rankUpPrivate( sender, rankPlayer, ladder, mode, permission, cmdTasks, sbRanks ); - } - if (results.getStatus() == RankupStatus.RANKUP_SUCCESS){ - rankupSuccess = true; - } - - - // Get the player rank after -// PlayerRank playerRankAfter = rankPlayer.getNextPlayerRank(); -// PlayerRank playerRankAfter = rankPlayerFactory.getRank( rankPlayer, ladder ); - -// if ( playerRankAfter != null ) { -// -// pRankAfter = playerRankAfter.getRank(); -// } - - // Prestige method if canPrestige and a successful rankup. - // pRankTarget now contains the target rank prior to processing the rankup. SO it should be - // the same as pRankAfter, but if it is wrong, then rankupWithSuccess will not be true. So ignore... - if ( canPrestige && rankupSuccess ) { - prestigePlayer( sender, rankPlayer, lm, cmdTasks, sbRanks ); -// prestigePlayer( sender, player, rankPlayer, pRankAfter, lm ); - - } - else if ( canPrestige ) { - rankupNotAbleToPrestigeMsg( sender, rankPlayer ); - } + // Performs the actual rankup here: + RankupResults results = new RankUtil().rankupPlayer(rankPlayer, rankPlayer, ladder, + sender.getName(), cmdTasks ); + + + processResults( sender, rankPlayer.getName(), results, null, ladder, currency, sbRanks, mode ); + + // If the last rankup attempt was successful and they are trying to rankup as many times as possible: + // Note they used to restrict rankupmax from working on prestige ladder... + if (results.getStatus() == RankupStatus.RANKUP_SUCCESS && mode == RankupModes.MAX_RANKS ) { + rankUpPrivate( sender, rankPlayer, ladder, mode, permission, cmdTasks, sbRanks ); + } + if (results.getStatus() == RankupStatus.RANKUP_SUCCESS){ + rankupSuccess = true; + } + + + // Prestige method if canPrestige and a successful rankup. + // pRankTarget now contains the target rank prior to processing the rankup. SO it should be + // the same as pRankAfter, but if it is wrong, then rankupWithSuccess will not be true. So ignore... + if ( canPrestige && rankupSuccess ) { + prestigePlayer( sender, rankPlayer, lm, cmdTasks, sbRanks ); + + } + else if ( canPrestige ) { + rankupNotAbleToPrestigeMsg( sender, rankPlayer ); + } } @@ -870,48 +665,28 @@ private void prestigePlayer(CommandSender sender, RankPlayer rankPlayer, if ( resetDefaultLadder ) { - // Get the player rank after, just to check if it has success Conditions -// if (willPrestige && rankupWithSuccess && pRankAfter != null && pRank != pRankAfter) { - // Set the player rank to the first one of the default ladder - - RankLadder ladder = lm.getLadder(LadderManager.LADDER_DEFAULT); Rank dRank = ladder.getLowestRank().get(); setPlayerRank( rankPlayer, ladder, dRank, sender, cmdTasks, sbRanks ); - -// String ladderName = LadderManager.LADDER_DEFAULT; -// String defaultRank = lm.getLadder(LadderManager.LADDER_DEFAULT).getLowestRank().get().getName(); -// -// setPlayerRank( rankPlayer, defaultRank, ladderName, sender ); + PlayerRank playerRankSecond = rankPlayer.getPlayerRankDefault(); - // Call the function directly and skip using dispatch commands: -// setRank( sender, player.getName(), -// lm.getLadder(LadderManager.LADDER_DEFAULT).getLowestRank().get().getName(), -// LadderManager.LADDER_DEFAULT ); - + if ( playerRankSecond != null ) { - PlayerRank playerRankSecond = rankPlayer.getPlayerRankDefault(); + Rank pRankSecond = playerRankSecond.getRank(); + // Check if the ranks match - - - if ( playerRankSecond != null ) { - - Rank pRankSecond = playerRankSecond.getRank(); - // Check if the ranks match - - if ( !pRankSecond.equals( lm.getLadder(LadderManager.LADDER_DEFAULT).getLowestRank().get()) ) { - - rankupNotAbleToResetRankMsg( sender, rankPlayer ); - success = false; - } - } - else { + if ( !pRankSecond.equals( lm.getLadder(LadderManager.LADDER_DEFAULT).getLowestRank().get()) ) { rankupNotAbleToResetRankMsg( sender, rankPlayer ); success = false; } -// } + } + else { + + rankupNotAbleToResetRankMsg( sender, rankPlayer ); + success = false; + } } if ( success && resetBalance ) { @@ -931,13 +706,11 @@ private void prestigePlayer(CommandSender sender, RankPlayer rankPlayer, String title = newPRank == null || newPRank.getTag() == null ? newPRank.getName() : newPRank.getTag(); - if ( success ) { - // Send a message to the player because he did prestige! + if ( success ) { prestigePlayerSucessfulMsg( sender, title, rankPlayer ); } else { - prestigePlayerFailureMsg( sender, title, rankPlayer ); } @@ -970,34 +743,21 @@ public void promotePlayer(CommandSender sender, def = "no_charge") String chargePlayer ) { - - RankPlayer rPlayer = getRankPlayer(sender, null, playerName); if ( rPlayer == null ) { - rankupInvalidPlayerNameMsg( sender, playerName ); - return; + rankupInvalidPlayerNameMsg( sender, playerName ); + return; } - -// Player player = getPlayerByName( playerName ); -// -//// if (player == null) { -//// ranksPromotePlayerMustBeOnlineMsg( sender ); -//// return; -//// } - -// UUID playerUuid = player.getUUID(); - - RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); -// RankPlayer rankPlayer = getRankPlayer( sender, playerUuid, player.getName() ); - - PromoteForceCharge pForceCharge = PromoteForceCharge.fromString( chargePlayer ); - if ( pForceCharge == null|| pForceCharge == PromoteForceCharge.refund_player ) { - - ranksPromotePlayerInvalidChargeValueMsg( sender, rPlayer ); - return; - } + RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); + + PromoteForceCharge pForceCharge = PromoteForceCharge.fromString( chargePlayer ); + if ( pForceCharge == null|| pForceCharge == PromoteForceCharge.refund_player ) { + + ranksPromotePlayerInvalidChargeValueMsg( sender, rPlayer ); + return; + } ladder = confirmLadder( sender, ladder, rPlayer ); @@ -1033,9 +793,9 @@ public void promotePlayer(CommandSender sender, } else { - // Message: Player is not on the ladder - sender.sendMessage( "Promote: Player is not on the specified ladder. " - + "Try using '/ranks set rank' to add them."); + // Message: Player is not on the ladder + sender.sendMessage( "Promote: Player is not on the specified ladder. " + + "Try using '/ranks set rank' to add them."); } } @@ -1060,26 +820,16 @@ public void demotePlayer(CommandSender sender, RankPlayer rPlayer = getRankPlayer(sender, null, playerName); if ( rPlayer == null ) { - rankupInvalidPlayerNameMsg( sender, playerName ); - return; + rankupInvalidPlayerNameMsg( sender, playerName ); + return; } - -// Player player = getPlayer( sender, playerName ); -// -// if (player == null) { -// ranksPromotePlayerMustBeOnlineMsg( sender ); -// return; -// } - -// UUID playerUuid = player.getUUID(); -// RankPlayer rankPlayer = getRankPlayer( sender, playerUuid, player.getName() ); - - PromoteForceCharge pForceCharge = PromoteForceCharge.fromString( refundPlayer ); - if ( pForceCharge == null || pForceCharge == PromoteForceCharge.charge_player ) { - ranksDemotePlayerInvalidRefundValueMsg( sender, rPlayer ); - return; - } + + PromoteForceCharge pForceCharge = PromoteForceCharge.fromString( refundPlayer ); + if ( pForceCharge == null || pForceCharge == PromoteForceCharge.charge_player ) { + ranksDemotePlayerInvalidRefundValueMsg( sender, rPlayer ); + return; + } ladder = confirmLadder( sender, ladder, rPlayer ); if ( ladder == null ) { @@ -1093,32 +843,32 @@ public void demotePlayer(CommandSender sender, if ( rPlayer != null && playerRank != null ) { - Rank pRank = playerRank.getRank(); - if ( pRank == null ) { - sender.sendMessage( "Demote: There was an error trying to access the " - + "current rank of the player. Try viewing the player's " - + "details: '/ranks player help'."); - return; - } - - // Get currency if it exists, otherwise it will be null if the Rank has no currency: - String currency = pRank.getCurrency(); - - List cmdTasks = new ArrayList<>(); - - RankupResults results = new RankUtil().demotePlayer( rPlayer, rPlayer, ladder, - rPlayer.getName(), sender.getName(), pForceCharge, cmdTasks ); - - // submit cmdTasks - submitCmdTasks( rPlayer, cmdTasks ); - - processResults( sender, rPlayer.getName(), results, null, ladder, currency, null, RankupModes.ONE_RANK ); - + Rank pRank = playerRank.getRank(); + if ( pRank == null ) { + sender.sendMessage( "Demote: There was an error trying to access the " + + "current rank of the player. Try viewing the player's " + + "details: '/ranks player help'."); + return; + } + + // Get currency if it exists, otherwise it will be null if the Rank has no currency: + String currency = pRank.getCurrency(); + + List cmdTasks = new ArrayList<>(); + + RankupResults results = new RankUtil().demotePlayer( rPlayer, rPlayer, ladder, + rPlayer.getName(), sender.getName(), pForceCharge, cmdTasks ); + + // submit cmdTasks + submitCmdTasks( rPlayer, cmdTasks ); + + processResults( sender, rPlayer.getName(), results, null, ladder, currency, null, RankupModes.ONE_RANK ); + } else { - // Message: Player is not on the ladder - sender.sendMessage( "Demote: Player is not on the specified ladder. " - + "Try using '/ranks set rank' to add them."); + // Message: Player is not on the ladder + sender.sendMessage( "Demote: Player is not on the specified ladder. " + + "Try using '/ranks set rank' to add them."); } } @@ -1137,41 +887,37 @@ public void setRank(CommandSender sender, "to deleete the player from the rank.") String rank, @Arg(name = "ladder", description = "The ladder to demote on.", def = "default") String ladder) { - if ( "*all*".equalsIgnoreCase( playerName )) { - PlayerManager pm = PrisonRanks.getInstance().getPlayerManager(); - - RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); - - for ( RankPlayer player : pm.getPlayers() ) { - -// Player targetPlayer = getPlayerByName( player.getName() ); -// if ( targetPlayer != null ) { - - boolean isSameRank = rank.equalsIgnoreCase("*same*"); - - PlayerRank pRank = rankPlayerFactory.getRank( player, ladder ); - String rankNameCurrent = isSameRank && - pRank != null && - pRank.getRank() != null ? - pRank.getRank().getName() : ""; - - String targetRank = isSameRank ? rankNameCurrent : rank; - setPlayerRank( player, targetRank, ladder, sender ); -// } - } - - } - else { - - Player player = getPlayerByName( playerName ); - - if (player == null) { - ranksPromotePlayerMustBeOnlineMsg( sender ); - return; - } - - setPlayerRank( player.getRankPlayer(), rank, ladder, sender ); - } + if ( "*all*".equalsIgnoreCase( playerName )) { + PlayerManager pm = PrisonRanks.getInstance().getPlayerManager(); + + RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); + + for ( RankPlayer player : pm.getPlayers() ) { + + boolean isSameRank = rank.equalsIgnoreCase("*same*"); + + PlayerRank pRank = rankPlayerFactory.getRank( player, ladder ); + String rankNameCurrent = isSameRank && + pRank != null && + pRank.getRank() != null ? + pRank.getRank().getName() : ""; + + String targetRank = isSameRank ? rankNameCurrent : rank; + setPlayerRank( player, targetRank, ladder, sender ); + } + + } + else { + + Player player = getPlayerByName( playerName ); + + if (player == null) { + ranksPromotePlayerMustBeOnlineMsg( sender ); + return; + } + + setPlayerRank( player.getRankPlayer(), rank, ladder, sender ); + } } @@ -1182,7 +928,7 @@ public void removeRank(CommandSender sender, @Arg(name = "playerName", def = "", description = "Player name") String playerName, @Arg(name = "ladder", description = "The ladder to demote on.", def = "default") String ladder) { - setRank( sender, playerName, "-remove-", ladder ); + setRank( sender, playerName, "-remove-", ladder ); } @@ -1191,21 +937,20 @@ public void setPlayerRank( RankPlayer rankPlayer, Rank pRank ) { if ( rankPlayer != null ) { - List cmdTasks = new ArrayList<>(); - - RankupResults results = - new RankUtil().setRank(rankPlayer, rankPlayer, - pRank.getLadder().getName(), pRank.getName(), - rankPlayer.getName(), rankPlayer.getName(), - cmdTasks ); - - // submit cmdTasks -// Player player = getPlayerByName( rankPlayer.getName() ); + List cmdTasks = new ArrayList<>(); + + RankupResults results = + new RankUtil().setRank(rankPlayer, rankPlayer, + pRank.getLadder().getName(), pRank.getName(), + rankPlayer.getName(), rankPlayer.getName(), + cmdTasks ); + + // submit cmdTasks submitCmdTasks( rankPlayer, cmdTasks ); - - processResults( rankPlayer, rankPlayer.getName(), results, - pRank.getName(), pRank.getLadder().getName(), - pRank.getCurrency(), null, RankupModes.ONE_RANK ); + + processResults( rankPlayer, rankPlayer.getName(), results, + pRank.getName(), pRank.getLadder().getName(), + pRank.getCurrency(), null, RankupModes.ONE_RANK ); } } @@ -1218,24 +963,23 @@ public void setPlayerRank( RankPlayer rankPlayer, Rank pRank ) { */ public void setPlayerRankFirstJoin( RankPlayer rankPlayer, Rank pRank ) { - if ( rankPlayer != null ) { - - List cmdTasks = new ArrayList<>(); - - RankupResults results = - new RankUtil().setRank(rankPlayer, rankPlayer, - pRank.getLadder().getName(), pRank.getName(), - rankPlayer.getName(), "FirstJoinEvent", - cmdTasks ); - - // submit cmdTasks -// Player player = getPlayer( null, rankPlayer.getName() ); - submitCmdTasks( rankPlayer, cmdTasks ); - - processResults( rankPlayer, rankPlayer.getName(), results, - pRank.getName(), pRank.getLadder().getName(), - pRank.getCurrency(), null, RankupModes.ONE_RANK ); - } + if ( rankPlayer != null ) { + + List cmdTasks = new ArrayList<>(); + + RankupResults results = + new RankUtil().setRank(rankPlayer, rankPlayer, + pRank.getLadder().getName(), pRank.getName(), + rankPlayer.getName(), "FirstJoinEvent", + cmdTasks ); + + // submit cmdTasks + submitCmdTasks( rankPlayer, cmdTasks ); + + processResults( rankPlayer, rankPlayer.getName(), results, + pRank.getName(), pRank.getLadder().getName(), + pRank.getCurrency(), null, RankupModes.ONE_RANK ); + } } @@ -1243,47 +987,44 @@ private void setPlayerRank( RankPlayer rankPlayer, RankLadder ladder, Rank pRank CommandSender sender, List cmdTasks, StringBuilder sbRanks ) { - // Get currency if it exists, otherwise it will be null if the Rank has no currency: - String currency = rankPlayer == null || pRank == null ? null : pRank.getCurrency(); - - - RankupResults results = new RankUtil().setRank( rankPlayer, rankPlayer, - ladder.getName(), pRank.getName(), - rankPlayer.getName(), sender.getName(), cmdTasks ); - - - processResults( sender, rankPlayer.getName(), results, pRank.getName(), ladder.getName(), - currency, sbRanks, RankupModes.ONE_RANK ); + // Get currency if it exists, otherwise it will be null if the Rank has no currency: + String currency = rankPlayer == null || pRank == null ? null : pRank.getCurrency(); + + + RankupResults results = new RankUtil().setRank( rankPlayer, rankPlayer, + ladder.getName(), pRank.getName(), + rankPlayer.getName(), sender.getName(), cmdTasks ); + + + processResults( sender, rankPlayer.getName(), results, pRank.getName(), ladder.getName(), + currency, sbRanks, RankupModes.ONE_RANK ); } private void setPlayerRank( RankPlayer rankPlayer, String rank, String ladderName, CommandSender sender ) { -// UUID playerUuid = player.getUUID(); Output.get().logDebug( DebugTarget.rankup, "Rankup: setPlayerRank: "); -// RankPlayer rankPlayer = getRankPlayer( sender, playerUuid, player.getName() ); ladderName = confirmLadder( sender, ladderName, rankPlayer ); if ( ladderName != null && rankPlayer != null ) { -// RankLadder rLadder = PrisonRanks.getInstance().getLadderManager().getLadder( ladderName ); - - Rank pRank = PrisonRanks.getInstance().getRankManager().getRank( rank ); - - // Get currency if it exists, otherwise it will be null if the Rank has no currency: - String currency = rankPlayer == null || pRank == null ? null : pRank.getCurrency(); - - List cmdTasks = new ArrayList<>(); - RankupResults results = new RankUtil().setRank(rankPlayer, rankPlayer, ladderName, rank, - rankPlayer.getName(), sender.getName(), cmdTasks ); - - // submit cmdTasks + Rank pRank = PrisonRanks.getInstance().getRankManager().getRank( rank ); + + // Get currency if it exists, otherwise it will be null if the Rank has no currency: + String currency = rankPlayer == null || pRank == null ? null : pRank.getCurrency(); + + List cmdTasks = new ArrayList<>(); + + RankupResults results = new RankUtil().setRank(rankPlayer, rankPlayer, ladderName, rank, + rankPlayer.getName(), sender.getName(), cmdTasks ); + + // submit cmdTasks submitCmdTasks( rankPlayer, cmdTasks ); - - processResults( sender, rankPlayer.getName(), results, rank, ladderName, currency, null, RankupModes.ONE_RANK ); + + processResults( sender, rankPlayer.getName(), results, rank, ladderName, currency, null, RankupModes.ONE_RANK ); } } @@ -1296,10 +1037,10 @@ private String confirmLadder( CommandSender sender, String ladderName, RankPlaye // The ladder doesn't exist if ( ladder == null ) { - ranksConfirmLadderMsg( sender, ladderName, rPlayer ); + ranksConfirmLadderMsg( sender, ladderName, rPlayer ); } else { - results = ladder.getName(); + results = ladder.getName(); } return results; } @@ -1323,7 +1064,7 @@ public RankPlayer getRankPlayer( CommandSender sender, UUID playerUuid, String p // Well, this isn't supposed to happen... if ( player == null ) { - ranksRankupFailureToGetRankPlayerMsg( sender ); + ranksRankupFailureToGetRankPlayerMsg( sender ); } return player; @@ -1339,62 +1080,72 @@ public void processResults( CommandSender sender, String playerName, switch (results.getStatus()) { case RANKUP_SUCCESS: - ranksRankupSuccessMsg( sender, playerName, results, sbRanks ); - - break; + ranksRankupSuccessMsg( sender, playerName, results, sbRanks ); + + break; case DEMOTE_SUCCESS: - ranksRankupSuccessMsg( sender, playerName, results, null ); - - break; + ranksRankupSuccessMsg( sender, playerName, results, null ); + + break; + case RANKUP_CANT_AFFORD: - // If mode is MAX_RANKS and was already successful, then do not display - // cannot afford message when it hits the end of the max rankups... - if ( mode != RankupModes.MAX_RANKS || - mode == RankupModes.MAX_RANKS && sbRanks.length() == 0 ) { - - ranksRankupCannotAffordMsg( sender, results ); - } + // If mode is MAX_RANKS and was already successful, then do not display + // cannot afford message when it hits the end of the max rankups... + if ( mode != RankupModes.MAX_RANKS || + mode == RankupModes.MAX_RANKS && sbRanks.length() == 0 ) { + + ranksRankupCannotAffordMsg( sender, results ); + } + break; - break; case RANKUP_LOWEST: - ranksRankupLowestRankMsg( sender, playerName, results ); + ranksRankupLowestRankMsg( sender, playerName, results ); + + break; - break; case RANKUP_HIGHEST: - ranksRankupHighestRankMsg( sender, playerName, results ); + ranksRankupHighestRankMsg( sender, playerName, results ); - break; + break; + case RANKUP_FAILURE: - ranksRankupFailureMsg( sender, results.getRankPlayer() ); + ranksRankupFailureMsg( sender, results.getRankPlayer() ); - break; + break; + case RANKUP_FAILURE_COULD_NOT_LOAD_PLAYER: - ranksRankupFailureCouldNotLoadPlayerMsg( sender, results.getRankPlayer() ); + ranksRankupFailureCouldNotLoadPlayerMsg( sender, results.getRankPlayer() ); - break; + break; + case RANKUP_FAILURE_COULD_NOT_LOAD_LADDER: - ranksRankupFailureCouldNotLoadLadderMsg( sender, results.getRankPlayer() ); + ranksRankupFailureCouldNotLoadLadderMsg( sender, results.getRankPlayer() ); - break; + break; + case RANKUP_FAILURE_UNABLE_TO_ASSIGN_RANK: - ranksRankupFailureUnableToAssignRankMsg( sender, results.getRankPlayer() ); + ranksRankupFailureUnableToAssignRankMsg( sender, results.getRankPlayer() ); - break; + break; + case RANKUP_FAILURE_COULD_NOT_SAVE_PLAYER_FILE: - ranksRankupFailureCouldNotSavePlayerFileMsg( sender, results.getRankPlayer() ); + ranksRankupFailureCouldNotSavePlayerFileMsg( sender, results.getRankPlayer() ); - break; + break; + case RANKUP_NO_RANKS: - ranksRankupFailureNoRanksMsg( sender, results.getRankPlayer() ); + ranksRankupFailureNoRanksMsg( sender, results.getRankPlayer() ); - break; + break; + case RANKUP_FAILURE_RANK_DOES_NOT_EXIST: - ranksRankupFailureRankDoesNotExistMsg( sender, rank, results.getRankPlayer() ); + ranksRankupFailureRankDoesNotExistMsg( sender, rank, results.getRankPlayer() ); - break; - case RANKUP_FAILURE_RANK_IS_NOT_IN_LADDER: + break; + + case RANKUP_FAILURE_RANK_IS_NOT_IN_LADDER: ranksRankupFailureRankIsNotInLadderMsg( sender, rank, ladder, results.getRankPlayer() ); break; @@ -1427,6 +1178,7 @@ public void processResults( CommandSender sender, String playerName, ranksRankupFailureInProgressMsg( sender, results.getRankPlayer() ); break; + default: break; } @@ -1437,16 +1189,12 @@ private void submitCmdTask( Player player, String command ) { Scheduler scheduler = Prison.get().getPlatform().getScheduler(); scheduler.performCommand( player, command ); -// scheduler.dispatchCommand( player, command ); - -// PrisonCommandTaskData task = new PrisonCommandTaskData( errorPrefix, command ); -// PrisonCommandTasks.submitTasks( player, task ); } private void submitCmdTasks( Player player, List cmdTasks ) { - PrisonCommandTasks.submitTasks( player, cmdTasks ); + PrisonCommandTasks.submitTasks( player, cmdTasks ); } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RankUpCommandMessages.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RankUpCommandMessages.java index b3107a1fc..21d1f032d 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RankUpCommandMessages.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RankUpCommandMessages.java @@ -35,8 +35,8 @@ protected void rankupMaxNoPermissionMsg( CommandSender sender, String permission protected String rankupCannotRunFromConsoleMsg() { return PrisonRanks.getInstance().getRanksMessages() - .getLocalizable( "ranks_rankup__cannot_run_from_console" ) - .localize(); + .getLocalizable( "ranks_rankup__cannot_run_from_console" ) + .localize(); } protected void rankupInvalidPlayerNameMsg(CommandSender sender, String playerName) { @@ -66,24 +66,24 @@ protected void rankupErrorNoLowerRankMsg( CommandSender sender ) { protected void rankupErrorNoLadderMsg( CommandSender sender, String ladderName ) { PrisonRanks.getInstance().getRanksMessages() - .getLocalizable( "ranks_rankup__error_no_ladder" ) - .withReplacements( ladderName ) - .sendTo( sender ); + .getLocalizable( "ranks_rankup__error_no_ladder" ) + .withReplacements( ladderName ) + .sendTo( sender ); } protected void rankupErrorNoRankOnLadderMsg( CommandSender sender, String ladderName ) { PrisonRanks.getInstance().getRanksMessages() - .getLocalizable( "ranks_rankup__error_no_lower_rank_on_ladder" ) - .withReplacements( ladderName ) - .sendTo( sender ); + .getLocalizable( "ranks_rankup__error_no_lower_rank_on_ladder" ) + .withReplacements( ladderName ) + .sendTo( sender ); } protected void rankupErrorPlayerNotOnDefaultLadder( CommandSender sender, RankPlayer rankPlayer ) { PrisonRanks.getInstance().getRanksMessages() - .getLocalizable( "ranks_rankup__error_player_not_on_default_ladder" ) - .withReplacements( rankPlayer.getName() ) - .sendTo( sender ); + .getLocalizable( "ranks_rankup__error_player_not_on_default_ladder" ) + .withReplacements( rankPlayer.getName() ) + .sendTo( sender ); } protected void rankupNotAtLastRankMsg( CommandSender sender, @@ -96,8 +96,8 @@ protected void rankupNotAtLastRankMsg( CommandSender sender, protected void rankupAtLastRankMsg( CommandSender sender, RankPlayer rPlayer ) { PrisonRanks.getInstance().getRanksMessages() - .getLocalizable( "ranks_rankup__at_last_rank" ) - .sendTo( sender, rPlayer ); + .getLocalizable( "ranks_rankup__at_last_rank" ) + .sendTo( sender, rPlayer ); } protected void rankupNotAbleToPrestigeMsg( CommandSender sender, @@ -134,9 +134,9 @@ protected void prestigePlayerSucessfulMsg( CommandSender sender, String tag, protected void prestigePlayerSucessfulBroadcastMsg( CommandSender sender, String tag, RankPlayer rPlayer ) { PrisonRanks.getInstance().getRanksMessages() - .getLocalizable( "ranks_rankup__prestige_successful_broadcast" ) - .withReplacements( tag ) - .sendTo( sender, rPlayer ); + .getLocalizable( "ranks_rankup__prestige_successful_broadcast" ) + .withReplacements( tag ) + .sendTo( sender, rPlayer ); } protected void prestigePlayerFailureMsg( CommandSender sender, String tag, @@ -233,7 +233,7 @@ protected void prestigeConfirmationMsg( CommandSender sender, .sendTo( sender, rPlayer ); rMsg.getLocalizable( "ranks_rankup__confirm_prestige_line_3" ) - .withReplacements( + .withReplacements( dFmt.format( balance), currency == null || currency.trim().length() == 0 ? "" : " " + currency ) @@ -275,7 +275,7 @@ protected void ranksRankupPlayerBalanceMsg( CommandSender sender, LocaleManager rMsg = PrisonRanks.getInstance().getRanksMessages(); rMsg.getLocalizable( "ranks_rankup__confirm_prestige_line_3" ) - .withReplacements( + .withReplacements( dFmt.format( balance), currency == null || currency.trim().length() == 0 ? "" : " " + currency ) @@ -334,7 +334,6 @@ protected void ranksRankupSuccessMsg( CommandSender sender, String playerName, RankPlayer rPlayer = results.getRankPlayer(); -// PlayerRank tpRank = results.getPlayerRankTarget(); Rank tRank = results.getTargetRank(); @@ -350,108 +349,96 @@ protected void ranksRankupSuccessMsg( CommandSender sender, String playerName, "ranks_rankup__demote_success" : "ranks_rankup__rankup_success" ; - String messagNoPlayerName = PrisonRanks.getInstance().getRanksMessages() - .getLocalizable( "ranks_rankup__rankup_no_player_name" ).localize(); - - Localizable localManager = PrisonRanks.getInstance().getRanksMessages() - .getLocalizable( messageId ) - .withReplacements( - - (playerName == null ? messagNoPlayerName : playerName), - (tRank == null ? "" : tRank.getTag() ), - (results.getMessage() != null ? results.getMessage() : "") - ); - - Localizable localManagerLog = PrisonRanks.getInstance().getRanksMessages() - .getLocalizable( "ranks_rankup__log_rank_change" ) - .withReplacements( - - sender.getName(), localManager.localize() - ); - Output.get().logInfo( - rPlayer.convertStringPlaceholders( - localManagerLog.localize() )); + String messagNoPlayerName = PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( "ranks_rankup__rankup_no_player_name" ).localize(); + + Localizable localManager = PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( messageId ) + .withReplacements( + + (playerName == null ? messagNoPlayerName : playerName), + (tRank == null ? "" : tRank.getTag() ), + (results.getMessage() != null ? results.getMessage() : "") + ); + + Localizable localManagerLog = PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( "ranks_rankup__log_rank_change" ) + .withReplacements( + + sender.getName(), localManager.localize() + ); + Output.get().logInfo( + rPlayer.convertStringPlaceholders( + localManagerLog.localize() )); - if ( Prison.get().getPlatform().getConfigBooleanFalse( "broadcast-rankups" ) ) { - String messagNoPlayerNameBroadcast = PrisonRanks.getInstance().getRanksMessages() - .getLocalizable( "ranks_rankup__rankup_no_player_name_broadcast" ).localize(); - - PrisonRanks.getInstance().getRanksMessages() - .getLocalizable( messageId ) - .withReplacements( - - (playerName == null ? messagNoPlayerNameBroadcast : playerName), - (tRank == null ? "" : tRank.getTag() ), - (results.getMessage() != null ? results.getMessage() : "") - ) - .broadcast( rPlayer ); - } - else { - localManager.sendTo( sender, rPlayer ); - } + if ( Prison.get().getPlatform().getConfigBooleanFalse( "broadcast-rankups" ) ) { + String messagNoPlayerNameBroadcast = PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( "ranks_rankup__rankup_no_player_name_broadcast" ).localize(); + + PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( messageId ) + .withReplacements( + + (playerName == null ? messagNoPlayerNameBroadcast : playerName), + (tRank == null ? "" : tRank.getTag() ), + (results.getMessage() != null ? results.getMessage() : "") + ) + .broadcast( rPlayer ); + } + else { + localManager.sendTo( sender, rPlayer ); + } } protected void ranksRankupMaxSuccessMsg( CommandSender sender, StringBuilder ranks, RankPlayer rPlayer ) { - Localizable localManagerLog = PrisonRanks.getInstance().getRanksMessages() - .getLocalizable( "ranks_rankup__log_rank_change" ) - .withReplacements( - - sender.getName(), ranks.toString() - ); - - // Print to console for record: - Output.get().logInfo( localManagerLog.localize() ); - - String messageId = "ranks_rankup__rankup_success" ; - -// String messagNoPlayerName = PrisonRanks.getInstance().getRanksMessages() -// .getLocalizable( "ranks_rankup__rankup_no_player_name" ).localize(); - - + Localizable localManagerLog = PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( "ranks_rankup__log_rank_change" ) + .withReplacements( + + sender.getName(), ranks.toString() + ); + + // Print to console for record: + Output.get().logInfo( localManagerLog.localize() ); + + String messageId = "ranks_rankup__rankup_success" ; + + - String messagNoPlayerNameBroadcast = PrisonRanks.getInstance().getRanksMessages() - .getLocalizable( "ranks_rankup__rankup_no_player_name_broadcast" ).localize(); - - if ( Prison.get().getPlatform().getConfigBooleanFalse( "broadcast-rankups" ) ) { - - PrisonRanks.getInstance().getRanksMessages() - .getLocalizable( messageId ) - .withReplacements( - - (rPlayer.getName() == null ? messagNoPlayerNameBroadcast : rPlayer.getName() ), - ranks.toString(), - "" // no message - do not have anything configured for rankupmax on this? - ) - .broadcast( rPlayer ); - } - else { - - Localizable localManager = PrisonRanks.getInstance().getRanksMessages() - .getLocalizable( messageId ) - .withReplacements( - - (rPlayer.getName() == null ? messagNoPlayerNameBroadcast : rPlayer.getName() ), - ranks.toString(), - "" // no message - do not have anything configured for rankupmax on this? - - ); - - localManager.sendTo( sender, rPlayer ); - } + + String messagNoPlayerNameBroadcast = PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( "ranks_rankup__rankup_no_player_name_broadcast" ).localize(); + + if ( Prison.get().getPlatform().getConfigBooleanFalse( "broadcast-rankups" ) ) { + + PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( messageId ) + .withReplacements( + + (rPlayer.getName() == null ? messagNoPlayerNameBroadcast : rPlayer.getName() ), + ranks.toString(), + "" // no message - do not have anything configured for rankupmax on this? + ) + .broadcast( rPlayer ); + } + else { + + Localizable localManager = PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( messageId ) + .withReplacements( + + (rPlayer.getName() == null ? messagNoPlayerNameBroadcast : rPlayer.getName() ), + ranks.toString(), + "" // no message - do not have anything configured for rankupmax on this? + + ); + + localManager.sendTo( sender, rPlayer ); + } - -// if ( Prison.get().getPlatform().getConfigBooleanFalse( "broadcast-rankups" ) ) { -// -// localManagerLog.broadcast( rPlayer ); -// -// } -// else { -// -// localManagerLog.sendTo( sender, rPlayer ); -// } } protected void ranksRankupCannotAffordMsg( CommandSender sender, @@ -470,15 +457,15 @@ protected void ranksRankupCannotAffordMsg( CommandSender sender, Rank tRank = tpRank.getRank(); - PrisonRanks.getInstance().getRanksMessages() - .getLocalizable( "ranks_rankup__rankup_cant_afford" ) - .withReplacements( - - dFmt.format( tpRank == null ? 0 : tpRank.getRankCost()), - tRank == null || tRank.getCurrency() == null ? "" : - " " +tRank.getCurrency() - ) - .sendTo( sender, rPlayer ); + PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( "ranks_rankup__rankup_cant_afford" ) + .withReplacements( + + dFmt.format( tpRank == null ? 0 : tpRank.getRankCost()), + tRank == null || tRank.getCurrency() == null ? "" : + " " +tRank.getCurrency() + ) + .sendTo( sender, rPlayer ); } protected void ranksRankupLowestRankMsg( CommandSender sender, String playerName, @@ -545,8 +532,8 @@ protected void ranksRankupFailureUnableToAssignRankWithRefundMsg( CommandSender RankPlayer rPlayer ) { PrisonRanks.getInstance().getRanksMessages() - .getLocalizable( "ranks_rankup__rankup_failed_to_assign_rank_with_refund" ) - .sendTo( sender, rPlayer ); + .getLocalizable( "ranks_rankup__rankup_failed_to_assign_rank_with_refund" ) + .sendTo( sender, rPlayer ); } protected void ranksRankupFailureCouldNotSavePlayerFileMsg( CommandSender sender, @@ -598,8 +585,8 @@ protected void ranksRankupFailureEconomyFailedMsg( CommandSender sender, RankPlayer rPlayer ) { PrisonRanks.getInstance().getRanksMessages() - .getLocalizable( "ranks_rankup__rankup_economy_failed" ) - .sendTo( sender, rPlayer ); + .getLocalizable( "ranks_rankup__rankup_economy_failed" ) + .sendTo( sender, rPlayer ); } protected void ranksRankupFailureLadderRemovedMsg( CommandSender sender, 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 1bec29df3..7f21debfa 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 @@ -82,19 +82,19 @@ public void setRankCommandCommands( CommandCommands rankCommandCommands ) { @Command(identifier = "ranks command", onlyPlayers = false, permissions = "prison.commands") public void ranksCommandSubcommands(CommandSender sender) { - sender.dispatchCommand( "ranks command help" ); + sender.dispatchCommand( "ranks command help" ); } @Command(identifier = "ranks ladder", onlyPlayers = false, permissions = "prison.commands") public void ranksLadderSubcommands(CommandSender sender) { - sender.dispatchCommand( "ranks ladder help" ); + sender.dispatchCommand( "ranks ladder help" ); } // @Command(identifier = "ranks perms", // onlyPlayers = false, permissions = "prison.commands") public void ranksPermsSubcommands(CommandSender sender) { - sender.dispatchCommand( "ranks perms help" ); + sender.dispatchCommand( "ranks perms help" ); } // @Command(identifier = "ranks remove", @@ -106,7 +106,7 @@ public void ranksPermsSubcommands(CommandSender sender) { @Command(identifier = "ranks set", onlyPlayers = false, permissions = "prison.commands") public void ranksSetSubcommands(CommandSender sender) { - sender.dispatchCommand( "ranks set help" ); + sender.dispatchCommand( "ranks set help" ); } @Command(identifier = "ranks create", description = "Creates a new rank", @@ -134,23 +134,23 @@ public boolean createRank(CommandSender sender, tag += " " + options; } - boolean updatePlaceholders = !tag.toLowerCase().contains( "noplaceholderupdate" ); - if ( !updatePlaceholders ) { - tag = tag.replaceAll( "(?i)noPlaceholderUpdate", "" ).trim(); - } + boolean updatePlaceholders = !tag.toLowerCase().contains( "noplaceholderupdate" ); + if ( !updatePlaceholders ) { + tag = tag.replaceAll( "(?i)noPlaceholderUpdate", "" ).trim(); + } boolean success = false; // Ensure a rank with the name doesn't already exist if (PrisonRanks.getInstance().getRankManager().getRank(name) != null) { - rankAlreadyExistsMsg( sender, name ); + rankAlreadyExistsMsg( sender, name ); return success; } // Ensure a rank with the name doesn't already exist if (name == null || name.trim().length() == 0 || name.contains( "&" )) { - rankNameRequiredMsg( sender ); - return success; + rankNameRequiredMsg( sender ); + return success; } // Fetch the ladder first, so we can see if it exists @@ -158,7 +158,7 @@ public boolean createRank(CommandSender sender, RankLadder rankLadder = PrisonRanks.getInstance().getLadderManager().getLadder(ladder); if ( rankLadder == null ) { - ladderDoesNotExistMsg( sender, ladder ); + ladderDoesNotExistMsg( sender, ladder ); return success; } @@ -173,20 +173,14 @@ public boolean createRank(CommandSender sender, // Ensure it was created if (!newRankOptional.isPresent()) { - rankCannotBeCreatedMsg( sender ); + rankCannotBeCreatedMsg( sender ); return success; } Rank newRank = newRankOptional.get(); // Save the rank -// try { - PrisonRanks.getInstance().getRankManager().saveRank(newRank); -// } catch (IOException e) { -// Output.get().sendError(sender, -// "The new rank could not be saved to disk. Check the console for details."); -// Output.get().logError("Rank could not be written to disk.", e); -// } + PrisonRanks.getInstance().getRankManager().saveRank(newRank); // Add the ladder @@ -196,7 +190,7 @@ public boolean createRank(CommandSender sender, success = true; if ( updatePlaceholders ) { - Prison.get().getPlatform().getPlaceholders().reloadPlaceholders(); + Prison.get().getPlatform().getPlaceholders().reloadPlaceholders(); } @@ -210,7 +204,7 @@ public boolean createRank(CommandSender sender, } else { - errorCouldNotSaveLadderMsg( sender, rankLadder.getName() ); + errorCouldNotSaveLadderMsg( sender, rankLadder.getName() ); } return success; @@ -423,40 +417,6 @@ public void autoConfigureRanks(CommandSender sender, return; } -// TreeMap plugins = -// Prison.get().getPrisonCommands().getRegisteredPluginData(); - - -// String permCmdAdd = null; -// String permCmdDel = null; -// String perm1 = "mines."; -// String perm2 = "mines.tp."; - -// if ( plugins.containsKey("LuckPerms") ){ -// permCmdAdd = "lp user {player} permission set "; -// permCmdDel = "lp user {player} permission unset "; -// } -// else if ( plugins.containsKey("PermissionsEx") ){ -// permCmdAdd = "pex user {player} add "; -// permCmdDel = "pex user {player} add -"; -// } -// else if ( plugins.containsKey("UltraPermissions") ){ -// permCmdAdd = "upc addplayerpermission {player} "; -// permCmdDel = "upc removeplayerpermission {player} "; -// } -// else if ( plugins.containsKey("GroupManager") ){ -// permCmdAdd = "manuaddp {player} "; -// permCmdDel = "manudelp {player} "; -// } -// else if ( plugins.containsKey("zPermissions") ){ -// permCmdAdd = "permissions player {player} set "; -// permCmdDel = "permissions player {player} unset "; -// } -// else if ( plugins.containsKey("PowerfulPerms") ){ -// permCmdAdd = "pp user {player} add "; -// permCmdAdd = "pp user {player} remove "; -// } - int countRanks = 0; @@ -476,93 +436,64 @@ public void autoConfigureRanks(CommandSender sender, String firstRankName = null; for ( char cRank = 'A'; cRank <= 'Z'; cRank++) { - String rankName = Character.toString( cRank ); - - rankMineNames.add( rankName ); - - String tag = "&7[&" + Integer.toHexString((colorID++ % 15) + 1) + rankName + "&7]"; - - if ( firstRankName == null ) { - firstRankName = rankName; - } - -// char cRankNext = (char) (cRank + 1); -// String rankNameNext = Character.toString( cRankNext ); + String rankName = Character.toString( cRank ); + + rankMineNames.add( rankName ); + + String tag = "&7[&" + Integer.toHexString((colorID++ % 15) + 1) + rankName + "&7]"; + + if ( firstRankName == null ) { + firstRankName = rankName; + } - boolean forceRank = force && PrisonRanks.getInstance().getRankManager().getRank( rankName ) != null; - if ( forceRank || - createRank(sender, rankName, price, - LadderManager.LADDER_DEFAULT, tag, "noPlaceholderUpdate") ) { - - if ( forceRank ) { - countRanksForced++; - } - else { - countRanks++; - } - - -// if ( permCmdAdd != null ) { -// getRankCommandCommands().commandAdd( sender, rankName, permCmdAdd + perm1 + rankName.toLowerCase()); -// countRankCmds++; -//// getRankCommandCommands().commandAdd( sender, rankName, permCmdAdd + perm2 + rankName.toLowerCase()); -//// countRankCmds++; -// -// // Add all the command removal statements to rank A's commands so if the command /ranks set rank A is -// // used then all perms are removed -// if ( !firstRankName.equalsIgnoreCase( rankName ) ) { -// getRankCommandCommands().commandAdd( sender, firstRankName, permCmdDel + perm1 + rankName.toLowerCase()); -// countRankCmds++; -//// getRankCommandCommands().commandAdd( sender, firstRankName, permCmdDel + perm2 + rankName.toLowerCase()); -//// countRankCmds++; -// } -// -// if ( cRankNext <= 'Z' ) { -// getRankCommandCommands().commandAdd( sender, rankName, permCmdDel + perm1 + rankNameNext.toLowerCase()); -// countRankCmds++; -//// getRankCommandCommands().commandAdd( sender, rankName, permCmdDel + perm2 + rankNameNext.toLowerCase()); -//// countRankCmds++; -// } -// -// } - - if ( mines ) { - - // Creates a virtual mine: - String perm = null; -// String perm = perm1 + rankName; - - - - ModuleElement mine = Prison.get().getPlatform().getModuleElement( ModuleElementType.MINE, rankName ); - - boolean forceMine = force && mine != null; - - if ( mine == null ) { - mine = Prison.get().getPlatform().createModuleElement( - sender, ModuleElementType.MINE, rankName, tag, perm ); - } - - - if ( mine != null ) { - if ( forceMine ) { - countMinesForced++; - } - else { - countMines++; - } - - // Links the virtual mine to generated rank and configure mines: - if ( Prison.get().getPlatform().linkModuleElements( mine, ModuleElementType.RANK, rankName ) ) { - countLinked++; - } - - } - } - } - else { - autoConfigRankExistsSkipMsg( sender, Character.toString( cRank ) ); - } + boolean forceRank = force && PrisonRanks.getInstance().getRankManager().getRank( rankName ) != null; + if ( forceRank || + createRank(sender, rankName, price, + LadderManager.LADDER_DEFAULT, tag, "noPlaceholderUpdate") ) { + + if ( forceRank ) { + countRanksForced++; + } + else { + countRanks++; + } + + + if ( mines ) { + + // Creates a virtual mine: + String perm = null; + + + ModuleElement mine = Prison.get().getPlatform().getModuleElement( ModuleElementType.MINE, rankName ); + + boolean forceMine = force && mine != null; + + if ( mine == null ) { + mine = Prison.get().getPlatform().createModuleElement( + sender, ModuleElementType.MINE, rankName, tag, perm ); + } + + + if ( mine != null ) { + if ( forceMine ) { + countMinesForced++; + } + else { + countMines++; + } + + // Links the virtual mine to generated rank and configure mines: + if ( Prison.get().getPlatform().linkModuleElements( mine, ModuleElementType.RANK, rankName ) ) { + countLinked++; + } + + } + } + } + else { + autoConfigRankExistsSkipMsg( sender, Character.toString( cRank ) ); + } if (price == 0){ price += startingPrice; @@ -644,11 +575,6 @@ public void autoConfigureRanks(CommandSender sender, // Reset all player to the first rank on the default ladder: PrisonRanks.getInstance().checkAllPlayersForJoin(); -// RankLadder defaultLadder = PrisonRanks.getInstance().getLadderManager().getLadder( "default" ); -// Rank defaultRank = defaultLadder.getLowestRank().get(); -// PrisonRanks.getInstance().getRankManager().getRankupCommands() -// .setRank( sender, "*all*", "*join*", defaultLadder.getName() ); - if ( countRanksForced > 0 ) { // message about number of ranks that preexisting and were force: @@ -678,13 +604,12 @@ public void autoConfigureRanks(CommandSender sender, Output.get().logInfo( ""); - - } 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 ); @@ -710,19 +635,19 @@ public void removeRank(CommandSender sender, // Check to ensure the rank exists Rank rank = PrisonRanks.getInstance().getRankManager().getRank(rankName); if ( rank == null ) { - rankDoesNotExistMsg( sender, rankName ); + rankDoesNotExistMsg( sender, rankName ); return; } if (PrisonRanks.getInstance().getDefaultLadder().getRanks().contains( rank ) && PrisonRanks.getInstance().getDefaultLadder().getRanks().size() == 1) { - rankCannotBeRemovedMsg( sender ); + rankCannotBeRemovedMsg( sender ); return; } if ( PrisonRanks.getInstance().getRankManager().removeRank(rank) ) { - Prison.get().getPlatform().getPlaceholders().reloadPlaceholders(); + Prison.get().getPlatform().getPlaceholders().reloadPlaceholders(); // Recalculate the ladder's base rank cost multiplier: PlayerRankRefreshTask rankRefreshTask = new PlayerRankRefreshTask(); @@ -730,7 +655,7 @@ public void removeRank(CommandSender sender, rankWasRemovedMsg( sender, rankName ); } else { - rankDeleteErrorMsg( sender, rankName ); + rankDeleteErrorMsg( sender, rankName ); } } @@ -739,34 +664,26 @@ public void removeRank(CommandSender sender, "ranks.", onlyPlayers = false, altPermissions = "ranks.list" ) - public void listRanks(CommandSender sender, - @Arg(name = "ladderName", def = "default", - description = "A ladder name, or 'all' to list all ranks by ladder.") String ladderName) { - - boolean hasPerm = sender.hasPermission("ranks.list") || - sender.isOp() || !sender.isPlayer(); - + public void listRanks(CommandSender sender, + @Arg(name = "ladderName", def = "default", + description = "A ladder name, or 'all' to list all ranks by ladder.") String ladderName) { + + boolean hasPerm = sender.hasPermission("ranks.list") || + sender.isOp() || !sender.isPlayer(); + RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder(ladderName); if ( ladder == null && !"all".equalsIgnoreCase( ladderName ) ) { - ladderDoesNotExistMsg( sender, ladderName ); + ladderDoesNotExistMsg( sender, ladderName ); return; } if ( ladder != null && ladder.getRanks().size() == 0 ) { - ladderHasNoRanksMsg( sender, ladderName ); + ladderHasNoRanksMsg( sender, ladderName ); } -// Rank rank = null; -// for (Rank pRank : ladder.getPositionRanks()) { -// Optional rankOptional = ladder.getByPosition(pRank.getPosition()); -// if (rankOptional.isPresent()) { -// rank = rankOptional.get(); -// break; -// } -// } RankPlayer rPlayer = PrisonRanks.getInstance().getPlayerManager().getPlayer( sender.getPlatformPlayer() ); @@ -774,14 +691,14 @@ public void listRanks(CommandSender sender, ChatDisplay display = null; if ( ladder != null ) { - display = listRanksOnLadder( ladder, hasPerm, rPlayer ); + display = listRanksOnLadder( ladder, hasPerm, rPlayer ); } else { - display = new ChatDisplay( "List ALL Ranks" ); + display = new ChatDisplay( "List ALL Ranks" ); display.addSupportHyperLinkData( "Rank List" ); - listAllRanksByLadders( display, hasPerm, rPlayer ); + listAllRanksByLadders( display, hasPerm, rPlayer ); } @@ -824,65 +741,50 @@ public void listRanks(CommandSender sender, public void listAllRanksByLadders( ChatDisplay display, boolean hasPerm, RankPlayer rPlayer ) { -// List ladders = PrisonRanks.getInstance().getLadderManager().getLadders(); - -// for ( RankLadder rLadder : ladders ) { -// ChatDisplay cDisp = listRanksOnLadder( rLadder, hasPerm ); -// -// if ( display == null ) { -// display = cDisp; -// } -// else { -// display.addEmptyLine(); -// -// display.addChatDisplay( cDisp ); -// } -// -// } - - // Track which ranks were included in the ladders listed: - List ranksIncluded = new ArrayList<>(); - - for ( RankLadder ladder : PrisonRanks.getInstance().getLadderManager().getLadders() ) { - List ladderRanks = ladder.getRanks(); - ranksIncluded.addAll( ladderRanks ); - - ChatDisplay cDisp = listRanksOnLadder( ladder, hasPerm, rPlayer ); - - if ( display == null ) { - display = cDisp; - } - else { - display.addEmptyLine(); + + // Track which ranks were included in the ladders listed: + List ranksIncluded = new ArrayList<>(); + + for ( RankLadder ladder : PrisonRanks.getInstance().getLadderManager().getLadders() ) { + List ladderRanks = ladder.getRanks(); + ranksIncluded.addAll( ladderRanks ); + + ChatDisplay cDisp = listRanksOnLadder( ladder, hasPerm, rPlayer ); - display.addChatDisplay( cDisp ); - } - - } - - // Next we need to get a list of all ranks that were not included. Create a temp ladder so they - // can be printed out with them: - List ranksExcluded = new ArrayList<>( PrisonRanks.getInstance().getRankManager().getRanks() ); - ranksExcluded.removeAll( ranksIncluded ); - - if ( ranksExcluded.size() > 0 ) { - RankLadder noLadder = new RankLadder( -1, "No Ladder" ); - - for ( Rank rank : ranksExcluded ) { - noLadder.addRank( rank ); - } - - ChatDisplay cDisp = listRanksOnLadder( noLadder, hasPerm, rPlayer ); - - if ( display == null ) { - display = cDisp; - } - else { - display.addEmptyLine(); + if ( display == null ) { + display = cDisp; + } + else { + display.addEmptyLine(); + + display.addChatDisplay( cDisp ); + } - display.addChatDisplay( cDisp ); - } - } + } + + // Next we need to get a list of all ranks that were not included. Create a temp ladder so they + // can be printed out with them: + List ranksExcluded = new ArrayList<>( PrisonRanks.getInstance().getRankManager().getRanks() ); + ranksExcluded.removeAll( ranksIncluded ); + + if ( ranksExcluded.size() > 0 ) { + RankLadder noLadder = new RankLadder( -1, "No Ladder" ); + + for ( Rank rank : ranksExcluded ) { + noLadder.addRank( rank ); + } + + ChatDisplay cDisp = listRanksOnLadder( noLadder, hasPerm, rPlayer ); + + if ( display == null ) { + display = cDisp; + } + else { + display.addEmptyLine(); + + display.addChatDisplay( cDisp ); + } + } } @@ -954,12 +856,12 @@ private ChatDisplay listRanksOnLadder( RankLadder ladder, boolean hasPerm, RankP if ( hasPerm ) { - display.addText( ranksListClickToEditMsg() ); + display.addText( ranksListClickToEditMsg() ); } if ( ladder.getRanks().size() == 0 ) { - display.addText( ladderHasNoRanksTextMsg() ); + display.addText( ladderHasNoRanksTextMsg() ); } BulletedListComponent.BulletedListBuilder builder = @@ -978,20 +880,20 @@ private ChatDisplay listRanksOnLadder( RankLadder ladder, boolean hasPerm, RankP int maxRankCostSize = 1; for (Rank rank : ladder.getRanks()) { - 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; - } + 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++; @@ -1003,145 +905,124 @@ private ChatDisplay listRanksOnLadder( RankLadder ladder, boolean hasPerm, RankP boolean first = true; for (Rank rank : ladder.getRanks()) { - 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 ); - -// // 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 -// // formatted text with tagNoColor, then replace the no color tag with the -// // normal tag. -// // If tag is null, show it as an empty String. Normally rank name will -// // be used, but at least this show's it is not set. -// String tag = rank.getTag() == null ? "" : rank.getTag(); -// String tagNoColor = Text.stripColor( tag ); - - - - // If rank list is being generated for a console or op'd player, then show the ladder's rank multiplier, - // but if generating for a player, then show total multiplier accross all ladders. - PlayerRank pRank = null; - double rankCost = 0; - double rMulti = 0; - - if ( hasPerm || rPlayer == null ) { - - rankCost = rank.getRawRankCost(); - - pRank = rankPlayerFactory.createPlayerRank( rank ); -// pRank = rankPlayerFactory.createPlayerRank( rank ); - - rMulti = pRank.getLadderBasedRankMultiplier(); - - } - else { - - pRank = rPlayer.calculateTargetPlayerRank( rank ); - -// pRank = rankPlayerFactory.createPlayerRank( rank ); -// -// -// pRank = pRank.getTargetPlayerRankForPlayer( pRank, rPlayer, rank ); - rankCost = pRank.getRankCost(); - - rMulti = pRank.getRankMultiplier(); - } - - - - String textCmdCount = ( hasPerm ? - ranksListCommandCountMsg(rank.getRankUpCommands().size()) - : "" ); - String textCurrency = (rank.getCurrency() == null ? "" : - ranksListCurrencyMsg( rank.getCurrency() )); - - String rankMultiplier = rMulti == 0d ? "" : fFmt.format( rMulti ); - - 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 ? "" : " +") ) -// : ""); + 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 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 ); + + // // 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 + // // formatted text with tagNoColor, then replace the no color tag with the + // // normal tag. + // // If tag is null, show it as an empty String. Normally rank name will + // // be used, but at least this show's it is not set. + // String tag = rank.getTag() == null ? "" : rank.getTag(); + // String tagNoColor = Text.stripColor( tag ); + + + + // If rank list is being generated for a console or op'd player, then show the ladder's rank multiplier, + // but if generating for a player, then show total multiplier accross all ladders. + PlayerRank pRank = null; + double rankCost = 0; + double rMulti = 0; + + if ( hasPerm || rPlayer == null ) { + + rankCost = rank.getRawRankCost(); + + pRank = rankPlayerFactory.createPlayerRank( rank ); + + rMulti = pRank.getLadderBasedRankMultiplier(); + + } + else { + + pRank = rPlayer.calculateTargetPlayerRank( rank ); + + rankCost = pRank.getRankCost(); + + rMulti = pRank.getRankMultiplier(); + } - StringBuilder minesSb = new StringBuilder(); - for ( ModuleElement mine : rank.getMines() ) { + + String textCmdCount = ( hasPerm ? + ranksListCommandCountMsg(rank.getRankUpCommands().size()) + : "" ); + String textCurrency = (rank.getCurrency() == null ? "" : + ranksListCurrencyMsg( rank.getCurrency() )); + + String rankMultiplier = rMulti == 0d ? "" : fFmt.format( rMulti ); + + String players = rank.getPlayers().size() == 0 ? "" : + " &dPlayers: &3" + rank.getPlayers().size(); + + + 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 %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, - - textCurrency, - textCmdCount, - players, - minesSb.toString() - ); - -// // Swap the color tag back in: -// text = text.replace( tagNoColor, tag ); - - if ( defaultRank ) { - // Swap out the default placeholder for the actual content: - text = text.replace( "{def}", "&c(&r&9Default&r&c)" ); - } - - String rankName = rank.getName(); - if ( rankName.contains( "&" ) ) { - rankName = rankName.replace( "&", "-" ); - } - FancyMessage msg = null; - if ( hasPerm ) { - msg = new FancyMessage(text).command("/ranks info " + rankName) - .tooltip( ranksListClickToViewMsg() ); - } - else { - msg = new FancyMessage(text); - } + if ( minesSb.length() > 0 ) { + minesSb.insert( 0, " &6Mines: &7" ); + } - builder.add(msg); + String text = + String.format("&3%s %s &7%" + maxRankCostSize + "s &a%s &b%s %s&7 %s%s%s", + nameFormatted, + tagFormatted, + + iFmt.format( rankCost ), + (defaultRank ? "{def}" : ""), + + rankMultiplier, + + textCurrency, + textCmdCount, + players, + minesSb.toString() + ); -// rank = rank.getRankNext(); - first = false; + if ( defaultRank ) { + // Swap out the default placeholder for the actual content: + text = text.replace( "{def}", "&c(&r&9Default&r&c)" ); + } + + String rankName = rank.getName(); + if ( rankName.contains( "&" ) ) { + rankName = rankName.replace( "&", "-" ); + } + FancyMessage msg = null; + if ( hasPerm ) { + msg = new FancyMessage(text).command("/ranks info " + rankName) + .tooltip( ranksListClickToViewMsg() ); + } + else { + msg = new FancyMessage(text); + } + + builder.add(msg); + + first = false; } @@ -1178,77 +1059,69 @@ private ChatDisplay listRanksOnLadder( RankLadder ladder, boolean hasPerm, RankP if ( rPlayer != null && !"No Ladder".equals( ladder.getName() ) ) { -// RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); - - double ladderMultiplier = ladder.getRankCostMultiplierPerRank(); - PlayerRank pRank = rankPlayerFactory.getRank( rPlayer, ladder ); - double playerMultiplier = pRank != null ? - pRank.getRankMultiplier() : 0; - - if ( playerMultiplier == 0 ) { - display.addText( "&3You have no Ladder Rank Multipliers enabled. The rank costs are not adjusted." ); - } - else { - display.addText( "&3Your current total Rank Multiplier: &7%s.", - fFmt.format( playerMultiplier ) ); - - if ( ladderMultiplier == 0 ) { - display.addText( "&3This ladder has no Rank Multiplier so all ranks on this ladder " + - "have the same multiplier." ); - } - else { - display.addText( "&3This ladder has a Rank Multiplier so each rank has " + - "a differnt multiplier." ); - } - - Set ladders = rPlayer.getLadderRanks().keySet(); - for ( RankLadder rLadder : ladders ) { - if ( rLadder.getRankCostMultiplierPerRank() != 0d ) { - - Rank r = rPlayer.getLadderRanks().get( rLadder ).getRank(); - - PlayerRank rpRank = rPlayer.calculateTargetPlayerRank( r ); -// PlayerRank rpRank = rankPlayerFactory.createPlayerRank( r ); - - display.addText( "&3 BaseMult: &7%7s &3CurrMult: &7%7s &7%s &7%s ", - fFmt.format( rLadder.getRankCostMultiplierPerRank() ), - fFmt.format( rpRank.getLadderBasedRankMultiplier() ), - rLadder.getName(), - (r.getTag() == null ? r.getName() : r.getTag()) - ); - -// display.addText( "&3 Ladder: &7%-9s &3Rank: &7%-8s &3Base Mult: %7s", -// rLadder.getName(), -// rPlayer.getLadderRanks().get( rLadder ).getRank().getTag(), -// fFmt.format( rLadder.getRankCostMultiplierPerRank() ) ); + double ladderMultiplier = ladder.getRankCostMultiplierPerRank(); + + PlayerRank pRank = rankPlayerFactory.getRank( rPlayer, ladder ); + double playerMultiplier = pRank != null ? + pRank.getRankMultiplier() : 0; + + if ( playerMultiplier == 0 ) { + display.addText( "&3You have no Ladder Rank Multipliers enabled. The rank costs are not adjusted." ); + } + else { + display.addText( "&3Your current total Rank Multiplier: &7%s.", + fFmt.format( playerMultiplier ) ); + + if ( ladderMultiplier == 0 ) { + display.addText( "&3This ladder has no Rank Multiplier so all ranks on this ladder " + + "have the same multiplier." ); + } + else { + display.addText( "&3This ladder has a Rank Multiplier so each rank has " + + "a differnt multiplier." ); + } + + Set ladders = rPlayer.getLadderRanks().keySet(); + for ( RankLadder rLadder : ladders ) { + if ( rLadder.getRankCostMultiplierPerRank() != 0d ) { + + Rank r = rPlayer.getLadderRanks().get( rLadder ).getRank(); + + PlayerRank rpRank = rPlayer.calculateTargetPlayerRank( r ); + + display.addText( "&3 BaseMult: &7%7s &3CurrMult: &7%7s &7%s &7%s ", + fFmt.format( rLadder.getRankCostMultiplierPerRank() ), + fFmt.format( rpRank.getLadderBasedRankMultiplier() ), + rLadder.getName(), + (r.getTag() == null ? r.getName() : r.getTag()) + ); + + } } - } - } + } } return display; } -// private String padRankName( Rank rank, int maxRankNameSize, int maxRankTagNoColorSize, boolean hasPerm ) { -// return padRankName( rank.getName(), rank.getTag(), maxRankNameSize, maxRankTagNoColorSize, hasPerm ); -// } + protected String padRankName( String rankName, String rankTag, int maxRankNameSize, int maxRankTagNoColorSize, boolean hasPerm ) { - StringBuilder sb = new StringBuilder(); - - int tLen = (hasPerm ? maxRankNameSize + 1 : 0) + maxRankTagNoColorSize; - String name = hasPerm ? rankName + " " : ""; - String tag = rankTag == null ? "" : rankTag; - String tagNoColor = Text.stripColor( tag ); - - sb.append( name ).append( tag ).append( "&8" ); - - int length = name.length() + tagNoColor.length(); - while ( length++ < tLen ) { - sb.append( "." ); - } + StringBuilder sb = new StringBuilder(); + + int tLen = (hasPerm ? maxRankNameSize + 1 : 0) + maxRankTagNoColorSize; + String name = hasPerm ? rankName + " " : ""; + String tag = rankTag == null ? "" : rankTag; + String tagNoColor = Text.stripColor( tag ); + + sb.append( name ).append( tag ).append( "&8" ); + + int length = name.length() + tagNoColor.length(); + while ( length++ < tLen ) { + sb.append( "." ); + } return sb.toString(); } @@ -1263,45 +1136,35 @@ public void infoCmd(CommandSender sender, Rank rank = PrisonRanks.getInstance().getRankManager().getRank(rankName); if ( rank == null ) { -// rankOpt = PrisonRanks.getInstance().getRankManager().getRankEscaped(rankName); -// if (!rankOpt.isPresent()) { rankDoesNotExistMsg( sender, rankName ); return; -// } } - ChatDisplay display = rankInfoDetails( sender, rank, options ); display.send(sender); -// if ( options != null && "all".equalsIgnoreCase( options )) { - - //getRankCommandCommands().commandLadderList( sender, rank.getLadder().getName(), "noRemoves" ); - -// getRankCommandCommands().commandList( sender, rankName, "noRemoves" ); -// } } public void allRanksInfoDetails( StringBuilder sb ) { - PrisonRanks pRanks = PrisonRanks.getInstance(); - RankManager rMan = pRanks.getRankManager(); - - for ( Rank rank : rMan.getRanks() ) { - - Prison.get().getPrisonStatsUtil().printFooter( sb ); - - JumboTextFont.makeJumboFontText( rank.getName(), sb ); - sb.append( "\n" ); - - ChatDisplay chatDisplay = rankInfoDetails( null, rank, "all" ); - - sb.append( chatDisplay.toStringBuilder() ); + PrisonRanks pRanks = PrisonRanks.getInstance(); + RankManager rMan = pRanks.getRankManager(); + + for ( Rank rank : rMan.getRanks() ) { + + Prison.get().getPrisonStatsUtil().printFooter( sb ); + + JumboTextFont.makeJumboFontText( rank.getName(), sb ); + sb.append( "\n" ); + + ChatDisplay chatDisplay = rankInfoDetails( null, rank, "all" ); + + sb.append( chatDisplay.toStringBuilder() ); } - - Prison.get().getPrisonStatsUtil().printFooter( sb ); + + Prison.get().getPrisonStatsUtil().printFooter( sb ); } @@ -1328,29 +1191,29 @@ private ChatDisplay rankInfoDetails( CommandSender sender, Rank rank, String opt if ( rank.getLadder() != null ) { - row.addTextComponent( " " ); - - row.addTextComponent( "&3Ladder Position: &7%d", rank.getPosition() ); + row.addTextComponent( " " ); + + row.addTextComponent( "&3Ladder Position: &7%d", rank.getPosition() ); } display.addComponent( row ); if ( rank.getMines().size() == 0 ) { - display.addText( ranksInfoNotLinkedToMinesMsg() ); + display.addText( ranksInfoNotLinkedToMinesMsg() ); } else { - StringBuilder sb = new StringBuilder(); - - for ( ModuleElement mine : rank.getMines() ) { - if ( sb.length() > 0 ) { - sb.append( "&3, " ); - } - sb.append( "&7" ); - sb.append( mine.getName() ); + StringBuilder sb = new StringBuilder(); + + for ( ModuleElement mine : rank.getMines() ) { + if ( sb.length() > 0 ) { + sb.append( "&3, " ); + } + sb.append( "&7" ); + sb.append( mine.getName() ); } - display.addText( ranksInfoLinkedMinesMsg( sb.toString() )); + display.addText( ranksInfoLinkedMinesMsg( sb.toString() )); } @@ -1369,9 +1232,6 @@ private ChatDisplay rankInfoDetails( CommandSender sender, Rank rank, String opt // The following is the rank adjusted rank multiplier -// PlayerManager pm = PrisonRanks.getInstance().getPlayerManager(); -// RankPlayer rPlayer = pm.getPlayer(player.getUUID(), player.getName()); - RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); PlayerRank pRank = rankPlayerFactory.createPlayerRank( rank ); @@ -1398,25 +1258,20 @@ private ChatDisplay rankInfoDetails( CommandSender sender, Rank rank, String opt if ( isOp || isConsole || sender.hasPermission("ranks.admin")) { // This is admin-exclusive content -// display.addText("&8[Admin Only]"); display.addText( ranksInfoRankIdMsg( rank.getId() )); -// FancyMessage del = -// new FancyMessage( ranksInfoRankDeleteMessageMsg() ).command("/ranks delete " + rank.getName()) -// .tooltip( ranksInfoRankDeleteToolTipMsg() ); -// display.addComponent(new FancyMessageComponent(del)); } if ( (isOp || isConsole) && options != null && "all".equalsIgnoreCase( options )) { - - if ( rank.getLadder() != null ) { - - ChatDisplay cmdLadderDisplays = getRankCommandCommands().commandLadderListDetail( rank.getLadder(), true ); - display.addChatDisplay( cmdLadderDisplays ); - } - - ChatDisplay cmdLadderCmdsDisplays = getRankCommandCommands().commandListDetails( rank, true ); - display.addChatDisplay( cmdLadderCmdsDisplays ); + + if ( rank.getLadder() != null ) { + + ChatDisplay cmdLadderDisplays = getRankCommandCommands().commandLadderListDetail( rank.getLadder(), true ); + display.addChatDisplay( cmdLadderDisplays ); + } + + ChatDisplay cmdLadderCmdsDisplays = getRankCommandCommands().commandListDetails( rank, true ); + display.addChatDisplay( cmdLadderCmdsDisplays ); } return display; @@ -1435,13 +1290,11 @@ public void setCost(CommandSender sender, Rank rank = PrisonRanks.getInstance().getRankManager().getRank(rankName); if ( rank == null ) { - rankDoesNotExistMsg( sender, rankName ); + rankDoesNotExistMsg( sender, rankName ); return; } - rank.setRawRankCost( rawCost ); -// PlayerRank.setRawRankCost( rank, rawCost ); PrisonRanks.getInstance().getRankManager().saveRank(rank); @@ -1462,47 +1315,47 @@ public void setCurrency(CommandSender sender, description = "The custom currency to use with this rank, " + "or 'none' to remove a custom currency.") String currency){ - Rank rank = PrisonRanks.getInstance().getRankManager().getRank(rankName); - if ( rank == null ) { - rankDoesNotExistMsg( sender, rankName ); - return; - } - - - if ( currency == null || currency.trim().length() == 0 ) { - rankSetCurrencyNotSpecifiedMsg( sender, currency ); - return; - } - - if ( "none".equalsIgnoreCase( currency ) && rank.getCurrency() == null ) { - - rankSetCurrencyNoCurrencyToClearMsg( sender, rankName ); - - } - else if ( "none".equalsIgnoreCase( currency ) ) { - rank.setCurrency( null ); - - PrisonRanks.getInstance().getRankManager().saveRank(rank); - - rankSetCurrencyClearedMsg( sender, rankName ); - - } - else { - - EconomyCurrencyIntegration currencyEcon = PrisonAPI.getIntegrationManager() - .getEconomyForCurrency( currency ); - if ( currencyEcon == null ) { - - rankSetCurrencyNoActiveSupportMsg( sender, currency ); - return; - } - - rank.setCurrency( currency ); - - PrisonRanks.getInstance().getRankManager().saveRank(rank); - - rankSetCurrencySuccessfulMsg( sender, rankName, currency ); - } + Rank rank = PrisonRanks.getInstance().getRankManager().getRank(rankName); + if ( rank == null ) { + rankDoesNotExistMsg( sender, rankName ); + return; + } + + + if ( currency == null || currency.trim().length() == 0 ) { + rankSetCurrencyNotSpecifiedMsg( sender, currency ); + return; + } + + if ( "none".equalsIgnoreCase( currency ) && rank.getCurrency() == null ) { + + rankSetCurrencyNoCurrencyToClearMsg( sender, rankName ); + + } + else if ( "none".equalsIgnoreCase( currency ) ) { + rank.setCurrency( null ); + + PrisonRanks.getInstance().getRankManager().saveRank(rank); + + rankSetCurrencyClearedMsg( sender, rankName ); + + } + else { + + EconomyCurrencyIntegration currencyEcon = PrisonAPI.getIntegrationManager() + .getEconomyForCurrency( currency ); + if ( currencyEcon == null ) { + + rankSetCurrencyNoActiveSupportMsg( sender, currency ); + return; + } + + rank.setCurrency( currency ); + + PrisonRanks.getInstance().getRankManager().saveRank(rank); + + rankSetCurrencySuccessfulMsg( sender, rankName, currency ); + } } @@ -1516,18 +1369,18 @@ public void setTag(CommandSender sender, Rank rank = PrisonRanks.getInstance().getRankManager().getRank(rankName); if ( rank == null ) { - rankDoesNotExistMsg( sender, rankName ); + rankDoesNotExistMsg( sender, rankName ); return; } if ( tag == null || tag.trim().length() == 0 ) { - rankSetTagInvalidMsg( sender ); - return; + rankSetTagInvalidMsg( sender ); + return; } if ( tag.equalsIgnoreCase( "none" ) ) { - tag = null; + tag = null; } @@ -1535,8 +1388,8 @@ public void setTag(CommandSender sender, rank.getTag() != null && rank.getTag().equalsIgnoreCase( tag )) { - rankSetTagNoChangeMsg( sender ); - return; + rankSetTagNoChangeMsg( sender ); + return; } rank.setTag( tag ); @@ -1544,10 +1397,10 @@ public void setTag(CommandSender sender, PrisonRanks.getInstance().getRankManager().saveRank(rank); if ( tag == null ) { - rankSetTagClearedMsg( sender, rank.getName() ); + rankSetTagClearedMsg( sender, rank.getName() ); } else { - rankSetTagSucessMsg( sender, tag, rank.getName() ); + rankSetTagSucessMsg( sender, tag, rank.getName() ); } } @@ -1575,34 +1428,12 @@ public void ranksImportByPermissions(CommandSender sender, "[]") String options){ - if ( !ladderName.equalsIgnoreCase( "all" ) && - PrisonRanks.getInstance().getLadderManager().getLadder( ladderName ) == null ) { - ranksPlayersInvalidLadderMsg( sender, ladderName ); - return; - } - - -// RanksByLadderOptions option = RanksByLadderOptions.fromString( action ); -// if ( option == null ) { -// ranksPlayersInvalidActionMsg( sender, action ); -// return; -// } + if ( !ladderName.equalsIgnoreCase( "all" ) && + PrisonRanks.getInstance().getLadderManager().getLadder( ladderName ) == null ) { + ranksPlayersInvalidLadderMsg( sender, ladderName ); + return; + } -// boolean includeAll = action.equalsIgnoreCase( "all" ); -// PrisonRanks.getInstance().getRankManager().ranksByLadders( sender, ladderName, option ); - -// Output.get().logInfo( "Ranks by ladders:" ); -// -// for ( RankLadder ladder : PrisonRanks.getInstance().getLadderManager().getLadders() ) { -// if ( ladderName.equalsIgnoreCase( "all" ) || ladderName.equalsIgnoreCase( ladder.name ) ) { -// -// boolean includeAll = action.equalsIgnoreCase( "all" ); -// String ladderRanks = ladder.listAllRanks( includeAll ); -// -// sender.sendMessage( ladderRanks ); -// } -// -// } } @@ -1627,30 +1458,16 @@ public void rankPlayer(CommandSender sender, // This is a SpigotPlayer object, with the bukkit player attached: Player sPlayer = rankPlayer.getPlatformPlayer(); - -// Player player = getPlayer( sender, playerName ); -// -// if (player == null) { -// ranksPlayerOnlineMsg( sender ); -// return; -// } - - List msgs = new ArrayList<>(); - - DecimalFormat iFmt = Prison.get().getDecimalFormatInt(); - DecimalFormat dFmt = Prison.get().getDecimalFormat("#,##0.00"); - DecimalFormat fFmt = Prison.get().getDecimalFormat("0.0000"); - DecimalFormat pFmt = Prison.get().getDecimalFormat("#,##0.0000"); + + List msgs = new ArrayList<>(); + + DecimalFormat iFmt = Prison.get().getDecimalFormatInt(); + DecimalFormat dFmt = Prison.get().getDecimalFormat("#,##0.00"); + DecimalFormat fFmt = Prison.get().getDecimalFormat("0.0000"); + DecimalFormat pFmt = Prison.get().getDecimalFormat("#,##0.0000"); SimpleDateFormat sdFmt = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ); - // need to see if the player is offline or online: -// Player offlinePlayer = Prison.get().getPlatform().getOfflinePlayer( rankPlayer.getUUID() ).orElse( null ); - - - //PlayerManager pm = PrisonRanks.getInstance().getPlayerManager(); -// RankPlayer rankPlayer = player.getRankPlayer(); -// RankPlayer rankPlayer = pm.getPlayer(player.getUUID(), player.getName()); // Get the cachedPlayer: PlayerCachePlayerData cPlayer = rankPlayer.getPlayerCachePlayerData(); @@ -1673,17 +1490,6 @@ public void rankPlayer(CommandSender sender, rankPlayer.setDirty( true ); } } -// if ( offlinePlayer != null && cPlayer != null ) { -// if ( cPlayer.getLastSeenDate() < offlinePlayer.getLastSeenDate() ) { -// cPlayer.setLastSeenDate( offlinePlayer.getLastSeenDate() ); -// cPlayer.setDirty( true ); -// } -// -// if ( rankPlayer.getLastSeenDate() < offlinePlayer.getLastSeenDate() ) { -// rankPlayer.setLastSeenDateTemp( offlinePlayer.getLastSeenDate() ); -// rankPlayer.setDirty( true ); -// } -// } String lastSeen = cPlayer == null || cPlayer.getLastSeenDate() == 0 ? @@ -1702,25 +1508,11 @@ public void rankPlayer(CommandSender sender, msgs.add( msgLs ); - - String msg2 = String.format( " &7Ranks with (Rank Cost Multiplier):"); -// double rankCostMultiplier = 0d; -// Set rpKeys = rankPlayer.getLadderRanks().keySet(); -// for ( RankLadder rpKey : rpKeys ) { -// PlayerRank pRank = rankPlayer.getLadderRanks().get( rpKey ); -// rankCostMultiplier += pRank.getRankMultiplier(); -// } -// String msg2 = String.format( " &7Rank Cost Multiplier: &f", -// fFmt.format( rankCostMultiplier )); msgs.add( msg2 ); - if ( rankPlayer != null ) { -// DecimalFormat iFmt = Prison.get().getDecimalFormatInt(); -// -// SimpleDateFormat sdFmt = new SimpleDateFormat( "HH:mm:ss" ); // Collect all currencies in the default ladder: Set currencies = new LinkedHashSet<>(); @@ -1733,8 +1525,6 @@ public void rankPlayer(CommandSender sender, } -// RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); - Map rankLadders = rankPlayer.getLadderRanks(); @@ -1747,11 +1537,6 @@ public void rankPlayer(CommandSender sender, // This calculates the target rank, and takes in to consideration the player's existing rank: PlayerRank nextPRank = rankPlayer.calculateTargetPlayerRank( nextRank ); - // PlayerRank nextPRank = pRank.getTargetPlayerRankForPlayer( rankPlayer, nextRank ); -// PlayerRank nextPRank = PlayerRank.getTargetPlayerRankForPlayer( rankPlayer, nextRank ); - -// PlayerRank nextPRank = nextRank == null ? null : -// new PlayerRank( nextRank, pRank.getRankMultiplier() ); double rankCostMultiplier = pRank.getRankMultiplier(); @@ -1768,16 +1553,13 @@ public void rankPlayer(CommandSender sender, messageRank += ranksPlayerLadderNextRankMsg( nextRank.getName(), ( nextRank == null ? "0" : dFmt.format( nextPRank.getRankCost()) ) ); -// dFmt.format( nextRank.getCost() ) ); if ( nextRank.getCurrency() != null ) { messageRank += ranksPlayerLadderNextRankCurrencyMsg( nextRank.getCurrency() ); } } - msgs.add( messageRank ); -// sendToPlayerAndConsole( sender, messageRank ); } // Print out the player's balances: @@ -1786,7 +1568,6 @@ public void rankPlayer(CommandSender sender, double balance = rankPlayer.getBalance(); String message = ranksPlayerBalanceDefaultMsg( rankPlayer.getName(), dFmt.format( balance ) ); msgs.add( message ); -// sendToPlayerAndConsole( sender, message ); for ( String currency : currencies ) { @@ -1794,7 +1575,6 @@ public void rankPlayer(CommandSender sender, String messageCurrency = ranksPlayerBalanceOthersMsg( rankPlayer.getName(), dFmt.format( balanceCurrency ), currency ); msgs.add( messageCurrency ); -// sendToPlayerAndConsole( sender, messageCurrency ); } @@ -1802,13 +1582,10 @@ public void rankPlayer(CommandSender sender, boolean isPlayer = sPlayer != null ? sPlayer.isPlayer() : rankPlayer.isPlayer(); boolean isOnline = sPlayer != null ? sPlayer.isOnline() : rankPlayer.isOnline(); -// boolean isPrisonPlayer = (rankPlayer instanceof Player); -// boolean isPrisonOfflineMcPlayer = offlinePlayer != null ? true : (rankPlayer instanceof OfflineMcPlayer); if ( !isOnline ) { String msgOffline = ranksPlayerPermsOfflineMsg(); msgs.add( msgOffline ); -// sendToPlayerAndConsole( sender, msgOffline ); } @@ -1819,7 +1596,6 @@ public void rankPlayer(CommandSender sender, pFmt.format( sellallMultiplier ), (!isOnline ? " " + messageNotAccurrate : "") ); msgs.add( messageSellallMultiplier ); -// sendToPlayerAndConsole( sender, messageSellallMultiplier ); // Warning, if the player is offline, then the list of multiplier details @@ -1899,51 +1675,12 @@ public void rankPlayer(CommandSender sender, msgs.add( " &7Blocks By Type&8:" ); msgs.addAll( Text.formatTreeMapStats(cPlayer.getBlocksByType(), 3 ) ); - - -// Set keysEarnings = cPlayer.getEarningsByMine().keySet(); -// -// int count = 0; -// StringBuilder sbErn = new StringBuilder(); -// for ( String earningKey : keysEarnings ) -// { -// Double mineEarnings = cPlayer.getEarningsByMine().get( earningKey ); -// -// String earnings = PlaceholdersUtil.formattedKmbtSISize( mineEarnings, dFmt, " " ); -// -// sbErn.append( String.format( "%s %s ", earningKey, earnings ) ); -// -// if ( count++ % 5 == 0 ) { -// msgs.add( String.format( -// " " + sbErn.toString() ) ); -// sbErn.setLength( 0 ); -// -// } -// } -// -// if ( sbErn.length() > 0 ) { -// -// msgs.add( String.format( -// " " + sbErn.toString() ) ); -// } - - - -// msgs.add( String.format( -// " " ) ); -// -// cPlayer.getEarningsByMine() - } - - - sendToPlayerAndConsole( sender, msgs ); - if ( sender.hasPermission("ranks.admin") ) { // This is admin-exclusive content @@ -1970,8 +1707,6 @@ public void rankPlayer(CommandSender sender, (isOp ? " " + ranksPlayerOpMsg() : ""), (isPlayer ? " " + ranksPlayerPlayerMsg() : ""), (isOnline ? " " + ranksPlayerOnlineMsg() : " " + ranksPlayerOfflineMsg()) -// (isPrisonOfflineMcPlayer ? " " + ranksPlayerPrisonOfflinePlayerMsg() : -// (isPrisonPlayer ? " " + ranksPlayerPrisonPlayerMsg() : "")) ) ); if ( !isOnline ) { @@ -1984,9 +1719,6 @@ public void rankPlayer(CommandSender sender, listPermissions( sender, "bukkit", perms ); -// sendToPlayerAndConsole( sender, "### has perm prison.mines.a: " + -// player.hasPermission( "prison.mines.a" ) ); - List permissionIntegrations = PrisonAPI.getIntegrationManager().getAllForType( IntegrationType.PERMISSION ); @@ -2006,179 +1738,10 @@ public void rankPlayer(CommandSender sender, } } -// String nextRank = pm.getPlayerNextRankName( rankPlayer ); -// String nextRankCost = pm.getPlayerNextRankCost( rankPlayer ); -// -// String message = String.format("&c%s&7: Current Rank: &b%s&7", -// player.getDisplayName(), pm.getPlayerRankName( rankPlayer )); -// -// if ( nextRank.trim().length() == 0 ) { -// message += " It's the highest rank!"; -// } else { -// message += String.format(" Next rank: &b%s&7 &c$&b%s &7s%", -// nextRank, nextRankCost, currency ); -// } -// sender.sendMessage( message ); } -// else { -// ranksPlayerNoRanksFoundMsg( sender, player.getDisplayName() ); -// } } -// private String formatTimeMs( long timeMs ) { -// -// DecimalFormat iFmt = Prison.get().getDecimalFormatInt(); -// DecimalFormat tFmt = Prison.get().getDecimalFormat("00"); -//// SimpleDateFormat sdFmt = new SimpleDateFormat( "HH:mm:ss" ); -// -// long _sec = 1000; -// long _min = _sec * 60; -// long _hour = _min * 60; -// long _day = _hour * 24; -// -// long ms = timeMs; -// long days = _day < ms ? ms / _day : 0; -// -// ms -= (days * _day); -// long hours = _hour < ms ? ms / _hour : 0; -// -// ms -= (hours * _hour); -// long mins = _min < ms ? ms / _min : 0; -// -// ms -= (mins * _min); -// long secs = _sec < ms ? ms / _sec : 0; -// -// -// String results = -// (days == 0 ? "" : iFmt.format( days ) + "d ") + -// tFmt.format( hours ) + ":" + -// tFmt.format( mins ) + ":" + -// tFmt.format( secs ) -// ; -// -// return results; -// } - -// private void formatTreeMapStats( TreeMap statMap, List msgs, -// DecimalFormat dFmt, DecimalFormat iFmt, -// int columns ) { -// -// Set keysEarnings = statMap.keySet(); -// -// -// List values = new ArrayList<>(); -// List valueMaxLen = new ArrayList<>(); -// -// -// int count = 0; -// StringBuilder sb = new StringBuilder(); -// for ( String earningKey : keysEarnings ) -// { -// String value = null; -// Object valueObj = statMap.get( earningKey ); -// -// if ( valueObj instanceof Double ) { -// -// value = PlaceholdersUtil.formattedKmbtSISize( (Double) valueObj, dFmt, " &9" ); -// } -// else if ( valueObj instanceof Integer ) { -// int intVal = (Integer) valueObj; -// value = PlaceholdersUtil.formattedKmbtSISize( intVal, -// ( intVal < 1000 ? iFmt : dFmt ), " &9" ); -// } -// else if ( valueObj instanceof Long ) { -// -// value = Text.formatTimeDaysHhMmSs( (Long) valueObj ); -// } -// -// String msg = String.format( "&3%s&8: &b%s", earningKey, value ).trim(); -// -// String msgNoColor = Text.stripColor( msg ); -// int lenMNC = msgNoColor.length(); -// -// -// int col = values.size() % columns; -// values.add( msg ); -// -// if ( col >= valueMaxLen.size() || lenMNC > valueMaxLen.get( col ) ) { -// -// if ( col > valueMaxLen.size() - 1 ) { -// valueMaxLen.add( lenMNC ); -// } -// else { -// -// valueMaxLen.set( col, lenMNC ); -// } -// } -// } -// -// -// for ( int j = 0; j < values.size(); j++ ) -// { -// String msg = values.get( j ); -// -// int col = j % columns; -// -// int maxColumnWidth = col > valueMaxLen.size() - 1 ? -// msg.length() : -// valueMaxLen.get( col ); -// -// sb.append( msg ); -// -// // Pad the right of all content with spaces to align columns, up to a -// // given maxLength: -// String msgNoColor = Text.stripColor( msg ); -// int lenMNC = msgNoColor.length(); -// for( int i = lenMNC; i < maxColumnWidth; i++ ) { -// sb.append( " " ); -// } -// -// // The spacer: -// sb.append( " " ); -// -// if ( ++count % columns == 0 ) { -// msgs.add( String.format( -// " " + sb.toString() ) ); -// sb.setLength( 0 ); -// -// } -// } -// -// if ( sb.length() > 0 ) { -// -// msgs.add( String.format( -// " " + sb.toString() ) ); -// } -// -// -// } - - -//// @Command(identifier = "ranks playerInventory", permissions = "mines.set", -//// description = "For listing what's in a player's inventory by dumping it to console.", -//// onlyPlayers = false ) -// public void ranksPlayerInventoryCommand(CommandSender sender, -// @Arg(name = "player", def = "", description = "Player name") String playerName -// ) { -// -// Player player = getPlayer( sender, playerName ); -// -// if (player == null) { -// sender.sendMessage( "&3You must be a player in the game to run this command, and/or the player must be online." ); -// return; -// } -// -//// Player player = getPlayer( sender ); -//// -//// if (player == null || !player.isOnline()) { -//// sender.sendMessage( "&3You must be a player in the game to run this command." ); -//// return; -//// } -// -// player.printDebugInventoryInformationToConsole(); -// } -// private void listPermissions( CommandSender sender, String prefix, List perms ) { @@ -2244,35 +1807,21 @@ public void rankPlayers(CommandSender sender, "'All' includes all ranks including ones without players. " + "'Full includes player names if prison is tracking them. [players, all, full]") String action){ - - if ( !ladderName.equalsIgnoreCase( "all" ) && - PrisonRanks.getInstance().getLadderManager().getLadder( ladderName ) == null ) { - ranksPlayersInvalidLadderMsg( sender, ladderName ); - return; - } - - - RanksByLadderOptions option = RanksByLadderOptions.fromString( action ); - if ( option == null ) { - ranksPlayersInvalidActionMsg( sender, action ); - return; - } - -// boolean includeAll = action.equalsIgnoreCase( "all" ); - PrisonRanks.getInstance().getRankManager().ranksByLadders( sender, ladderName, option ); - -// Output.get().logInfo( "Ranks by ladders:" ); -// -// for ( RankLadder ladder : PrisonRanks.getInstance().getLadderManager().getLadders() ) { -// if ( ladderName.equalsIgnoreCase( "all" ) || ladderName.equalsIgnoreCase( ladder.name ) ) { -// -// boolean includeAll = action.equalsIgnoreCase( "all" ); -// String ladderRanks = ladder.listAllRanks( includeAll ); -// -// sender.sendMessage( ladderRanks ); -// } -// -// } + + if ( !ladderName.equalsIgnoreCase( "all" ) && + PrisonRanks.getInstance().getLadderManager().getLadder( ladderName ) == null ) { + ranksPlayersInvalidLadderMsg( sender, ladderName ); + return; + } + + + RanksByLadderOptions option = RanksByLadderOptions.fromString( action ); + if ( option == null ) { + ranksPlayersInvalidActionMsg( sender, action ); + return; + } + + PrisonRanks.getInstance().getRankManager().ranksByLadders( sender, ladderName, option ); } @@ -2299,141 +1848,110 @@ public void rankTopN(CommandSender sender, "Can use multiple options. " + "[alt archived forceReload stats debugSave]") String options ){ - int page = 1; - int pageSize = 10; - - if ( contains( "forceReload", pageNumber, pageSizeNumber, options ) ) { - - if ( sender.isOp() ) { - TopNPlayers.getInstance().forceReloadAllPlayers(); - ranksTopNPlayerForcedReloadSuccess( sender ); - } - else { - - ranksTopNPlayerForcedReloadFailure( sender ); - } - - } - - if ( contains( "debugSave", pageNumber, pageSizeNumber, options ) ) { - - if ( sender.isOp() ) { - TopNPlayers.getInstance().saveToJson(); - TopNPlayers.getInstance().loadSaveFile(); - ranksTopNPlayerDebugSaved( sender ); - } - } - - boolean alt = contains( "alt", pageNumber, pageSizeNumber, options ); -// if ( pageNumber.toLowerCase().contains("alt") || -// pageSizeNumber.toLowerCase().contains("alt") || -// options.toLowerCase().contains("alt") ) { -// alt = true; -// } - - // Since it's contains, "archive" will hit on archived, archives, etc... - boolean archived = contains( "archive", pageNumber, pageSizeNumber, options ); - -// boolean sort = contains( "sort", pageNumber, pageSizeNumber, options ); - - int topNSize = TopNPlayers.getInstance().getTopNSize(); - boolean loading = TopNPlayers.getInstance().isLoading(); - int archivedSize = TopNPlayers.getInstance().getArchivedSize(); - - - if ( contains( "stats", pageNumber, pageSizeNumber, options ) ) { - - sender.sendMessage( TopNPlayers.getInstance().getTopNStats() ); - } - - - try { - page = Integer.parseInt(pageNumber); - } - catch (NumberFormatException e ) { - // Ignore: will use defaults - } - try { - pageSize = Integer.parseInt(pageSizeNumber); - } - catch (NumberFormatException e ) { - // Ignore: will use defaults - } - - if ( page <= 0 ) { - page = 1; - } - if ( pageSize <= 0 ) { - pageSize = 10; - } - - int totalPlayers = - archived ? - archivedSize : - topNSize; - -// int totalPlayers = PrisonRanks.getInstance().getPlayerManager().getPlayers().size(); - int totalPages = (totalPlayers / pageSize) + (totalPlayers % pageSize == 0 ? 0 : 1); - - if ( page > 1 && totalPages > 1 && page > totalPages ) { - page = totalPages; - } - - int posStart = (page - 1) * pageSize; - int posEnd = posStart + pageSize; - -// DecimalFormat dFmt = Prison.get().getDecimalFormat("#,##0.00"); - - -// if ( sort ) { -// -// if ( sender.isOp() || !sender.isPlayer() ) { -// -//// PrisonRanks.getInstance().getPlayerManager().sortPlayerByTopRanked(); -//// PrisonRanks.getInstance().getPlayerManager().sortPlayerByTopRankedNoRankScoreUpdate(); -// sender.sendMessage( "&3Sorting has been submitted." ); -// } -// else { -// sender.sendMessage( "&3Only admins can force a sorting of the topn players." ); -// -// } -// -// } - - - - -// List topN = PrisonRanks.getInstance().getPlayerManager().getTopNPlayers().getTopNList(); - - String header = alt ? - RankPlayer.printRankScoreLine2Header() : - RankPlayer.printRankScoreLine1Header(); - sender.sendMessage( header ); - - if ( loading ) { - sender.sendMessage( "&3(Loading TopN List - Please Wait)" ); - } - - - for ( int i = posStart; i < posEnd; i++ ) { - - RankPlayer rPlayer = - archived ? - TopNPlayers.getInstance().getTopNRankArchivedPlayer( i ) : - TopNPlayers.getInstance().getTopNRankPlayer( i ); - - -// PrisonRanks.getInstance().getPlayerManager().getTopNRankPlayer( i ); - - if ( rPlayer != null ) { - - String message = alt ? - rPlayer.printRankScoreLine2( i + 1 ) : - rPlayer.printRankScoreLine1( i + 1 ); - - sender.sendMessage(message); - } - } + int page = 1; + int pageSize = 10; + + if ( contains( "forceReload", pageNumber, pageSizeNumber, options ) ) { + + if ( sender.isOp() ) { + TopNPlayers.getInstance().forceReloadAllPlayers(); + ranksTopNPlayerForcedReloadSuccess( sender ); + } + else { + + ranksTopNPlayerForcedReloadFailure( sender ); + } + + } + + if ( contains( "debugSave", pageNumber, pageSizeNumber, options ) ) { + + if ( sender.isOp() ) { + TopNPlayers.getInstance().saveToJson(); + TopNPlayers.getInstance().loadSaveFile(); + ranksTopNPlayerDebugSaved( sender ); + } + } + + boolean alt = contains( "alt", pageNumber, pageSizeNumber, options ); + + // Since it's contains, "archive" will hit on archived, archives, etc... + boolean archived = contains( "archive", pageNumber, pageSizeNumber, options ); + + + int topNSize = TopNPlayers.getInstance().getTopNSize(); + boolean loading = TopNPlayers.getInstance().isLoading(); + int archivedSize = TopNPlayers.getInstance().getArchivedSize(); + + + if ( contains( "stats", pageNumber, pageSizeNumber, options ) ) { + + sender.sendMessage( TopNPlayers.getInstance().getTopNStats() ); + } + + + try { + page = Integer.parseInt(pageNumber); + } + catch (NumberFormatException e ) { + // Ignore: will use defaults + } + try { + pageSize = Integer.parseInt(pageSizeNumber); + } + catch (NumberFormatException e ) { + // Ignore: will use defaults + } + + if ( page <= 0 ) { + page = 1; + } + if ( pageSize <= 0 ) { + pageSize = 10; + } + + int totalPlayers = + archived ? + archivedSize : + topNSize; + + int totalPages = (totalPlayers / pageSize) + (totalPlayers % pageSize == 0 ? 0 : 1); + + if ( page > 1 && totalPages > 1 && page > totalPages ) { + page = totalPages; + } + + int posStart = (page - 1) * pageSize; + int posEnd = posStart + pageSize; + + + String header = alt ? + RankPlayer.printRankScoreLine2Header() : + RankPlayer.printRankScoreLine1Header(); + sender.sendMessage( header ); + + if ( loading ) { + sender.sendMessage( "&3(Loading TopN List - Please Wait)" ); + } + + + for ( int i = posStart; i < posEnd; i++ ) { + + RankPlayer rPlayer = + archived ? + TopNPlayers.getInstance().getTopNRankArchivedPlayer( i ) : + TopNPlayers.getInstance().getTopNRankPlayer( i ); + + + if ( rPlayer != null ) { + + String message = alt ? + rPlayer.printRankScoreLine2( i + 1 ) : + rPlayer.printRankScoreLine1( i + 1 ); + + sender.sendMessage(message); + } + } } @@ -2493,39 +2011,15 @@ public void supportPlayerFileNameUpdateCmd(CommandSender sender, int page ) { - ReportMode reportMode = ReportMode.fromString( action ); + ReportMode reportMode = ReportMode.fromString( action ); - // Get the PrisonSystemSettings for the PlayerFileNameUpdate and format the results: - PlayerNewFileNameCheckAsyncTask task = new PlayerNewFileNameCheckAsyncTask(); -// List msg = task.getStatusDetails(); - -// boolean useNewFormat = Prison.get().getPlatform() -// .getConfigBooleanFalse( PrisonSystemSettings.PRISON_SYSTEM_SETTING_FRIENDLY_PLAYER_FILE_NAMES ); - -// msg.add( "" ); - -// sender.sendMessage(msg); - - if ( reportMode == ReportMode.cache || reportMode == ReportMode.players ) { - - task.playerConverterReport( reportMode, page ); - } -// else if ( reportMode == ReportMode.run ) { -// -// if ( !useNewFormat ) { -// Output.get().logInfo( "&cCommand failure: &aBefore the player file names can be " + -// "checked, the setting '&c%s&a' " + -// "must be set to '&ctrue&a'. Once enabled, this can not be " + -// "reverted because the player files (Player Ranks and Player Caches) " + -// "could be corrupted.", -// PrisonSystemSettings.PRISON_SYSTEM_SETTING_FRIENDLY_PLAYER_FILE_NAMES -// ); -// } -// else { -// long delayTicks = 0; -// PlayerNewFileNameCheckAsyncTask.submitTaskSync( delayTicks ); -// } -// } + // Get the PrisonSystemSettings for the PlayerFileNameUpdate and format the results: + PlayerNewFileNameCheckAsyncTask task = new PlayerNewFileNameCheckAsyncTask(); + + if ( reportMode == ReportMode.cache || reportMode == ReportMode.players ) { + + task.playerConverterReport( reportMode, page ); + } } @@ -2540,19 +2034,19 @@ public void supportPlayerFileNameUpdateCmd(CommandSender sender, + "copy of prison's settings.", aliases = "prison reload players", onlyPlayers = false, permissions = "ranks.set") - public void reloadPlayersCmd(CommandSender sender ){ - - - try { + public void reloadPlayersCmd(CommandSender sender ){ + + + try { PrisonRanks.getInstance().getPlayerManager().reloadAllPlayers(); String msg = String.format( "&3Reload Players: Successful. Maybe..." ); sender.sendMessage(msg); - + } - catch (IOException e) { + catch (IOException e) { String msg = String.format( "&cReload Players: Failed. [%s]", e.getMessage() ); @@ -2576,106 +2070,33 @@ public void reloadPlayersCmd(CommandSender sender ){ public void reloadLaddersAndRanksCmd(CommandSender sender ){ - PrisonRanks.getInstance().reloadRanksAndLadders(); - - String msg = String.format( - "&3Reload ranks, ladders and players: Successful. Maybe..." ); - - sender.sendMessage(msg); + PrisonRanks.getInstance().reloadRanksAndLadders(); + + String msg = String.format( + "&3Reload ranks, ladders and players: Successful. Maybe..." ); + + sender.sendMessage(msg); } private boolean contains( String search, String... values ) { - boolean results = false; - - if ( search != null && values != null ) { - - search = search.trim().toLowerCase(); - - for (String val : values) { + boolean results = false; + + if ( search != null && values != null ) { + + search = search.trim().toLowerCase(); + + for (String val : values) { if ( val.toLowerCase().contains(search) ) { results = true; break; } - } - } - - return results; + } + } + + return results; } -// /** -// * This function is just an arbitrary test to access the various components. -// * -// * @param sender -// * @param playerName -// */ -// @Command( identifier = "ranks test", onlyPlayers = false, permissions = "prison.admin" ) -// public void prisonModuleTest(CommandSender sender, -// @Arg(name = "player", def = "", description = "Player name") String playerName){ -// -// ModuleManager modMan = Prison.get().getModuleManager(); -// Module module = modMan == null ? null : modMan.getModule( PrisonRanks.MODULE_NAME ).orElse( null ); -// -// int moduleCount = (modMan == null ? 0 : modMan.getModules().size()); -// sender.sendMessage(String.format( "prisonModuleTest: prison=%s moduleManager=%s " + -// "registeredModules=%s PrisonRanks=%s", -// (Prison.get() == null ? "null" : "active"), -// (Prison.get().getModuleManager() == null ? "null" : "active"), -// Integer.toString( moduleCount ), -// (modMan.getModule( PrisonRanks.MODULE_NAME ) == null ? "null" : "active") -// ) ); -// -// if ( module == null || !(module instanceof PrisonRanks) ) { -// -// sender.sendMessage( "prisonModuleTest: Cannot get PrisonRanks. Terminating" ); -// return; -// } -// -// -// PrisonRanks rankPlugin = (PrisonRanks) module; -// -// if ( rankPlugin == null || rankPlugin.getPlayerManager() == null ) { -// sender.sendMessage( "prisonModuleTest: PrisonRanks could not be created. Terminating" ); -// return; -// } -// -// -// PlayerManager playerManager = rankPlugin.getPlayerManager(); -// Player player = getPlayer( sender, playerName ); -// -// sender.sendMessage( String.format( "prisonModuleTest: PlayerManager=%s player=%s sender=%s playerName=%s", -// (playerManager == null ? "null" : "active"), (player == null ? "null" : player.getName()), -// (sender == null ? "null" : sender.getName()), (playerName == null ? "null" : playerName) -// )); -// -// -// if ( player == null ) { -// sender.sendMessage( "prisonModuleTest: Cannot get a valid player. " + -// "If console, must supply a valid name. Terminating" ); -// return; -// } -// -// RankPlayer rPlayer = playerManager.getPlayer( player.getUUID() ).orElse( null ); -// LadderManager lm = rankPlugin.getLadderManager(); -// -// for ( RankLadder ladderData : lm.getLadders() ) { -// Rank playerRank = rPlayer == null ? null : rPlayer.getRank( ladderData ).orElse( null ); -// Rank rank = ladderData.getLowestRank().orElse( null ); -// -// while ( rank != null ) { -// boolean playerHasThisRank = playerRank != null && playerRank.equals( rank ); -// -// sender.sendMessage(String.format( "prisonModuleTest: ladder=%s rank=%s playerRank=%s hasRank=%s", -// ladderData.name, rank.name, (playerRank == null ? "null" : playerRank.name ), -// Boolean.valueOf( playerHasThisRank ).toString() -// )); -// -// rank = rank.rankNext; -// } -// } -// } - - /** *

This gets the RankPlayer for the given UUID or playerName. The 'sender' generally is the diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommandsMessages.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommandsMessages.java index c98e55de7..87b3a9d85 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommandsMessages.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommandsMessages.java @@ -142,16 +142,16 @@ protected void autoConfigLadderRankCostMultiplierInfoMsg( CommandSender sender, DecimalFormat dFmt = Prison.get().getDecimalFormat("0.0000"); PrisonRanks.getInstance().getRanksMessages() - .getLocalizable( "ranks_rankCommands__auto_config_ladder_rank_cost_multiplier_info" ) - .withReplacements( - dFmt.format( rankCostMultiplier ) ) - .sendTo( sender ); + .getLocalizable( "ranks_rankCommands__auto_config_ladder_rank_cost_multiplier_info" ) + .withReplacements( + dFmt.format( rankCostMultiplier ) ) + .sendTo( sender ); } protected void autoConfigLadderRankCostMultiplierCmdMsg( CommandSender sender ) { PrisonRanks.getInstance().getRanksMessages() - .getLocalizable( "ranks_rankCommands__auto_config_ladder_rank_cost_multiplier_command_example" ) - .sendTo( sender ); + .getLocalizable( "ranks_rankCommands__auto_config_ladder_rank_cost_multiplier_command_example" ) + .sendTo( sender ); } protected void autoConfigRanksCreatedMsg( CommandSender sender, diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommandsPerms.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommandsPerms.java index 68cff60fe..00d8cfa21 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommandsPerms.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommandsPerms.java @@ -17,315 +17,7 @@ public RanksCommandsPerms( String cmdGroup ) { } -// @Command(identifier = "ranks perms list", description = "Lists rank permissions", -// onlyPlayers = false, permissions = "ranks.set") -// public void rankPermsList(CommandSender sender, -// @Arg(name = "rankName") String rankName -// ){ -// sender.sendMessage( "&cWarning: &3This feature is not yet functional." ); -// -// Rank rank = PrisonRanks.getInstance().getRankManager().getRank(rankName); -// if ( rank == null ) { -// rankDoesNotExistMsg( sender, rankName ); -// return; -// } -// -// -// if ( rank.getPermissions() == null ||rank.getPermissions().size() == 0 && -// rank.getPermissionGroups() == null && rank.getPermissionGroups().size() == 0 ) { -// -// Output.get().sendInfo(sender, "The Rank '%s' contains no permissions or " + -// "permission groups.", rank.getName()); -// return; -// } -// -// RankLadder ladder = rank.getLadder(); -// -// ChatDisplay display = new ChatDisplay("Rank Permissions and Groups for " + rank.getName()); -// display.addText("&8Click a Permission to remove it."); -// BulletedListComponent.BulletedListBuilder builder = -// new BulletedListComponent.BulletedListBuilder(); -// -// listLadderPerms( ladder, builder ); -// -// int rowNumber = 1; -// -// if ( rank.getPermissions().size() > 0 ) { -// builder.add( "&7Permissions:" ); -// } -// for (String perm : rank.getPermissions() ) { -// -// RowComponent row = new RowComponent(); -// -// row.addTextComponent( " &3Row: &d%d ", rowNumber++ ); -// -// FancyMessage msgPermission = new FancyMessage( String.format( "&7%s ", perm ) ) -// .command( "/ranks perms edit " + rank.getName() + " " + rowNumber + " " ) -// .tooltip("Permission - Click to Edit"); -// row.addFancy( msgPermission ); -// -// -// FancyMessage msgRemove = new FancyMessage( String.format( " &cRemove " ) ) -// .command( "/ranks perms remove " + rank.getName() + " " + rowNumber + " " ) -// .tooltip("Remove Permission - Click to Delete"); -// row.addFancy( msgRemove ); -// -// builder.add( row ); -// } -// -// if ( rank.getPermissionGroups().size() > 0 ) { -// builder.add( "&7Permission Groups:" ); -// } -// for (String permGroup : rank.getPermissionGroups() ) { -// -// RowComponent row = new RowComponent(); -// -// row.addTextComponent( " &3Row: &d%d ", rowNumber++ ); -// -// FancyMessage msgPermission = new FancyMessage( String.format( "&7%s ", permGroup ) ) -// .command( "/ranks perms edit " + rank.getName() + " " + rowNumber + " " ) -// .tooltip("Permission Group - Click to Edit"); -// row.addFancy( msgPermission ); -// -// -// FancyMessage msgRemove = new FancyMessage( String.format( " &cRemove " ) ) -// .command( "/ranks perms remove " + rank.getName() + " " + rowNumber + " " ) -// .tooltip("Remove Permission Group - Click to Delete"); -// row.addFancy( msgRemove ); -// -// builder.add( row ); -// } -// -// -// display.addComponent(builder.build()); -// display.addComponent(new FancyMessageComponent( -// new FancyMessage("&7[&a+&7] Add Permission") -// .suggest("/ranks perms addPerm " + rank.getName() + " [perm] /") -// .tooltip("&7Add a new Permission."))); -// display.addComponent(new FancyMessageComponent( -// new FancyMessage("&7[&a+&7] Add Permission Group") -// .suggest("/ranks perms addPermGroup " + rank.getName() + " [permGroup] /") -// .tooltip("&7Add a new Permission Group."))); -// -// display.send(sender); -// -// } - -// private void listLadderPerms( RankLadder ladder, -// BulletedListComponent.BulletedListBuilder builder ) { -// -// if ( ladder.getPermissions().size() > 0 ) { -// builder.add( "&3Ladder &7%s &3Permissions:", ladder.getName() ); -// } -// for (String perm : ladder.getPermissions() ) { -// -// RowComponent row = new RowComponent(); -// -// row.addTextComponent( " " ); -// -// FancyMessage msgPermission = new FancyMessage( String.format( "&7%s ", perm ) ) -// .command( "/ranks ladder perms list " + ladder.getName() ) -// .tooltip("Ladder Permission - Click to List Ladder"); -// row.addFancy( msgPermission ); -// -// builder.add( row ); -// } -// -// if ( ladder.getPermissionGroups().size() > 0 ) { -// builder.add( "&3Ladder &7%s &3Permission Groups:", ladder.getName() ); -// } -// for (String permGroup : ladder.getPermissionGroups() ) { -// -// RowComponent row = new RowComponent(); -// -// row.addTextComponent( " " ); -// -// FancyMessage msgPermission = new FancyMessage( String.format( "&7%s ", permGroup ) ) -// .command( "/ranks ladder perms list " + ladder.getName() ) -// .tooltip("Ladder Permission Group - Click to List Ladder"); -// row.addFancy( msgPermission ); -// -// builder.add( row ); -// } -// -// } - - -// @Command(identifier = "ranks perms addPerm", -// description = "Add a ladder permission. Valid placeholder: {rank}.", -// onlyPlayers = false, permissions = "ranks.set") -// public void rankPermsAddPerm(CommandSender sender, -// @Arg(name = "rankName", -// description = "Rank name to add the permission to.") String rankName, -// @Arg(name = "permission", description = "Permission") String permission -// ){ -// -// sender.sendMessage( "&cWarning: &3This feature is not yet functional." ); -// -// Rank rank = PrisonRanks.getInstance().getRankManager().getRank(rankName); -// if ( rank == null ) { -// rankDoesNotExistMsg( sender, rankName ); -// return; -// } -// -// -// if ( permission == null || permission.trim().isEmpty() ) { -// -// Output.get().sendInfo(sender, "&3The &7permission &3parameter is required." ); -// return; -// } -// -// -// if ( rank.hasPermission( permission ) ) { -// -// Output.get().sendInfo(sender, "&3The permission &7%s &3already exists.", permission ); -// return; -// } -// -// rank.getPermissions().add( permission ); -// -// -// PrisonRanks.getInstance().getRankManager().saveRank(rank); -// -// Output.get().sendInfo(sender, "&3The permission &7%s &3was successfully added " + -// "to the rank &7%s&3.", permission, rank.getName() ); -// -// rankPermsList( sender, rank.getName() ); -// } - - -// @Command(identifier = "ranks perms addGroup", -// description = "Add a ladder permission. Valid placeholder: {rank}.", -// onlyPlayers = false, permissions = "ranks.set") -// public void rankPermsAddPermGroup(CommandSender sender, -// @Arg(name = "rankName", -// description = "Rank name to add the permission to.") String rankName, -// @Arg(name = "permissionGroup", description = "Permission Group") String permissionGroup -// ){ -// -// sender.sendMessage( "&cWarning: &3This feature is not yet functional." ); -// -// Rank rank = PrisonRanks.getInstance().getRankManager().getRank(rankName); -// if ( rank == null ) { -// rankDoesNotExistMsg( sender, rankName ); -// return; -// } -// -// -// if ( permissionGroup == null || permissionGroup.trim().isEmpty() ) { -// -// Output.get().sendInfo(sender, "&3The &7permission group &3parameter is required." ); -// return; -// } -// -// -// if ( rank.hasPermissionGroup( permissionGroup ) ) { -// -// Output.get().sendInfo(sender, "&3The permission Group &7%s &3already exists.", permissionGroup ); -// return; -// } -// -// rank.getPermissionGroups().add( permissionGroup ); -// -// -// PrisonRanks.getInstance().getRankManager().saveRank(rank); -// -// Output.get().sendInfo(sender, "&3The permission group &7%s &3was successfully added " + -// "to the rank &7%s&3.", permissionGroup, rank.getName() ); -// -// rankPermsList( sender, rank.getName() ); -// } - - - -// @Command(identifier = "ranks perms remove", description = "Remove rank permissions", -// onlyPlayers = false, permissions = "ranks.set") -// public void rankPermsRemove(CommandSender sender, -// @Arg(name = "rankName", def = "default", -// description = "Rank name to list the permissions.") String rankName, -// @Arg(name = "row") Integer row -// ){ -// sender.sendMessage( "&cWarning: &3This feature is not yet functional." ); -// -// -// Rank rank = PrisonRanks.getInstance().getRankManager().getRank(rankName); -// if ( rank == null ) { -// rankDoesNotExistMsg( sender, rankName ); -// return; -// } -// -// -// boolean dirty = false; -// String removedPerm = ""; -// boolean permGroup = false; -// -// if ( row == null || row <= 0 ) { -// sender.sendMessage( -// String.format("&7Please provide a valid row number greater than zero. " + -// "Was row=[&b%d&7]", -// (row == null ? "null" : row) )); -// return; -// } -// -// if ( row <= rank.getPermissions().size() ) { -// removedPerm = rank.getPermissions().remove( row - 1 ); -// dirty = true; -// } -// else { -// // Remove from row the size of permissions so the row will align to the permissionGroups. -// row -= rank.getPermissions().size(); -// -// if ( row <= rank.getPermissionGroups().size() ) { -// -// removedPerm = rank.getPermissions().remove( row - 1 ); -// dirty = true; -// permGroup = true; -// } -// } -// -// if ( dirty ) { -// PrisonRanks.getInstance().getRankManager().saveRank(rank); -// -// Output.get().sendInfo(sender, "&3The permission%s &7%s &3was successfully removed " + -// "to the rank &7%s&3.", -// ( permGroup ? " group" : "" ), -// removedPerm, rank.getName() ); -// -// } -// else { -// Output.get().sendInfo(sender, "&3The permission on row &7%s &3was unable to be removed " + -// "from the &7%s &3rank. " + -// "Is that a valid row number?", -// Integer.toString( row ), rank.getName() ); -// } -// } - - // @Command(identifier = "ranks playerInventory", permissions = "mines.set", - // description = "For listing what's in a player's inventory by dumping it - // to console.", - // onlyPlayers = false ) -// public void ranksPlayerInventoryCommand( CommandSender sender, -// @Arg( name = "player", def = "", description = "Player name" ) String playerName ) -// { -// -// Player player = getPlayer( sender, playerName ); -// -// if ( player == null ) -// { -// sender.sendMessage( "&3You must be a player in the game to run this command, and/or the player must be online." ); -// return; -// } -// -// // Player player = getPlayer( sender ); -// // -// // if (player == null || !player.isOnline()) { -// // sender.sendMessage( "&3You must be a player in the game to run this -// // command." ); -// // return; -// // } -// -// player.printDebugInventoryInformationToConsole(); -// } - + // NOTE: All of the commented out code has been purged. + // Please see the history in github for what was removed. } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/PrisonSortableLaddersRanks.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/PrisonSortableLaddersRanks.java index 249b17093..14ba051f9 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/PrisonSortableLaddersRanks.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/PrisonSortableLaddersRanks.java @@ -11,7 +11,6 @@ public class PrisonSortableLaddersRanks extends PrisonSorter { - @Override public Set getSortedSet() { @@ -39,16 +38,11 @@ public Set getSortedSet() for ( RankLadder rankLadder : ladders ) { List rankList = rankLadder.getRanks(); - // Perform the sort of the ranks: -// ranksSorted.addAll( rankList ); - // Add the ranks to the result set in sorted order: results.addAll( rankList ); -// results.addAll( ranksSorted ); // Remove from the unsortedRanks list, all ranks that were used: unsortedRanks.removeAll( rankList ); -// unsortedRanks.removeAll( ranksSorted ); } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankFactory.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankFactory.java index 7efe71561..29ff4bbe0 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankFactory.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankFactory.java @@ -19,8 +19,6 @@ public Rank createRank( Document document ) try { - // Object pos = document.get("position"); - // this.position = RankUtil.doubleToInt( pos == null ? 0.0d : pos ); int id = ConversionUtil.doubleToInt( document.get( "id" ) ); String name = (String) document.get( "name" ); @@ -46,8 +44,6 @@ public Rank createRank( Document document ) } } - // This was allowing nulls to be added to the live commands... - // this.rankUpCommands = (List) cmds; } rank.getMines().clear(); @@ -59,33 +55,6 @@ public Rank createRank( Document document ) rank.setMineStrings( mineStrings ); } - // getPermissions().clear(); - // Object perms = document.get( "permissions" ); - // if ( perms != null ) { - // List permissions = (List) perms; - // for ( String permission : permissions ) { - // getPermissions().add( permission ); - // } - // } - // - // - // getPermissionGroups().clear(); - // Object permsGroups = document.get( "permissionGroups" ); - // if ( perms != null ) { - // List permissionGroups = (List) permsGroups; - // for ( String permissionGroup : permissionGroups ) { - // getPermissionGroups().add( permissionGroup ); - // } - // } - - -// // Hook up the ladder if it has not been setup yet: -// if ( rank.getLadder() == null ) { -// -// RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder( rank ); -// -// rank.setLadder( ladder ); -// } } catch ( Exception e ) { @@ -102,7 +71,6 @@ public Rank createRank( Document document ) public Document toDocument( Rank rank ) { Document ret = new Document(); -// ret.put("position", this.position ); if ( rank.getId() != -1 ) { ret.put("id", rank.getId()); @@ -132,12 +100,8 @@ public Document toDocument( Rank rank ) { } ret.put("mines", mineStrings); -// ret.put( "permissions", getPermissions() ); -// ret.put( "permissionGroups", getPermissionGroups() ); return ret; } - - } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankLadderFactory.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankLadderFactory.java index 856a8543a..ce5e42c55 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankLadderFactory.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankLadderFactory.java @@ -80,8 +80,6 @@ public RankLadder createRankLadder(Document document, RankManager rankManager) { rankLadder = new RankLadder( id, name ); -// RankManager rankManager = prisonRanks.getRankManager(); - if ( rankManager == null ) { RankMessages rMessages = new RankMessages(); @@ -90,28 +88,25 @@ public RankLadder createRankLadder(Document document, RankManager rankManager) { return null; } - List> ranksLocal = - (List>) document.get("ranks"); + List> ranksLocal = + (List>) document.get("ranks"); - rankLadder.getRankUpCommands().clear(); - Object cmds = document.get("commands"); - if ( cmds != null ) { + rankLadder.getRankUpCommands().clear(); + Object cmds = document.get("commands"); + if ( cmds != null ) { - List commands = (List) cmds; - for ( String cmd : commands ) { - if ( cmd != null ) { - rankLadder.getRankUpCommands().add( cmd ); - } + List commands = (List) cmds; + for ( String cmd : commands ) { + if ( cmd != null ) { + rankLadder.getRankUpCommands().add( cmd ); } - - // This was allowing nulls to be added to the live commands... -// this.rankUpCommands = (List) cmds; } + + } -// rankLadder.ranks = new ArrayList<>(); // already initialized - for (LinkedTreeMap rank : ranksLocal) { - + for (LinkedTreeMap rank : ranksLocal) { + if ( rank == null ) { // Force a resave to "fix" the problem? @@ -125,7 +120,7 @@ public RankLadder createRankLadder(Document document, RankManager rankManager) { continue; } - + // The only real field that is important here is rankId to tie the // rank back to this ladder. Name helps clarify the contents of the // Ladder file. @@ -138,7 +133,7 @@ public RankLadder createRankLadder(Document document, RankManager rankManager) { // the file was saved with rankIds, so resave to remove them: isDirty = true; } - + if ( rRankName == null || rRankName.trim().length() == 0 ) { // NOTICE: Loading an older save file that has not been converted @@ -154,8 +149,8 @@ public RankLadder createRankLadder(Document document, RankManager rankManager) { rankPrison = rankManager.getRank( rRankName ); } - - + + if ( rankPrison != null && rankPrison.getLadder() != null ) { if ( rankPrison.getLadder().equals( rankLadder ) ) { @@ -174,27 +169,17 @@ public RankLadder createRankLadder(Document document, RankManager rankManager) { } -// RankMessages rMessages = new RankMessages(); -// rMessages.rankFailureLoadingDuplicateRankMsg( -// rankPrison.getName(), -// rankPrison.getLadder().getName(), -// rankLadder.getName() ); - + isDirty = true; } else if ( rankPrison != null) { - + rankLadder.addRank( rankPrison ); - -// Output.get().logInfo( "RankLadder load : " + getName() + -// " rank= " + rankPrison.getName() + " " + rankPrison.getId() + -// ); + + // Output.get().logInfo( "RankLadder load : " + getName() + + // " rank= " + rankPrison.getName() + " " + rankPrison.getId() + + // ); -// // if null look it up from loaded ranks: -// if ( rRankName == null ) { -// rRankName = rankPrison.getName(); -// dirty = true; -// } } else { // Rank not found. Try to create it? The name maybe wrong. @@ -208,60 +193,37 @@ else if ( rankPrison != null) { rankLadder.addRank( newRank ); -// String message = String.format( -// "Loading RankLadder Error: A rank for %s was not found so it was " + -// "fabricated: %s id=%d tag=%s cost=%d", getName(), newRank.getName(), newRank.getId(), -// newRank.getTag(), newRank.getCost() ); -// Output.get().logError( message ); + // String message = String.format( + // "Loading RankLadder Error: A rank for %s was not found so it was " + + // "fabricated: %s id=%d tag=%s cost=%d", getName(), newRank.getName(), newRank.getId(), + // newRank.getTag(), newRank.getCost() ); + // Output.get().logError( message ); } - - } + + } -// this.maxPrestige = RankUtil.doubleToInt(document.get("maxPrestige")); - Double rankCostMultiplier = (Double) document.get( "rankCostMultiplierPerRank" ); - rankLadder.setRankCostMultiplierPerRank( rankCostMultiplier == null ? 0 : rankCostMultiplier ); - - Boolean applyRankCostMultiplierToLadder = (Boolean) document.get( "applyRankCostMultiplierToLadder" ); - if ( applyRankCostMultiplierToLadder != null ) { - - rankLadder.setApplyRankCostMultiplierToLadder( applyRankCostMultiplierToLadder ); - } - else { - rankLadder.setApplyRankCostMultiplierToLadder( true ); - isDirty = true; - } + Double rankCostMultiplier = (Double) document.get( "rankCostMultiplierPerRank" ); + rankLadder.setRankCostMultiplierPerRank( rankCostMultiplier == null ? 0 : rankCostMultiplier ); + + Boolean applyRankCostMultiplierToLadder = (Boolean) document.get( "applyRankCostMultiplierToLadder" ); + if ( applyRankCostMultiplierToLadder != null ) { + rankLadder.setApplyRankCostMultiplierToLadder( applyRankCostMultiplierToLadder ); + } + else { + rankLadder.setApplyRankCostMultiplierToLadder( true ); + isDirty = true; + } -// getPermissions().clear(); -// Object perms = document.get( "permissions" ); -// if ( perms != null ) { -// List permissions = (List) perms; -// for ( String permission : permissions ) { -// getPermissions().add( permission ); -// } -// } -// -// -// getPermissionGroups().clear(); -// Object permsGroups = document.get( "permissionGroups" ); -// if ( perms != null ) { -// List permissionGroups = (List) permsGroups; -// for ( String permissionGroup : permissionGroups ) { -// getPermissionGroups().add( permissionGroup ); -// } -// } - - - - if ( isDirty ) { - PrisonRanks.getInstance().getLadderManager().save( rankLadder ); - } + if ( isDirty ) { + PrisonRanks.getInstance().getLadderManager().save( rankLadder ); + } - return rankLadder; - } + return rankLadder; + } } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactory.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactory.java index 1828d5d89..5d465c5c8 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactory.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactory.java @@ -20,7 +20,6 @@ import tech.mcprison.prison.ranks.commands.RankUpCommand; import tech.mcprison.prison.ranks.events.FirstJoinEvent; import tech.mcprison.prison.ranks.managers.LadderManager; -import tech.mcprison.prison.ranks.managers.PlayerManager; import tech.mcprison.prison.store.Document; import tech.mcprison.prison.util.ConversionUtil; @@ -28,33 +27,28 @@ public class RankPlayerFactory { JsonFileIO jfIO = new JsonFileIO(); - @SuppressWarnings( "unchecked" ) - public RankPlayer createRankPlayer(Document document) { - RankPlayer rankPlayer = null; - - - String uuidStr = document.containsKey("uid") ? - (String) document.get("uid") : - document.containsKey("uuid") ? - (String) document.get("uuid") : - null; - - UUID uuid = UUID.fromString( uuidStr ); - - rankPlayer = new RankPlayer( uuid ); - - LinkedTreeMap ranksLocal = - (LinkedTreeMap) document.get("ranks"); -// LinkedTreeMap prestigeLocal = -// (LinkedTreeMap) document.get("prestige"); - -// LinkedTreeMap blocksMinedLocal = -// (LinkedTreeMap) document.get("blocksMined"); - - LadderManager ladderManager = PrisonRanks.getInstance().getLadderManager(); - + @SuppressWarnings( "unchecked" ) + public RankPlayer createRankPlayer(Document document) { + RankPlayer rankPlayer = null; + + + String uuidStr = document.containsKey("uid") ? + (String) document.get("uid") : + document.containsKey("uuid") ? + (String) document.get("uuid") : + null; + + UUID uuid = UUID.fromString( uuidStr ); + + rankPlayer = new RankPlayer( uuid ); + + LinkedTreeMap ranksLocal = + (LinkedTreeMap) document.get("ranks"); + + LadderManager ladderManager = PrisonRanks.getInstance().getLadderManager(); + - for (String key : ranksLocal.keySet()) { + for (String key : ranksLocal.keySet()) { Object rankObj = ranksLocal.get(key); @@ -74,8 +68,6 @@ public RankPlayer createRankPlayer(Document document) { // Setups up the rank for the player and recalculates all of the rank multipliers: rankPlayer.addRank( rank ); - // Obsolete, but used when upgrading from an older version of prison. -// rankPlayer.getRanksRefs().put(key, rankId ); } else { @@ -100,7 +92,6 @@ public RankPlayer createRankPlayer(Document document) { // Use of rankId is obsolete so ignore it: int rankId = rData.getRankId(); -// rankPlayer.getRanksRefs().put( rData.getLadderName(), rankId ); RankLadder ladder = ladderManager.getLadder( ladderName ); @@ -131,30 +122,17 @@ public RankPlayer createRankPlayer(Document document) { } } - } - - - // Sets up the Ladder and Rank objects: - setupLadderRanks( rankPlayer ); - - - - -// for (String key : prestigeLocal.keySet()) { -// prestige.put(key, RankUtil.doubleToInt(prestigeLocal.get(key))); -// } + } -//// rankPlayer.setBlocksMined( new HashMap<>() ); -// if ( blocksMinedLocal != null ) { -// for (String key : blocksMinedLocal.keySet()) { -// rankPlayer.getBlocksMined().put(key, ConversionUtil.doubleToInt(blocksMinedLocal.get(key))); -// } -// } - + + // Sets up the Ladder and Rank objects: + setupLadderRanks( rankPlayer ); + - Object namesListObject = document.get( "names" ); - if ( namesListObject != null ) { + Object namesListObject = document.get( "names" ); + + if ( namesListObject != null ) { for ( Object rankPlayerNameMap : (ArrayList) namesListObject ) { LinkedTreeMap rpnMap = (LinkedTreeMap) rankPlayerNameMap; @@ -169,75 +147,73 @@ public RankPlayer createRankPlayer(Document document) { } } - } - - - - if ( document.get("balance") != null ) { - - rankPlayer.setCurrentBalanceTemp( (Double) document.get("balance") ); - } - - if ( document.get("totalBlocks") != null ) { - - rankPlayer.setTotalBlocksTemp( getLong( rankPlayer.getName(), "totalBlocks", document ) ); - } - - if ( document.get("totalTokens") != null ) { - - rankPlayer.setTotalTokensTemp( getLong( rankPlayer.getName(), "totalTokens", document ) ); - } - - if ( document.get("lastSeenDate") != null ) { - - rankPlayer.setLastSeenDateTemp( getLong( rankPlayer.getName(), "lastSeenDate", document ) ); - } - - - if ( document.get("lastSaved") != null ) { - rankPlayer.setLastSaved( getLong( rankPlayer.getName(), "lastSaved", document ) ); - } - + } - if ( document.get("lastRefreshed") != null ) { - rankPlayer.setLastRefreshed( getLong( rankPlayer.getName(), "lastRefreshed", document ) ); - } - - - - // The new field permsSnapShot will be a list of all of the player's perms, captured - // at major moments when they are online. Since perms are not available offline, - // this will provide a "rough" listing of what they maybe. Its beyond the scope of - // this snap shot to ensure these perms are "current"; if they change after this - // image is taken, then that's not our problem. - if ( document.get("permsSnapShot") != null ) { + if ( document.get("balance") != null ) { + + rankPlayer.setCurrentBalanceTemp( (Double) document.get("balance") ); + } + + if ( document.get("totalBlocks") != null ) { + + rankPlayer.setTotalBlocksTemp( getLong( rankPlayer.getName(), "totalBlocks", document ) ); + } + + if ( document.get("totalTokens") != null ) { + + rankPlayer.setTotalTokensTemp( getLong( rankPlayer.getName(), "totalTokens", document ) ); + } + + if ( document.get("lastSeenDate") != null ) { + + rankPlayer.setLastSeenDateTemp( getLong( rankPlayer.getName(), "lastSeenDate", document ) ); + } + + + if ( document.get("lastSaved") != null ) { + rankPlayer.setLastSaved( getLong( rankPlayer.getName(), "lastSaved", document ) ); + } + + + if ( document.get("lastRefreshed") != null ) { + rankPlayer.setLastRefreshed( getLong( rankPlayer.getName(), "lastRefreshed", document ) ); + } + + + + // The new field permsSnapShot will be a list of all of the player's perms, captured + // at major moments when they are online. Since perms are not available offline, + // this will provide a "rough" listing of what they maybe. Its beyond the scope of + // this snap shot to ensure these perms are "current"; if they change after this + // image is taken, then that's not our problem. + if ( document.get("permsSnapShot") != null ) { List perms = (List) document.get("permsSnapShot"); rankPlayer.setPermsSnapShot( perms ); - } + } - if ( document.get("sellallMultiplier") != null ) { + if ( document.get("sellallMultiplier") != null ) { double multValue = (Double) document.get("sellallMultiplier"); rankPlayer.setSellallMultiplierValue( multValue ); - } - - if ( document.get("sellallMultipliers") != null ) { + } + + if ( document.get("sellallMultipliers") != null ) { List mults = (List) document.get("sellallMultipliers"); rankPlayer.setSellallMultipliers( mults ); - } - - - return rankPlayer; - } + } + + + return rankPlayer; + } - private long getLong( String playerName, String field, Document document ) { - long value = 0L; - - Object obj = document.get(field); - if ( obj == null ) { - } + private long getLong( String playerName, String field, Document document ) { + long value = 0L; + + Object obj = document.get(field); + if ( obj == null ) { + } if ( obj instanceof Long ) { value = (Long) obj; } @@ -247,112 +223,105 @@ else if ( obj instanceof Double ) { } return value; - } - public static Document toDocument( RankPlayer rankPlayer ) { + } + + + public static Document toDocument( RankPlayer rankPlayer ) { // Update some stats from the playerCache: PlayerCachePlayerData cacheData = rankPlayer.getPlayerCache().getOnlinePlayerCached(rankPlayer); rankPlayer.updateTotalLastValues( cacheData , false); - Document ret = new Document(); - ret.put("uid", rankPlayer.getUUID()); - - - - Set ladders = rankPlayer.getLadderRanks().keySet(); - TreeMap playerRanks = new TreeMap<>(); - for (RankLadder ladder : ladders) { + Document ret = new Document(); + ret.put("uid", rankPlayer.getUUID()); + + + + Set ladders = rankPlayer.getLadderRanks().keySet(); + TreeMap playerRanks = new TreeMap<>(); + for (RankLadder ladder : ladders) { PlayerRank rank = rankPlayer.getLadderRanks().get(ladder); RankPlayerFactoryDataRank rData = new RankPlayerFactoryDataRank( rank.getRank().getName(), ladder.getName(), rank.getRank().getId() ); -// String json = jfIO.toString( rData ); playerRanks.put( rData.getLadderName(), rData.getJsonObject() ); - // The key must be ladder name: -// playerRanks.put( rData.getRankName(), rData.getJsonObject() ); - } - - ret.put("ranks", playerRanks ); -// ret.put("ranks", rankPlayer.getRanksRefs() ); + } + + ret.put("ranks", playerRanks ); + + ret.put("names", rankPlayer.getNames()); + + + ret.put("balance", Double.valueOf( rankPlayer.getCurrentBalanceTemp() )); + ret.put("totalBlocks", Long.valueOf( rankPlayer.getTotalBlocksTemp() )); + ret.put("totalTokens", Long.valueOf( rankPlayer.getTotalTokensTemp() )); + ret.put("lastSeenDate", Long.valueOf( rankPlayer.getLastSeenDateTemp() )); + -// ret.put("prestige", this.prestige); - - ret.put("names", rankPlayer.getNames()); - - - ret.put("balance", Double.valueOf( rankPlayer.getCurrentBalanceTemp() )); - ret.put("totalBlocks", Long.valueOf( rankPlayer.getTotalBlocksTemp() )); - ret.put("totalTokens", Long.valueOf( rankPlayer.getTotalTokensTemp() )); - ret.put("lastSeenDate", Long.valueOf( rankPlayer.getLastSeenDateTemp() )); - - - - Player sPlayer = rankPlayer.getPlatformPlayer(); - - -// // create a timestamp: -// ret.put( "lastSeenDate", Long.valueOf( rankPlayer.getLastSeenDate() )); - // create a timestamp: - ret.put( "lastSaved", Long.valueOf( System.currentTimeMillis() )); + Player sPlayer = rankPlayer.getPlatformPlayer(); + + + + // create a timestamp: + ret.put( "lastSaved", Long.valueOf( System.currentTimeMillis() )); - - if ( sPlayer != null && sPlayer.isOnline() ) { - ret.put( "lastRefreshed", Long.valueOf( System.currentTimeMillis() )); - } - else { - ret.put( "lastRefreshed", rankPlayer.getLastRefreshed() ); - } + + if ( sPlayer != null && sPlayer.isOnline() ) { + ret.put( "lastRefreshed", Long.valueOf( System.currentTimeMillis() )); + } + else { + ret.put( "lastRefreshed", rankPlayer.getLastRefreshed() ); + } - // The new field permsSnapShot will be a list of all of the player's perms, captured - // at major moments when they are online. Since perms are not available offline, - // this will provide a "rough" listing of what they maybe. Its beyond the scope of - // this snap shot to ensure these perms are "current"; if they change after this - // image is taken, then that's not our problem. - List perms = new ArrayList<>(); - - - if ( sPlayer != null && sPlayer.isOnline() ) { + // The new field permsSnapShot will be a list of all of the player's perms, captured + // at major moments when they are online. Since perms are not available offline, + // this will provide a "rough" listing of what they maybe. Its beyond the scope of + // this snap shot to ensure these perms are "current"; if they change after this + // image is taken, then that's not our problem. + List perms = new ArrayList<>(); + + + if ( sPlayer != null && sPlayer.isOnline() ) { // If the player is online, get a fresh list of perms: perms = sPlayer.getPermissions(); rankPlayer.setPermsSnapShot(perms); - } - else { + } + else { // Otherwise since the player if offline, then save whatever permsSnapShot is already available: perms = rankPlayer.getPermsSnapShot(); - } - ret.put( "permsSnapShot", perms ); - - - double multValue = 1d; - if ( sPlayer != null && sPlayer.isOnline() ) { - multValue = sPlayer.getSellAllMultiplier(); - } - else { + } + ret.put( "permsSnapShot", perms ); + + + double multValue = 1d; + if ( sPlayer != null && sPlayer.isOnline() ) { + multValue = sPlayer.getSellAllMultiplier(); + } + else { // Otherwise since offline, save the existing list of multipliers: multValue = rankPlayer.getSellallMultiplierValue(); - } - ret.put( "sellallMultiplier", multValue ); + } + ret.put( "sellallMultiplier", multValue ); - List multipliers = new ArrayList<>(); - if ( sPlayer != null && sPlayer.isOnline() ) { - multipliers = sPlayer.getSellAllMultiplierListings(); - } - else { + List multipliers = new ArrayList<>(); + if ( sPlayer != null && sPlayer.isOnline() ) { + multipliers = sPlayer.getSellAllMultiplierListings(); + } + else { // Otherwise since offline, save the existing list of multipliers: multipliers = rankPlayer.getSellallMultipliers(); - } - ret.put("sellallMultipliers", multipliers); + } + ret.put("sellallMultipliers", multipliers); -// ret.put("blocksMined", rankPlayer.getBlocksMined() ); - return ret; - } + return ret; + } @@ -370,43 +339,42 @@ public static Document toDocument( RankPlayer rankPlayer ) { */ public void firstJoin( RankPlayer rankPlayer) { - RankLadder defaultLadder = PrisonRanks.getInstance().getDefaultLadder(); - - if ( defaultLadder == null ) { - - Output.get().logError( "RankPlayerFactory.firstJoin: No default ladder!!" ); - - } - else if ( !rankPlayer.getLadderRanks().containsKey( defaultLadder ) ) { - - Optional firstRank = defaultLadder.getLowestRank(); - - if ( firstRank.isPresent() ) { - Rank defaultRank = firstRank.get(); - - - RankUpCommand rankupCommands = PrisonRanks.getInstance().getRankManager().getRankupCommands(); - - rankupCommands.setPlayerRankFirstJoin( rankPlayer, defaultRank ); - rankPlayer.setDirty( true ); - - - // Saves the new player's rank: - PrisonRanks.getInstance().getPlayerManager().savePlayer(rankPlayer); - -// rankPlayer.addRank( defaultRank ); - - Prison.get().getEventBus().post(new FirstJoinEvent( rankPlayer )); - - FirstJoinHandlerMessages messages = new FirstJoinHandlerMessages(); - Output.get().logWarn( messages.firstJoinSuccess( rankPlayer.getName() ) ); - - } else { - - FirstJoinHandlerMessages messages = new FirstJoinHandlerMessages(); - Output.get().logWarn( messages.firstJoinWarningNoRanksOnServer() ); - } - } + RankLadder defaultLadder = PrisonRanks.getInstance().getDefaultLadder(); + + if ( defaultLadder == null ) { + + Output.get().logError( "RankPlayerFactory.firstJoin: No default ladder!!" ); + + } + else if ( !rankPlayer.getLadderRanks().containsKey( defaultLadder ) ) { + + Optional firstRank = defaultLadder.getLowestRank(); + + if ( firstRank.isPresent() ) { + Rank defaultRank = firstRank.get(); + + + RankUpCommand rankupCommands = PrisonRanks.getInstance().getRankManager().getRankupCommands(); + + rankupCommands.setPlayerRankFirstJoin( rankPlayer, defaultRank ); + rankPlayer.setDirty( true ); + + + // Saves the new player's rank: + PrisonRanks.getInstance().getPlayerManager().savePlayer(rankPlayer); + + + Prison.get().getEventBus().post(new FirstJoinEvent( rankPlayer )); + + FirstJoinHandlerMessages messages = new FirstJoinHandlerMessages(); + Output.get().logWarn( messages.firstJoinSuccess( rankPlayer.getName() ) ); + + } else { + + FirstJoinHandlerMessages messages = new FirstJoinHandlerMessages(); + Output.get().logWarn( messages.firstJoinWarningNoRanksOnServer() ); + } + } } @@ -418,15 +386,16 @@ else if ( !rankPlayer.getLadderRanks().containsKey( defaultLadder ) ) { * @param ladderName The ladder's name. */ public boolean removeLadder( RankPlayer rankPlayer, String ladderName ) { - boolean results = false; + boolean results = false; + if ( !ladderName.equalsIgnoreCase(LadderManager.LADDER_DEFAULT) ) { - Integer id = rankPlayer.getRanksRefs().remove(ladderName); - results = (id != null); - - RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder( ladderName ); - if ( ladder != null && !ladder.getName().equalsIgnoreCase( LadderManager.LADDER_DEFAULT ) ) { - rankPlayer.getLadderRanks().remove( ladder ); - } + Integer id = rankPlayer.getRanksRefs().remove(ladderName); + results = (id != null); + + RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder( ladderName ); + if ( ladder != null && !ladder.getName().equalsIgnoreCase( LadderManager.LADDER_DEFAULT ) ) { + rankPlayer.getLadderRanks().remove( ladder ); + } } return results; @@ -444,20 +413,20 @@ public boolean removeLadder( RankPlayer rankPlayer, String ladderName ) { * @return */ public PlayerRank getRank( RankPlayer rankPlayer, RankLadder ladder, boolean force ) { - PlayerRank results = getRank( rankPlayer, ladder ); - - if ( force && results == null ) { - Rank tempRank = ladder.getLowestRank().get(); - - if ( tempRank != null ) { - results = new PlayerRank( tempRank ); - - // force cost calculations with a zero multiplier: - results.applyMultiplier( 0 ); - } - } - - return results; + PlayerRank results = getRank( rankPlayer, ladder ); + + if ( force && results == null ) { + Rank tempRank = ladder.getLowestRank().get(); + + if ( tempRank != null ) { + results = new PlayerRank( tempRank ); + + // force cost calculations with a zero multiplier: + results.applyMultiplier( 0 ); + } + } + + return results; } /** @@ -467,64 +436,23 @@ public PlayerRank getRank( RankPlayer rankPlayer, RankLadder ladder, boolean for * @return An optional containing the {@link Rank} if found, or empty if there isn't a rank by that ladder for this player. */ public PlayerRank getRank( RankPlayer rankPlayer, RankLadder ladder ) { - PlayerRank results = null; - - if ( ladder != null ) { - - Set keys = rankPlayer.getLadderRanks().keySet(); - for ( RankLadder key : keys ) - { - if ( key != null && key.getName().equalsIgnoreCase( ladder.getName() ) ) { - results = rankPlayer.getLadderRanks().get( key ); - break; - } - } - } + PlayerRank results = null; + + if ( ladder != null ) { + + Set keys = rankPlayer.getLadderRanks().keySet(); + for ( RankLadder key : keys ) + { + if ( key != null && key.getName().equalsIgnoreCase( ladder.getName() ) ) { + results = rankPlayer.getLadderRanks().get( key ); + break; + } + } + } - return results; - -// if (!ranksRefs.containsKey(ladder.getName())) { -// return null; -// } -// int id = ranksRefs.get(ladder.getName()); -// return PrisonRanks.getInstance().getRankManager().getRank(id); + return results; } - -// /** -// * Returns all ladders this player is a part of, along with each rank the player has in that ladder. -// * -// * @return The map containing this data. -// */ -// public Map getLadderRanksx( RankPlayer rankPlayer ) { -// -// if ( rankPlayer.getLadderRanks().isEmpty() && !rankPlayer.getRanksRefs().isEmpty() ) { -// -// //Map ret = new HashMap<>(); -// -// for (Map.Entry entry : rankPlayer.getRanksRefs().entrySet()) { -// RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder(entry.getKey()); -// -// if ( ladder == null ) { -// continue; // Skip it -// } -// -// Rank rank = PrisonRanks.getInstance().getRankManager().getRank(entry.getValue()); -// if ( rank == null ) { -// continue; // Skip it -// } -// -// PlayerRank pRank = new PlayerRank( rank ); -// -// rankPlayer.getLadderRanks().put(ladder, pRank); -// } -// -// // Need to recalculate all rank multipliers: -// rankPlayer.recalculateRankMultipliers(); -// } -// -// return rankPlayer.getLadderRanks(); -// } /** @@ -538,35 +466,31 @@ public PlayerRank getRank( RankPlayer rankPlayer, RankLadder ladder ) { */ public void setupLadderRanks( RankPlayer rankPlayer ) { - if ( rankPlayer.getLadderRanks().isEmpty() && !rankPlayer.getRanksRefs().isEmpty() ) { - - //Map ret = new HashMap<>(); - - for (Map.Entry entry : rankPlayer.getRanksRefs().entrySet()) { - String ladderName = entry.getKey(); - int rankId = entry.getValue(); - - RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder( ladderName ); - - if ( ladder != null ) { - - for ( Rank rank : ladder.getRanks() ) { - if ( rank.getId() == rankId ) { - - PlayerRank pRank = rankPlayer.calculateTargetPlayerRank( rank ); -// PlayerRank pRank = createPlayerRank( rank ); - rankPlayer.getLadderRanks().put( ladder, pRank ); - - break; - } - } - } - } - - // Need to recalculate all rank multipliers: This may be redundant. - rankPlayer.recalculateRankMultipliers(); - } - + if ( rankPlayer.getLadderRanks().isEmpty() && !rankPlayer.getRanksRefs().isEmpty() ) { + + for (Map.Entry entry : rankPlayer.getRanksRefs().entrySet()) { + String ladderName = entry.getKey(); + int rankId = entry.getValue(); + + RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder( ladderName ); + + if ( ladder != null ) { + + for ( Rank rank : ladder.getRanks() ) { + if ( rank.getId() == rankId ) { + + PlayerRank pRank = rankPlayer.calculateTargetPlayerRank( rank ); + rankPlayer.getLadderRanks().put( ladder, pRank ); + + break; + } + } + } + } + + // Need to recalculate all rank multipliers: This may be redundant. + rankPlayer.recalculateRankMultipliers(); + } } @@ -579,15 +503,8 @@ public void setupLadderRanks( RankPlayer rankPlayer ) { */ public PlayerRank getRank( RankPlayer rankPlayer, String ladderName ) { - RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder( ladderName ); - return getRank( rankPlayer, ladder ); - -// Rank results = null; -// if (ladder != null && ranksRefs.containsKey(ladder)) { -// int id = ranksRefs.get(ladder); -// results = PrisonRanks.getInstance().getRankManager().getRank(id); -// } -// return results; + RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder( ladderName ); + return getRank( rankPlayer, ladder ); } @@ -605,46 +522,20 @@ public PlayerRank getRank( RankPlayer rankPlayer, String ladderName ) { * @return */ public PlayerRank createPlayerRank( Rank rank ) { - PlayerRank results = new PlayerRank( rank ); - - double rankMultiplier = results.getLadderBasedRankMultiplier( rank ); - - results.setRankCost( rankMultiplier ); - - return results; + PlayerRank results = new PlayerRank( rank ); + + double rankMultiplier = results.getLadderBasedRankMultiplier( rank ); + + results.setRankCost( rankMultiplier ); + + return results; } -// private PlayerRank createPlayerRank( Rank rank, double rankMultiplier ) { -// PlayerRank results = new PlayerRank( rank, rankMultiplier ); -// -// return results; -// } public PlayerRank getTargetPlayerRankForPlayer( PlayerRank playerRank, RankPlayer player, Rank targetRank ) { PlayerRank targetPlayerRank = player.calculateTargetPlayerRank( targetRank ); -// if ( targetRank != null ) { -// -// double targetRankMultiplier = playerRank.getLadderBasedRankMultiplier( targetRank ); -// -// PlayerRank pRankForPLayer = getRank( player, targetRank.getLadder() ); -// double existingRankMultiplier = pRankForPLayer == null ? 0 : -// playerRank.getLadderBasedRankMultiplier( pRankForPLayer.getRank() ); -// -// // Get the player's total rankMultiplier from the default ladder -// // because they will always have a rank there: -// PlayerRank pRank = getRank( player, LadderManager.LADDER_DEFAULT ); -// double playerMultipler = pRank == null ? 0 : pRank.getRankMultiplier(); -// -// // So the actual rank multiplier that needs to be used, is based upon the -// // Player's current multiplier PLUS the multiplier for the target rank -// // AND MINUS the multiplier for the current rank the player has within the -// // target rank's ladder. -// double rankMultiplier = playerMultipler + targetRankMultiplier - existingRankMultiplier; -// -// targetPlayerRank = createPlayerRank( targetRank, rankMultiplier ); -// } return targetPlayerRank; } @@ -656,6 +547,5 @@ public double getRawRankCost( Rank rank ) { public void setRawRankCost( Rank rank, double rawCost ) { rank.setCost( rawCost ); } - } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerSortableLadderRankBalance.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerSortableLadderRankBalance.java index 8a5185a09..00ebd8078 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerSortableLadderRankBalance.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerSortableLadderRankBalance.java @@ -162,15 +162,10 @@ private double calculateTopScore( RankPlayer rp1, Rank rank, double balance ) { Rank nextRank = rank.getRankNext(); PlayerRank pRank = rp1.getLadderRanks().get( rank.getLadder() ); -// PlayerRank pRank = rp1.getRank( rank.getLadder() ); // This calculates the target rank, and takes in to consideration the player's existing rank: PlayerRank pRankNext = rp1.calculateTargetPlayerRank( nextRank ); -// PlayerRank pRankNext = pRank.getTargetPlayerRankForPlayer( rp1, nextRank ); -// PlayerRank pRankNext = nextRank == null ? null : -// new PlayerRank( nextRank, pRank.getRankMultiplier() ); - double nextRankCost = nextRank == null ? pRank.getRankCost() : pRankNext.getRankCost(); topScore = nextRankCost / balance; 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 7543af291..214493e6d 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 @@ -93,8 +93,6 @@ public static TopNPlayers getInstance() { if ( instance == null ) { instance = new TopNPlayers(); -// instance.loadSaveFile(); - instance.launchTopNPlayerUpdateAsyncTask(); } } @@ -292,8 +290,6 @@ public void forceReloadAllPlayers() { setStatsBuildDataNanoSec( end - start ); -// saveToJson(); - } } @@ -474,10 +470,6 @@ public void refreshAndSort() { addPlayerData( topN, PlayerState.online ); - // Add player will always set the PlayerState to offline, so need to set it to - // online after addPlayerData() is called; -// topN.setPlayerState( PlayerState.online ); - setDirty( true ); @@ -501,9 +493,6 @@ public void refreshAndSort() { setTopNList(newTopNList); setArchivedList(newArchivedList); -// // sort: -// sortTopN(); - // If there has been any changes since the last save, then // save it: if ( isDirty() ) { @@ -626,35 +615,35 @@ public void updatePlayerData( RankPlayer rPlayer ) { } public String getTopNStats() { - - int topNSize = getTopNSize(); - int archivedSize = getArchivedSize(); - - - DecimalFormat dFmt = Prison.get().getDecimalFormat("#,##0.000"); - DecimalFormat iFmt = Prison.get().getDecimalFormat("#,##0"); - - String statsBuildMs = dFmt.format( - getStatsBuildDataNanoSec() / 1_000_000 ); - String statsRefreshMs = dFmt.format( - getStatsRefreshDataNanoSec() / 1_000_000 ); - String statsSaveMs = dFmt.format( - getStatsSaveDataNanoSec() / 1_000_000 ); - String statsLoadMs = dFmt.format( - getStatsLoadDataNanoSec() / 1_000_000 ); - - String msg = String.format( - "&7topNstats:&3 topNs: %s archives: %s buildMs: %s refreshMs: %s " + - "saveMs: %s loadMs: %s ", - iFmt.format(topNSize), - iFmt.format(archivedSize), - statsBuildMs, - statsRefreshMs, - statsSaveMs, - statsLoadMs - ); - - return msg; + + int topNSize = getTopNSize(); + int archivedSize = getArchivedSize(); + + + DecimalFormat dFmt = Prison.get().getDecimalFormat("#,##0.000"); + DecimalFormat iFmt = Prison.get().getDecimalFormat("#,##0"); + + String statsBuildMs = dFmt.format( + getStatsBuildDataNanoSec() / 1_000_000 ); + String statsRefreshMs = dFmt.format( + getStatsRefreshDataNanoSec() / 1_000_000 ); + String statsSaveMs = dFmt.format( + getStatsSaveDataNanoSec() / 1_000_000 ); + String statsLoadMs = dFmt.format( + getStatsLoadDataNanoSec() / 1_000_000 ); + + String msg = String.format( + "&7topNstats:&3 topNs: %s archives: %s buildMs: %s refreshMs: %s " + + "saveMs: %s loadMs: %s ", + iFmt.format(topNSize), + iFmt.format(archivedSize), + statsBuildMs, + statsRefreshMs, + statsSaveMs, + statsLoadMs + ); + + return msg; } public int getTopNSize() { @@ -687,44 +676,44 @@ public RankPlayer getTopNRankArchivedPlayer( int rankPosition ) { * @return */ private RankPlayer getTopNRankPlayer( int rankPosition, boolean archived ) { - RankPlayer rPlayer = null; - - if ( PrisonRanks.getInstance() != null && - PrisonRanks.getInstance().isEnabled() && - PrisonRanks.getInstance().getPlayerManager() != null ) { - - ArrayList tList = - archived ? - getArchivedList() : - getTopNList(); - - if ( rankPosition >= 0 && tList.size() > rankPosition ) { - - TopNPlayersData topN = tList.get( rankPosition ); - - rPlayer = topN.getrPlayer(); - - if ( rPlayer == null && PrisonRanks.getInstance().getPlayerManager() != null ) { - - UUID nullUuid = null; - rPlayer = PrisonRanks.getInstance().getPlayerManager() - .getPlayer( nullUuid, topN.getName() ); - } - - // The topN has the last extracted values, so copy them to the rPlayer if - // it has not been updated. This would be good for the archives. - if ( rPlayer != null && topN.getRankScore() != 0 && rPlayer.getRankScore() == 0 ) { - - rPlayer.setRankScore( topN.getRankScore() ); - rPlayer.setRankScorePenalty( topN.getRankScorePenalty() ); - - rPlayer.setRankScoreBalance( topN.getBalance() ); - rPlayer.setRankScoreCurrency( topN.getBalanceCurrency() ); - - } - - } - } + RankPlayer rPlayer = null; + + if ( PrisonRanks.getInstance() != null && + PrisonRanks.getInstance().isEnabled() && + PrisonRanks.getInstance().getPlayerManager() != null ) { + + ArrayList tList = + archived ? + getArchivedList() : + getTopNList(); + + if ( rankPosition >= 0 && tList.size() > rankPosition ) { + + TopNPlayersData topN = tList.get( rankPosition ); + + rPlayer = topN.getrPlayer(); + + if ( rPlayer == null && PrisonRanks.getInstance().getPlayerManager() != null ) { + + UUID nullUuid = null; + rPlayer = PrisonRanks.getInstance().getPlayerManager() + .getPlayer( nullUuid, topN.getName() ); + } + + // The topN has the last extracted values, so copy them to the rPlayer if + // it has not been updated. This would be good for the archives. + if ( rPlayer != null && topN.getRankScore() != 0 && rPlayer.getRankScore() == 0 ) { + + rPlayer.setRankScore( topN.getRankScore() ); + rPlayer.setRankScorePenalty( topN.getRankScorePenalty() ); + + rPlayer.setRankScoreBalance( topN.getBalance() ); + rPlayer.setRankScoreCurrency( topN.getBalanceCurrency() ); + + } + + } + } return rPlayer; diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/TopNPlayersData.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/TopNPlayersData.java index 7319192e0..9b1d1222f 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/TopNPlayersData.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/TopNPlayersData.java @@ -79,18 +79,9 @@ public TopNPlayersData( RankPlayer rPlayer) { this.name = rPlayer.getName(); this.uuid = rPlayer.getUUID().toString(); -// this.playerFileName = rPlayer.getPlayerFileName(); - -// // Note: the nextPlayer rank could be in either the default ladder, -// // or the next prestige rank if at end of default ladder. -// PlayerRank nextRank = rPlayer.getNextPlayerRank(); - // This may be expensive getting lastSeen from the player's cache data: setLastSeen( rPlayer.getLastSeenDateTemp() ); -// setLastSeen( rPlayer.getPlayerCachePlayerData().getLastSeenDate() ); - -// this.lastSeenFormatted = sdFmt.format( new Date( this.lastSeen ) ); updateRankPlayer( rPlayer ); @@ -111,8 +102,6 @@ public void updateRankPlayer( RankPlayer rPlayer ) { setBlocks( rPlayer.getTotalBlocksTemp() ); setTokens( rPlayer.getTotalTokensTemp() ); -// setTimeMining( rPlayer.getPlayerCachePlayerData().getOnlineMiningTimeTotal() ); -// setTimeOnline( rPlayer.getPlayerCachePlayerData().getOnlineTimeTotal() ); } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/events/FirstJoinEvent.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/events/FirstJoinEvent.java index 67c9cff31..2aa3fab50 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/events/FirstJoinEvent.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/events/FirstJoinEvent.java @@ -27,24 +27,12 @@ */ public class FirstJoinEvent { - /* - * Fields & Constants - */ - private RankPlayer player; - /* - * Constructors - */ - public FirstJoinEvent(RankPlayer player) { this.player = player; } - /* - * Getters & Setters - */ - public RankPlayer getPlayer() { return player; } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/events/RankUpEvent.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/events/RankUpEvent.java index a5bcc0ef2..4ff87f54e 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/events/RankUpEvent.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/events/RankUpEvent.java @@ -12,10 +12,6 @@ */ public class RankUpEvent { - /* - * Fields & Constants - */ - private RankPlayer player; private Rank oldRank; private Rank newRank; @@ -27,9 +23,6 @@ public class RankUpEvent { private boolean canceled = false; private String cancelReason = null; - /* - * Constructor - */ public RankUpEvent(RankPlayer player, Rank oldRank, Rank newRank, double cost, @@ -45,9 +38,6 @@ public RankUpEvent(RankPlayer player, this.forceCharge = forceCharge; } - /* - * Getters & Setters - */ public RankPlayer getPlayer() { return player; 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 953640ff1..27959f796 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 @@ -45,19 +45,11 @@ public class LadderManager public static final String LADDER_DEFAULT = "default"; public static final String LADDER_PRESTIGES = "prestiges"; - /* - * Fields & Constants - */ - private Collection collection; private List loadedLadders; private PrisonRanks prisonRanks; - /* - * Constructor - */ - /** * Instantiate this {@link LadderManager}. * @param prisonRanks @@ -69,9 +61,6 @@ public LadderManager(Collection collection, PrisonRanks prisonRanks) { this.prisonRanks = prisonRanks; } - /* - * Methods & Getters & Setters - */ /** * Loads a ladder from a file into the loaded ladders list. @@ -91,7 +80,7 @@ public void loadLadder(String fileKey, RankManager rankManager) throws IOExcepti // Will be dirty if load a ladder and the rank name does not exist and it adds them: if ( ladder.isDirty() ) { - saveLadder(ladder); + saveLadder(ladder); } } @@ -111,13 +100,13 @@ public void loadLadders( RankManager rankManager ) for ( RankLadder ladder : loadedLadders ) { - // If old file exists, then set dirty so it can be saved and update the file name: - checkIfOldFileExists( ladder ); - - // Will be dirty if load a ladder and the rank name does not exist and it adds them: - if ( ladder.isDirty() ) { - saveLadder(ladder); - } + // If old file exists, then set dirty so it can be saved and update the file name: + checkIfOldFileExists( ladder ); + + // Will be dirty if load a ladder and the rank name does not exist and it adds them: + if ( ladder.isDirty() ) { + saveLadder(ladder); + } } } @@ -128,9 +117,9 @@ public void loadLadders( RankManager rankManager ) * @param ladder */ private void checkIfOldFileExists(RankLadder ladder) { - if ( collection.exists( getLadderNameOld(ladder) )) { - ladder.setDirty( true ); - } + if ( collection.exists( getLadderNameOld(ladder) )) { + ladder.setDirty( true ); + } } /** @@ -153,14 +142,14 @@ public void saveLadder(RankLadder ladder, String fileKey, String oldFileName) th */ private void saveLadder(RankLadder ladder) throws IOException { - String fileLadderNameNew = getLadderNameNew(ladder); - String fileLadderNameOld = getLadderNameOld(ladder); - + String fileLadderNameNew = getLadderNameNew(ladder); + String fileLadderNameOld = getLadderNameOld(ladder); + this.saveLadder(ladder, fileLadderNameNew, fileLadderNameOld); } private String getLadderNameNew( RankLadder ladder ) { - return "ladder_" + ladder.getName(); + return "ladder_" + ladder.getName(); } /** @@ -173,7 +162,7 @@ private String getLadderNameNew( RankLadder ladder ) { * @return */ private String getLadderNameOld( RankLadder ladder ) { - return ladder.getId() == -1 ? null : "ladder_" + ladder.getId(); + return ladder.getId() == -1 ? null : "ladder_" + ladder.getId(); } /** @@ -192,20 +181,20 @@ private String getLadderNameOld( RankLadder ladder ) { * @return success or failure. A value of true indicates the save was successful. */ public boolean save( RankLadder ladder ) { - boolean success = false; - - try { - saveLadder( ladder ); - success = true; - } - catch ( IOException e ) { - - String errorMessage = cannotSaveLadderFile( ladder.getName(), e.getMessage() ); - - Output.get().logError( errorMessage, e ); - } - - return success; + boolean success = false; + + try { + saveLadder( ladder ); + success = true; + } + catch ( IOException e ) { + + String errorMessage = cannotSaveLadderFile( ladder.getName(), e.getMessage() ); + + Output.get().logError( errorMessage, e ); + } + + return success; } /** @@ -229,7 +218,7 @@ public void saveLadders() throws IOException { */ public RankLadder createLadder(String name) { // Set the default values... - // ladder id is no longer used, so use -1: + // ladder id is no longer used, so use -1: RankLadder newLadder = new RankLadder( -1, name ); // RankLadder newLadder = new RankLadder( getNextAvailableId(), name ); @@ -291,16 +280,15 @@ public boolean removeLadder(RankLadder ladder) { collection.delete( getLadderNameNew(ladder) ); collection.delete( getLadderNameOld(ladder) ); -// collection.remove("ladder_" + ladder.id); return true; } public RankLadder getLadderDefault() { - return getLadder( RankLadder.DEFAULT ); + return getLadder( RankLadder.DEFAULT ); } public RankLadder getLadderPrestiges() { - return getLadder( RankLadder.PRESTIGES ); + return getLadder( RankLadder.PRESTIGES ); } /** @@ -310,14 +298,14 @@ public RankLadder getLadderPrestiges() { * @return An optional containing either the {@link RankLadder} if it could be found, or empty if it does not exist by the specified name. */ public RankLadder getLadder(String name) { - RankLadder results = null; - for ( RankLadder rankLadder : loadedLadders ) { - if ( rankLadder.getName().equalsIgnoreCase( name ) ) { - results = rankLadder; - break; + RankLadder results = null; + for ( RankLadder rankLadder : loadedLadders ) { + if ( rankLadder.getName().equalsIgnoreCase( name ) ) { + results = rankLadder; + break; + } } - } - return results; + return results; } /** @@ -327,14 +315,14 @@ public RankLadder getLadder(String name) { * @return the {@link RankLadder} if it could be found, or null if it does not exist by the specified id. */ public RankLadder getLadder(int id) { - RankLadder results = null; - for ( RankLadder rankLadder : loadedLadders ) { - if ( rankLadder.getId() == id ) { - results = rankLadder; - break; + RankLadder results = null; + for ( RankLadder rankLadder : loadedLadders ) { + if ( rankLadder.getId() == id ) { + results = rankLadder; + break; + } } - } - return results; + return results; } /** @@ -399,18 +387,18 @@ public String printRankLadderInfoDetail( RankLadder ladder ) { 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 %5d %-12s %-12s", - ladder.getName(), - dFmt.format( ladder.getRankCostMultiplierPerRank() ), - rankCount, - (firstRank == null ? "" : firstRank.getName()), - (lastRank == null ? "" : lastRank.getName()) - ); - + 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 %5d %-12s %-12s", + ladder.getName(), + dFmt.format( ladder.getRankCostMultiplierPerRank() ), + rankCount, + (firstRank == null ? "" : firstRank.getName()), + (lastRank == null ? "" : lastRank.getName()) + ); + return ladderInfo; } @@ -448,19 +436,19 @@ public void createDefaultLadder() { if ( rankLadder == null ) { - String failureMsg = prisonRanks.prisonRanksFailureCreateDefaultLadderMsg(); - - Output.get().logError( failureMsg ); + String failureMsg = prisonRanks.prisonRanksFailureCreateDefaultLadderMsg(); + + Output.get().logError( failureMsg ); prisonRanks.getStatus().toFailed( failureMsg ); return; } if ( !save( rankLadder ) ) { - String failureMsg = prisonRanks.prisonRanksFailureSavingDefaultLadderMsg(); - - Output.get().logError( failureMsg ); - prisonRanks.getStatus().toFailed( failureMsg ); + String failureMsg = prisonRanks.prisonRanksFailureSavingDefaultLadderMsg(); + + Output.get().logError( failureMsg ); + prisonRanks.getStatus().toFailed( failureMsg ); } } @@ -469,18 +457,18 @@ public void createDefaultLadder() { if ( rankLadder == null ) { - String failureMsg = prisonRanks.prisonRanksFailureCreatePrestigeLadderMsg(); - - Output.get().logError( failureMsg ); + String failureMsg = prisonRanks.prisonRanksFailureCreatePrestigeLadderMsg(); + + Output.get().logError( failureMsg ); prisonRanks.getStatus().toFailed( failureMsg ); return; } if ( !save( rankLadder ) ) { - String failureMsg = prisonRanks.prisonRanksFailureSavingPrestigeLadderMsg(); - - Output.get().logError( failureMsg ); + String failureMsg = prisonRanks.prisonRanksFailureSavingPrestigeLadderMsg(); + + Output.get().logError( failureMsg ); prisonRanks.getStatus().toFailed( failureMsg ); } } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java index c75ddce14..12a69a397 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java @@ -106,35 +106,6 @@ public PlayerManager(Collection collection) { - /* - * Methods - */ - -// /** -// * Loads a player from a file and stores it in the registry for use on the server. -// * -// * @param playerFile The key that the player data is stored as. Case-sensitive. -// * @throws IOException If the file could not be read, or if the file does not exist. -// */ -// public void loadPlayer(String playerFile) throws IOException { -// Document document = collection.get(playerFile).orElseThrow(IOException::new); -// -// RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); -// -// RankPlayer rankPlayer = rankPlayerFactory.createRankPlayer(document); -// -// players.add( rankPlayer ); -// -// // add by uuid: -// playersByName.put( rankPlayer.getUUID().toString(), rankPlayer ); -// -// // add by name: -// if ( rankPlayer.getNames().size() > 0 ) { -// playersByName.put( rankPlayer.getDisplayName(), rankPlayer ); -// -// } -// } - public boolean isEnabled() { return enabled; } @@ -153,7 +124,7 @@ public void loadPlayers() throws IOException { for ( Document playerDocument : playerDocss ) { - RankPlayer rankPlayer = rankPlayerFactory.createRankPlayer(playerDocument); + RankPlayer rankPlayer = rankPlayerFactory.createRankPlayer(playerDocument); players.add( rankPlayer ); @@ -162,21 +133,16 @@ public void loadPlayers() throws IOException { // add by name: if ( rankPlayer.getNames().size() > 0 ) { - playersByName.put( rankPlayer.getDisplayName(), rankPlayer ); - - // add lowercased name: - playersByName.put( rankPlayer.getDisplayName().toLowerCase(), rankPlayer ); + playersByName.put( rankPlayer.getDisplayName(), rankPlayer ); + + // add lowercased name: + playersByName.put( rankPlayer.getDisplayName().toLowerCase(), rankPlayer ); } } -// players.forEach( -// document -> -// this.players.add( -// rankPlayerFactory.createRankPlayer(document) )); - } @@ -190,68 +156,37 @@ public void loadPlayers() throws IOException { * @see #savePlayer(RankPlayer) To save with the default conventional filename. */ private boolean savePlayer(RankPlayer player, String playerFile) throws IOException { - boolean success = false; - - if ( !player.isEnableDirty() || player.isEnableDirty() && player.isDirty() ) { - - collection.save(playerFile, RankPlayerFactory.toDocument( player ), null, "Player" ); - - player.setDirty( false ); - - success = true; - } -// RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); - -// collection.save(playerFile, RankPlayerFactory.toDocument( player ) ); -// collection.insert(playerFile, player.toDocument());y - - return success; + boolean success = false; + + if ( !player.isEnableDirty() || player.isEnableDirty() && player.isDirty() ) { + + collection.save(playerFile, RankPlayerFactory.toDocument( player ), null, "Player" ); + + player.setDirty( false ); + + success = true; + } + + return success; } public boolean savePlayer(RankPlayer player) { - boolean success = false; - - try { - success = this.savePlayer(player, player.filenamePlayer()); - } - catch (IOException e) { - - String errorMessage = cannotSaveNewPlayerFile( player.getName(), player.filenamePlayer() ); - - Output.get().logError( errorMessage, e); - } - - return success; + boolean success = false; + + try { + success = this.savePlayer(player, player.filenamePlayer()); + } + catch (IOException e) { + + String errorMessage = cannotSaveNewPlayerFile( player.getName(), player.filenamePlayer() ); + + Output.get().logError( errorMessage, e); + } + + return success; } - /** - * Saves every player in the registry. If one player fails to save, it will not - * prevent the others from being saved. - * - * @throws IOException If one of the players could not be saved. - * @see #savePlayer(RankPlayer, String) - */ -// public void savePlayers() throws IOException { -// for (RankPlayer player : players) { -// -// // Catch exceptions if a failed save so other players can be saved: -// try { -// savePlayer(player); -// } -// catch ( Exception e ) { -// -// String errorMessage = cannotSavePlayerFile( player.filename() ); -// -// if ( !getPlayerErrors().contains( errorMessage ) ) { -// getPlayerErrors().add( errorMessage ); -// Output.get().logError( errorMessage ); -// } -// -//// Output.get().logError(errorMessage, e); -// } -// } -// } - + /** *

If the player does not have a default rank, then assign it to them and * then save their new settings. @@ -280,18 +215,15 @@ public void checkPlayerDefaultRank( RankPlayer rPlayer ) { * */ public void connectPlayersToRanks( boolean checkPlayerBalances ) { - for ( RankPlayer player : players ) { - - for ( PlayerRank pRank : player.getLadderRanks().values() ) { - - pRank.getRank().addPlayer( player, checkPlayerBalances ); - } + for ( RankPlayer player : players ) { + + for ( PlayerRank pRank : player.getLadderRanks().values() ) { + + pRank.getRank().addPlayer( player, checkPlayerBalances ); + } } } - /* - * Getters & Setters - */ public List getPlayers() { return players; @@ -301,10 +233,6 @@ public TreeMap getPlayersByName() { return playersByName; } -// public List getPlayersByTop() { -// return playersByTop; -// } - public Set getPlayerErrors() { return playerErrors; } @@ -319,18 +247,17 @@ public Set getPlayerErrors() { */ public RankPlayer getPlayer(UUID uid, String playerName) { - RankPlayer results = null; -// boolean dirty = false; + RankPlayer results = null; - playerName = playerName == null ? "" : playerName.trim(); - - if ( !playerName.isEmpty() && getPlayersByName().containsKey( playerName ) ) { - results = getPlayersByName().get( playerName ); - } - else if ( !playerName.isEmpty() && getPlayersByName().containsKey( playerName.toLowerCase() ) ) { - results = getPlayersByName().get( playerName.toLowerCase() ); - } - else if ( uid != null && getPlayersByName().containsKey( uid.toString() ) ) { + playerName = playerName == null ? "" : playerName.trim(); + + if ( !playerName.isEmpty() && getPlayersByName().containsKey( playerName ) ) { + results = getPlayersByName().get( playerName ); + } + else if ( !playerName.isEmpty() && getPlayersByName().containsKey( playerName.toLowerCase() ) ) { + results = getPlayersByName().get( playerName.toLowerCase() ); + } + else if ( uid != null && getPlayersByName().containsKey( uid.toString() ) ) { results = getPlayersByName().get( uid.toString() ); if ( results != null ) { @@ -347,104 +274,60 @@ else if ( uid != null && getPlayersByName().containsKey( uid.toString() ) ) { } -// // If we don't have the player by name or UUID, we can only check -// if ( results == null ) { -// -// // Debug info on player when results are null from the first "search". -// debugLogPlayerInfo( "getPlayer(): UUID check (could not match on playerName):", playerName, -// uid == null ? "none" : uid.toString(), false ); -// -// for ( RankPlayer rankPlayer : players ) { -// if ( uid != null && rankPlayer.getUUID().equals(uid) || -// -// !playerName.isEmpty() && -// rankPlayer.getName() != null && -// rankPlayer.getName().equalsIgnoreCase( playerName ) ) { -// -// // This checks to see if they have a new name, if so, then adds it to the history: -// // But the UID must match: -// if ( uid != null && rankPlayer.getUUID().equals(uid) ) { -// rankPlayer.setEnableDirty( true ); -// rankPlayer.setDirty( rankPlayer.checkName( playerName ) ); -// } -// -// results = rankPlayer; -// break; -// } -// } -// } - -// Optional results = players.stream().filter( -// player -> (uid != null ? -// player.uid.equals(uid) : -// ( playerName != null || playerName.trim().length() == 0 ? false : -// player.checkName( playerName )))).findFirst(); - - if ( results == null && uid != null && playerName != null && !"console".equalsIgnoreCase( playerName ) ) { - - // Player's uuid and name cannot be null if they are being added as a new prison player: - - debugLogPlayerInfo( "getPlayer(): addPlayer (final attempt: could not match on playerName or UUID):", - playerName, uid == null ? "none" : uid.toString(), false ); - - results = addPlayer(uid, playerName); - - // addPlayer() will save the player: -// if ( results != null ) { -// -// results.setDirty( true ); -// } - -// dirty = results != null; - } - -// // Save if dirty (changed or new): -// if ( results != null && results.isDirty() ) { -// savePlayer( results ); -// -// } - - return results; + + if ( results == null && uid != null && playerName != null && !"console".equalsIgnoreCase( playerName ) ) { + + // Player's uuid and name cannot be null if they are being added as a new prison player: + + debugLogPlayerInfo( "getPlayer(): addPlayer (final attempt: could not match on playerName or UUID):", + playerName, uid == null ? "none" : uid.toString(), false ); + + results = addPlayer(uid, playerName); + + } + + + return results; } public RankPlayer getPlayer( Player player ) { - RankPlayer rPlayer = null; - if ( player != null ) { - - // This function is called by SpigotCommander, as an example, and if we use the - // function 'player.getRankPlayer()' then that will become an endless loop. - // Also, we cannot use that either, because if the RankPlayer is null, then it - // needs to be added, which is what this class's 'getPlayer()' does. -// rPlayer = player.getRankPlayer(); - rPlayer = getPlayer( player.getUUID(), player.getName() ); - } - return rPlayer; + RankPlayer rPlayer = null; + if ( player != null ) { + + // This function is called by SpigotCommander, as an example, and if we use the + // function 'player.getRankPlayer()' then that will become an endless loop. + // Also, we cannot use that either, because if the RankPlayer is null, then it + // needs to be added, which is what this class's 'getPlayer()' does. + // rPlayer = player.getRankPlayer(); + rPlayer = getPlayer( player.getUUID(), player.getName() ); + } + return rPlayer; } public RankPlayer addPlayer( Player player ) { - return addPlayer( player.getUUID(), player.getName() ); + return addPlayer( player.getUUID(), player.getName() ); } private RankPlayer addPlayer( UUID uid, String playerName ) { - RankPlayer results = null; - - // addPlayer can only be rank in the primary thread: - if ( PrisonTaskSubmitter.isPrimaryThread() ) { - results = addPlayerSyncTask( uid, playerName ); - } - else if ( !getPlayersByName().containsKey( playerName ) && - !getPlayersByName().containsKey( playerName.toLowerCase() ) - ) { - - // Submit the sync task to add player. But since this is an - // async thread, we can only return a null. Future requests - // for this player's placeholder will resolve successfully - // and a return value of null is perfectly acceptable. - NewRankPlayerSyncTask syncTask = new NewRankPlayerSyncTask( uid, playerName ); - PrisonTaskSubmitter.runTaskLater( syncTask, 0 ); - } - return results; + RankPlayer results = null; + + // addPlayer can only be rank in the primary thread: + if ( PrisonTaskSubmitter.isPrimaryThread() ) { + results = addPlayerSyncTask( uid, playerName ); + } + else if ( !getPlayersByName().containsKey( playerName ) && + !getPlayersByName().containsKey( playerName.toLowerCase() ) + ) { + + // Submit the sync task to add player. But since this is an + // async thread, we can only return a null. Future requests + // for this player's placeholder will resolve successfully + // and a return value of null is perfectly acceptable. + NewRankPlayerSyncTask syncTask = new NewRankPlayerSyncTask( uid, playerName ); + PrisonTaskSubmitter.runTaskLater( syncTask, 0 ); + } + return results; } protected RankPlayer addPlayerSyncTask( UUID uid, String playerName ) { @@ -458,119 +341,98 @@ protected RankPlayer addPlayerSyncTask( UUID uid, String playerName ) { !getPlayersByName().containsKey( playerName ) && !getPlayersByName().containsKey( playerName.toLowerCase() ) ) { - synchronized( getPlayersByName() ) { - - // recheck to ensure that the player's name is not in the getPlayersByName() - // collection... it could have been added since submitting the sync task: - - if ( !getPlayersByName().containsKey( playerName ) && - !getPlayersByName().containsKey( playerName.toLowerCase() ) ) { - - RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); - - // We need to create a new player data file. - newPlayer = new RankPlayer( uid, playerName ); -// newPlayer.checkName( playerName ); - newPlayer.setDirty( true ); - - // WARNING: Must save the newPlayer object to the playerManager collections - // before calling firstJoin(): - - players.add(newPlayer); - getPlayersByName().put( playerName, newPlayer ); - getPlayersByName().put( playerName.toLowerCase(), newPlayer ); - getPlayersByName().put( uid.toString(), newPlayer ); - - - debugLogPlayerInfo( "addPlayerSyncTask: firstJoin:", playerName, - newPlayer.getUUID().toString(), false ); - - rankPlayerFactory.firstJoin( newPlayer ); - - - boolean joined = newPlayer.getPlayerRankDefault() != null; - String msg = joined ? "joined" : "failed"; - debugLogPlayerInfo( "addPlayerSyncTask: " + msg, playerName, - newPlayer.getUUID().toString(), false ); - - - // the new player is now saved in firstJoin()( - //savePlayer(newPlayer); - - -// try { -// -// } -// catch (IOException e) { -// -// String errorMessage = cannotSaveNewPlayerFile( playerName, newPlayer.filename() ); -// -// Output.get().logError( errorMessage, e); -// } - } - - } + synchronized( getPlayersByName() ) { + + // recheck to ensure that the player's name is not in the getPlayersByName() + // collection... it could have been added since submitting the sync task: + + if ( !getPlayersByName().containsKey( playerName ) && + !getPlayersByName().containsKey( playerName.toLowerCase() ) ) { + + RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); + + // We need to create a new player data file. + newPlayer = new RankPlayer( uid, playerName ); + newPlayer.setDirty( true ); + + // WARNING: Must save the newPlayer object to the playerManager collections + // before calling firstJoin(): + + players.add(newPlayer); + getPlayersByName().put( playerName, newPlayer ); + getPlayersByName().put( playerName.toLowerCase(), newPlayer ); + getPlayersByName().put( uid.toString(), newPlayer ); + + + debugLogPlayerInfo( "addPlayerSyncTask: firstJoin:", playerName, + newPlayer.getUUID().toString(), false ); + + rankPlayerFactory.firstJoin( newPlayer ); + + + boolean joined = newPlayer.getPlayerRankDefault() != null; + String msg = joined ? "joined" : "failed"; + debugLogPlayerInfo( "addPlayerSyncTask: " + msg, playerName, + newPlayer.getUUID().toString(), false ); + + } + } } return newPlayer; } - /* - * Listeners - */ - + @Subscribe public void onPlayerJoin(PlayerJoinEvent event) { - - Player player = event.getPlayer(); - - if ( player != null ) { - debugLogPlayerInfo( "onPlayerJoin:", player.getName(), player.getUUID().toString(), true ); - - // Player is auto added if they do not exist when calling getPlayer so don't try to - // add them a second time. - RankPlayer rPlayer = player.getRankPlayer(); - - if ( rPlayer != null ) { - - rPlayer.doNothing(); - } - } + + Player player = event.getPlayer(); + + if ( player != null ) { + debugLogPlayerInfo( "onPlayerJoin:", player.getName(), player.getUUID().toString(), true ); + + // Player is auto added if they do not exist when calling getPlayer so don't try to + // add them a second time. + RankPlayer rPlayer = player.getRankPlayer(); + + if ( rPlayer != null ) { + + rPlayer.doNothing(); + } + } } public void debugLogPlayerInfo( String eventName, String playerName, String uuid, boolean date ) { - if ( Output.get().isDebug() ) { - - boolean newPlayer = playerName != null ? - !getPlayersByName().containsKey( playerName ) && - !getPlayersByName().containsKey( playerName.toLowerCase() ) : false; - - if ( playerName == null ) { - playerName = "**Error No player name**"; - } - - SimpleDateFormat sdFmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - - String msg = String.format( - "&6%s: &c%s &6%s &d%s uuid=%s", - eventName, - playerName, - date ? sdFmt.format(new Date()) : "", - newPlayer ? "[New Player]" : "", - uuid - ); - - Output.get().logInfo( msg ); - } - + if ( Output.get().isDebug() ) { + + boolean newPlayer = playerName != null ? + !getPlayersByName().containsKey( playerName ) && + !getPlayersByName().containsKey( playerName.toLowerCase() ) : false; + + if ( playerName == null ) { + playerName = "**Error No player name**"; + } + + SimpleDateFormat sdFmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + String msg = String.format( + "&6%s: &c%s &6%s &d%s uuid=%s", + eventName, + playerName, + date ? sdFmt.format(new Date()) : "", + newPlayer ? "[New Player]" : "", + uuid + ); + + Output.get().logInfo( msg ); + } } - public String getPlayerRankName( RankPlayer rankPlayer, String ladderName ) { - StringBuilder sb = new StringBuilder(); + StringBuilder sb = new StringBuilder(); if ( !rankPlayer.getLadderRanks().isEmpty()) { for (Map.Entry entry : rankPlayer.getLadderRanks().entrySet()) { @@ -598,31 +460,31 @@ public String getPlayerRankName( RankPlayer rankPlayer, String ladderName ) { public String getPlayerRankNumber( RankPlayer rankPlayer, String ladderName, PlaceholderAttributeNumberFormat attributeNFormat ) { - StringBuilder sb = new StringBuilder(); - - if ( !rankPlayer.getLadderRanks().isEmpty()) { - for (Map.Entry entry : rankPlayer.getLadderRanks().entrySet()) { - if ( ladderName == null || - ladderName != null && entry.getKey().getName().equalsIgnoreCase( ladderName )) { - - if ( sb.length() > 0 ) { - sb.append(" "); - } - - int rankNumber = rankNumber(entry.getValue().getRank()); - - if ( attributeNFormat != null ) { - - sb.append( attributeNFormat.format( (long) rankNumber ) ); - } - else { - sb.append( Integer.toString( rankNumber ) ); - } - } - } - } - - return (sb.length() == 0 ? "0" : sb.toString()); + StringBuilder sb = new StringBuilder(); + + if ( !rankPlayer.getLadderRanks().isEmpty()) { + for (Map.Entry entry : rankPlayer.getLadderRanks().entrySet()) { + if ( ladderName == null || + ladderName != null && entry.getKey().getName().equalsIgnoreCase( ladderName )) { + + if ( sb.length() > 0 ) { + sb.append(" "); + } + + int rankNumber = rankNumber(entry.getValue().getRank()); + + if ( attributeNFormat != null ) { + + sb.append( attributeNFormat.format( (long) rankNumber ) ); + } + else { + sb.append( Integer.toString( rankNumber ) ); + } + } + } + } + + return (sb.length() == 0 ? "0" : sb.toString()); } /** @@ -634,52 +496,32 @@ public String getPlayerRankNumber( RankPlayer rankPlayer, String ladderName, * @return */ private int rankNumber( Rank value ) { - int results = 0; - if ( value != null ) { - Rank r = value; - while ( r != null ) { - results++; - r = r.getRankPrior(); - } - } + int results = 0; + if ( value != null ) { + Rank r = value; + while ( r != null ) { + results++; + r = r.getRankPrior(); + } + } return results; } public String getPlayerRankTag( RankPlayer rankPlayer, String ladderName ) { - StringBuilder sb = new StringBuilder(); - - if ( !rankPlayer.getLadderRanks().isEmpty()) { - for (Map.Entry entry : rankPlayer.getLadderRanks().entrySet()) { - if ( ladderName == null || - ladderName != null && entry.getKey().getName().equalsIgnoreCase( ladderName )) { - -// if ( sb.length() > 0 ) { -// sb.append(" "); -// } - Rank rank = entry.getValue().getRank(); - -// if ( rank.getLadder() != null && rank.getLadder().isDefault() && -// rank.getRankNext() == null ) { -// PlayerRank prestigeRank = rankPlayer.getPlayerRankPrestiges(); -// -// if ( prestigeRank == null ) { -// RankLadder prestigeLadder = PrisonRanks.getInstance() -// .getLadderManager().getLadderPrestiges(); -// if ( prestigeLadder != null ) { -// rank = prestigeLadder.getLowestRank().orElseGet( null ); -// } -// } -// else { -// rank = prestigeRank.getRank().getRankNext(); -// } -// -// } - - String tag = rank.getTag(); - sb.append( tag == null ? rank.getName() : tag ); - } - } - } + StringBuilder sb = new StringBuilder(); + + if ( !rankPlayer.getLadderRanks().isEmpty()) { + for (Map.Entry entry : rankPlayer.getLadderRanks().entrySet()) { + if ( ladderName == null || + ladderName != null && entry.getKey().getName().equalsIgnoreCase( ladderName )) { + + Rank rank = entry.getValue().getRank(); + + String tag = rank.getTag(); + sb.append( tag == null ? rank.getName() : tag ); + } + } + } if ( sb.length() == 0 && LadderManager.LADDER_PRESTIGES.equals( ladderName ) ) { // Use config setting for no-prestige-value ladder rank: @@ -688,11 +530,11 @@ public String getPlayerRankTag( RankPlayer rankPlayer, String ladderName ) { sb.append( prestigeEmpty ); } - return sb.toString(); + return sb.toString(); } public List getPlayerRanks( RankPlayer rankPlayer ) { - List results = new ArrayList<>(); + List results = new ArrayList<>(); if ( !rankPlayer.getLadderRanks().isEmpty()) { for (Map.Entry entry : rankPlayer.getLadderRanks().entrySet()) { @@ -704,82 +546,80 @@ public List getPlayerRanks( RankPlayer rankPlayer ) { } public List getPlayerNextRanks( RankPlayer rankPlayer ) { - List results = new ArrayList<>(); - - if ( !rankPlayer.getLadderRanks().isEmpty()) { - - RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); - - for ( RankLadder ladder : rankPlayer.getLadderRanks().keySet() ) { - - Rank rank = rankPlayerFactory.getRank( rankPlayer, ladder ).getRank(); - if ( rank != null && rank.getRankNext() != null ) { - Rank nextRank = rank.getRankNext(); - - results.add( nextRank ); - } - } - } - - return results; + List results = new ArrayList<>(); + + if ( !rankPlayer.getLadderRanks().isEmpty()) { + + RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); + + for ( RankLadder ladder : rankPlayer.getLadderRanks().keySet() ) { + + Rank rank = rankPlayerFactory.getRank( rankPlayer, ladder ).getRank(); + if ( rank != null && rank.getRankNext() != null ) { + Rank nextRank = rank.getRankNext(); + + results.add( nextRank ); + } + } + } + + return results; } public String getPlayerNextRankCost( RankPlayer rankPlayer, String ladderName, boolean formatted, PlaceholderAttributeNumberFormat attributeNFormat ) { - StringBuilder sb = new StringBuilder(); - - if ( !rankPlayer.getLadderRanks().isEmpty()) { - DecimalFormat dFmt = Prison.get().getDecimalFormatInt(); - - RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); - - for ( RankLadder ladder : rankPlayer.getLadderRanks().keySet() ) { - - if ( ladderName == null || - ladderName != null && ladder.getName().equalsIgnoreCase( ladderName )) { - - boolean isDefault = ladder.getName().equals( LadderManager.LADDER_DEFAULT ) ; - - PlayerRank pRank = rankPlayerFactory.getRank( rankPlayer, ladder ); - Rank nextRank = pRank.getRank().getRankNext(); - - if ( pRank != null && - ( nextRank != null || nextRank == null && isDefault )) { - - nextRank = getNextPrestigeRank( rankPlayer, isDefault, nextRank ); - - // This calculates the target rank, and takes in to consideration the player's existing rank: - PlayerRank nextPRank = rankPlayer.calculateTargetPlayerRank( nextRank ); -// PlayerRank nextPRank = pRank.getTargetPlayerRankForPlayer( rankPlayer, nextRank ); - - //PlayerRank nextPRank = new PlayerRank( nextRank, pRank.getRankMultiplier() ); - - if ( nextPRank != null ) { - - if ( sb.length() > 0 ) { - sb.append(", "); - } - - double cost = nextPRank.getRankCost(); - - if ( attributeNFormat != null ) { - - sb.append( attributeNFormat.format( cost ) ); - } - else if ( formatted ) { - sb.append( PlaceholdersUtil.formattedMetricSISize( cost )); - } - else { - sb.append( dFmt.format( cost )); - } - } - } - } - } - - } - - return sb.toString(); + StringBuilder sb = new StringBuilder(); + + if ( !rankPlayer.getLadderRanks().isEmpty()) { + DecimalFormat dFmt = Prison.get().getDecimalFormatInt(); + + RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); + + for ( RankLadder ladder : rankPlayer.getLadderRanks().keySet() ) { + + if ( ladderName == null || + ladderName != null && ladder.getName().equalsIgnoreCase( ladderName )) { + + boolean isDefault = ladder.getName().equals( LadderManager.LADDER_DEFAULT ) ; + + PlayerRank pRank = rankPlayerFactory.getRank( rankPlayer, ladder ); + Rank nextRank = pRank.getRank().getRankNext(); + + if ( pRank != null && + ( nextRank != null || nextRank == null && isDefault )) { + + nextRank = getNextPrestigeRank( rankPlayer, isDefault, nextRank ); + + // This calculates the target rank, and takes in to consideration the player's existing rank: + PlayerRank nextPRank = rankPlayer.calculateTargetPlayerRank( nextRank ); + + + if ( nextPRank != null ) { + + if ( sb.length() > 0 ) { + sb.append(", "); + } + + double cost = nextPRank.getRankCost(); + + if ( attributeNFormat != null ) { + + sb.append( attributeNFormat.format( cost ) ); + } + else if ( formatted ) { + sb.append( PlaceholdersUtil.formattedMetricSISize( cost )); + } + else { + sb.append( dFmt.format( cost )); + } + } + } + } + } + + } + + return sb.toString(); } private Rank getNextPrestigeRank( RankPlayer rankPlayer, boolean isDefault, Rank nextRank ) @@ -814,120 +654,109 @@ private Rank getNextPrestigeRank( RankPlayer rankPlayer, boolean isDefault, Rank public String getPlayerNextRankCostPercent( RankPlayer rankPlayer, String ladderName, PlaceholderAttributeNumberFormat attributeNFormat ) { - StringBuilder sb = new StringBuilder(); - - if ( !rankPlayer.getLadderRanks().isEmpty()) { - DecimalFormat dFmt = Prison.get().getDecimalFormat("#,##0.00"); - - RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); - - for ( RankLadder ladder : rankPlayer.getLadderRanks().keySet() ) { - - if ( ladderName == null || - ladderName != null && ladder.getName().equalsIgnoreCase( ladderName )) { - - boolean isDefault = ladder.getName().equals( LadderManager.LADDER_DEFAULT ) ; - - PlayerRank pRank = rankPlayerFactory.getRank( rankPlayer, ladder ); - Rank nextRank = pRank.getRank().getRankNext(); - - if ( pRank != null && - ( nextRank != null || nextRank == null && isDefault ) ) { - - nextRank = getNextPrestigeRank( rankPlayer, isDefault, nextRank ); - - // This calculates the target rank, and takes in to consideration the player's existing rank: - PlayerRank nextPRank = rankPlayer.calculateTargetPlayerRank( nextRank ); -// PlayerRank nextPRank = pRank.getTargetPlayerRankForPlayer( rankPlayer, nextRank ); - -// PlayerRank nextPRank = new PlayerRank( nextRank, pRank.getRankMultiplier() ); - - if ( nextPRank != null ) { - - if ( sb.length() > 0 ) { - sb.append(", "); - } - -// Rank rank = key.getNext(key.getPositionOfRank(entry.getValue())).get(); - double cost = nextPRank.getRankCost(); - double balance = rankPlayer.getBalance( pRank.getRank().getCurrency() ); -// double balance = getPlayerBalance(prisonPlayer,nextRank); - - double percent = (balance < 0 ? 0 : - (cost == 0.0d || balance > cost ? 100.0 : - balance / cost * 100.0 ) - ); - - if ( attributeNFormat != null ) { - - sb.append( attributeNFormat.format( percent ) ); - } - else { - - sb.append( dFmt.format( percent )); - } - } - } - } - } - } - - return sb.toString(); + StringBuilder sb = new StringBuilder(); + + if ( !rankPlayer.getLadderRanks().isEmpty()) { + DecimalFormat dFmt = Prison.get().getDecimalFormat("#,##0.00"); + + RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); + + for ( RankLadder ladder : rankPlayer.getLadderRanks().keySet() ) { + + if ( ladderName == null || + ladderName != null && ladder.getName().equalsIgnoreCase( ladderName )) { + + boolean isDefault = ladder.getName().equals( LadderManager.LADDER_DEFAULT ) ; + + PlayerRank pRank = rankPlayerFactory.getRank( rankPlayer, ladder ); + Rank nextRank = pRank.getRank().getRankNext(); + + if ( pRank != null && + ( nextRank != null || nextRank == null && isDefault ) ) { + + nextRank = getNextPrestigeRank( rankPlayer, isDefault, nextRank ); + + // This calculates the target rank, and takes in to consideration the player's existing rank: + PlayerRank nextPRank = rankPlayer.calculateTargetPlayerRank( nextRank ); + + if ( nextPRank != null ) { + + if ( sb.length() > 0 ) { + sb.append(", "); + } + + double cost = nextPRank.getRankCost(); + double balance = rankPlayer.getBalance( pRank.getRank().getCurrency() ); + + double percent = (balance < 0 ? 0 : + (cost == 0.0d || balance > cost ? 100.0 : + balance / cost * 100.0 ) + ); + + if ( attributeNFormat != null ) { + + sb.append( attributeNFormat.format( percent ) ); + } + else { + + sb.append( dFmt.format( percent )); + } + } + } + } + } + } + + return sb.toString(); } public String getPlayerNextRankCostBar( RankPlayer rankPlayer, String ladderName, PlaceholderAttributeBar attributeBar ) { - StringBuilder sb = new StringBuilder(); - - if ( !rankPlayer.getLadderRanks().isEmpty()) { - -// DecimalFormat dFmt = Prison.get().getDecimalFormat("#,##0.00"); - - RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); - - for ( RankLadder ladder : rankPlayer.getLadderRanks().keySet() ) { - - if ( ladderName == null || - ladderName != null && ladder.getName().equalsIgnoreCase( ladderName )) { - - boolean isDefault = ladder.getName().equals( LadderManager.LADDER_DEFAULT ) ; - - PlayerRank pRank = rankPlayerFactory.getRank( rankPlayer, ladder ); - Rank rank = pRank.getRank(); - Rank nextRank = rank.getRankNext(); - - if ( rank != null && - ( nextRank != null || nextRank == null && isDefault )) { - - nextRank = getNextPrestigeRank( rankPlayer, isDefault, nextRank ); - - // This calculates the target rank, and takes in to consideration the player's existing rank: - PlayerRank nextPRank = rankPlayer.calculateTargetPlayerRank( nextRank ); -// PlayerRank nextPRank = pRank.getTargetPlayerRankForPlayer( rankPlayer, nextRank ); - -// PlayerRank nextPRank = new PlayerRank( nextRank, pRank.getRankMultiplier() ); - - if ( nextPRank != null ) { - - if ( sb.length() > 0 ) { - sb.append(", "); - } - - double cost = nextPRank.getRankCost(); - double balance = rankPlayer.getBalance( rank.getCurrency() ); -// double balance = getPlayerBalance(prisonPlayer,nextRank); - - - sb.append( PlaceholderManagerUtils.getInstance(). - getProgressBar( balance, cost, false, attributeBar )); - } - - } - } - } - } - - return sb.toString(); + StringBuilder sb = new StringBuilder(); + + if ( !rankPlayer.getLadderRanks().isEmpty()) { + + RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); + + for ( RankLadder ladder : rankPlayer.getLadderRanks().keySet() ) { + + if ( ladderName == null || + ladderName != null && ladder.getName().equalsIgnoreCase( ladderName )) { + + boolean isDefault = ladder.getName().equals( LadderManager.LADDER_DEFAULT ) ; + + PlayerRank pRank = rankPlayerFactory.getRank( rankPlayer, ladder ); + Rank rank = pRank.getRank(); + Rank nextRank = rank.getRankNext(); + + if ( rank != null && + ( nextRank != null || nextRank == null && isDefault )) { + + nextRank = getNextPrestigeRank( rankPlayer, isDefault, nextRank ); + + // This calculates the target rank, and takes in to consideration the player's existing rank: + PlayerRank nextPRank = rankPlayer.calculateTargetPlayerRank( nextRank ); + + if ( nextPRank != null ) { + + if ( sb.length() > 0 ) { + sb.append(", "); + } + + double cost = nextPRank.getRankCost(); + double balance = rankPlayer.getBalance( rank.getCurrency() ); + + + sb.append( PlaceholderManagerUtils.getInstance(). + getProgressBar( balance, cost, false, attributeBar )); + } + + } + } + } + } + + return sb.toString(); } /** @@ -944,72 +773,68 @@ public String getPlayerNextRankCostBar( RankPlayer rankPlayer, String ladderName */ public String getPlayerNextRankCostRemaining( RankPlayer rankPlayer, String ladderName, boolean formatted, PlaceholderAttributeNumberFormat attributeNFormat ) { - StringBuilder sb = new StringBuilder(); - - if ( !rankPlayer.getLadderRanks().isEmpty()) { - DecimalFormat dFmt = Prison.get().getDecimalFormat("#,##0.00"); - - RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); - - for ( RankLadder ladder : rankPlayer.getLadderRanks().keySet() ) { - - if ( ladderName == null || - ladderName != null && ladder.getName().equalsIgnoreCase( ladderName )) { - - boolean isDefault = ladder.getName().equals( LadderManager.LADDER_DEFAULT ) ; - - PlayerRank pRank = rankPlayerFactory.getRank( rankPlayer, ladder ); - Rank rank = pRank.getRank(); - Rank nextRank = rank.getRankNext(); - - if ( rank != null && - ( nextRank != null || nextRank == null && isDefault ) ) { - - nextRank = getNextPrestigeRank( rankPlayer, isDefault, nextRank ); - - // This calculates the target rank, and takes in to consideration the player's existing rank: - PlayerRank nextPRank = rankPlayer.calculateTargetPlayerRank( nextRank ); -// PlayerRank nextPRank = pRank.getTargetPlayerRankForPlayer( rankPlayer, nextRank ); - -// PlayerRank nextPRank = new PlayerRank( nextRank, pRank.getRankMultiplier() ); - - if ( nextPRank != null ) { - - if ( sb.length() > 0 ) { - sb.append(", "); - } - - double cost = nextPRank.getRankCost(); - double balance = rankPlayer.getBalance( rank.getCurrency() ); -// double balance = getPlayerBalance(prisonPlayer,nextRank); - - double remaining = cost - balance; - - // Without the following, if the player has more money than what the rank will cost, - // then it would result in a negative amount, which is wrong. - // This is cost remaining... once they are able to afford a rankup, then remaining - // cost will be zero. - if ( remaining < 0 ) { - remaining = 0; - } - - if ( attributeNFormat != null ) { - sb.append( attributeNFormat.format( remaining ) ); - } - - else if ( formatted ) { - sb.append( PlaceholdersUtil.formattedMetricSISize( remaining )); - } - else { - sb.append( dFmt.format( remaining )); - } - } - } - } - } - } - - return sb.toString(); + StringBuilder sb = new StringBuilder(); + + if ( !rankPlayer.getLadderRanks().isEmpty()) { + DecimalFormat dFmt = Prison.get().getDecimalFormat("#,##0.00"); + + RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); + + for ( RankLadder ladder : rankPlayer.getLadderRanks().keySet() ) { + + if ( ladderName == null || + ladderName != null && ladder.getName().equalsIgnoreCase( ladderName )) { + + boolean isDefault = ladder.getName().equals( LadderManager.LADDER_DEFAULT ) ; + + PlayerRank pRank = rankPlayerFactory.getRank( rankPlayer, ladder ); + Rank rank = pRank.getRank(); + Rank nextRank = rank.getRankNext(); + + if ( rank != null && + ( nextRank != null || nextRank == null && isDefault ) ) { + + nextRank = getNextPrestigeRank( rankPlayer, isDefault, nextRank ); + + // This calculates the target rank, and takes in to consideration the player's existing rank: + PlayerRank nextPRank = rankPlayer.calculateTargetPlayerRank( nextRank ); + + if ( nextPRank != null ) { + + if ( sb.length() > 0 ) { + sb.append(", "); + } + + double cost = nextPRank.getRankCost(); + double balance = rankPlayer.getBalance( rank.getCurrency() ); + + double remaining = cost - balance; + + // Without the following, if the player has more money than what the rank will cost, + // then it would result in a negative amount, which is wrong. + // This is cost remaining... once they are able to afford a rankup, then remaining + // cost will be zero. + if ( remaining < 0 ) { + remaining = 0; + } + + if ( attributeNFormat != null ) { + sb.append( attributeNFormat.format( remaining ) ); + } + + else if ( formatted ) { + sb.append( PlaceholdersUtil.formattedMetricSISize( remaining )); + } + else { + sb.append( dFmt.format( remaining )); + } + } + } + } + } + } + + return sb.toString(); } @@ -1039,34 +864,31 @@ public String getPlayerNextRankCostRemainingPercent( RankPlayer rankPlayer, Stri // This calculates the target rank, and takes in to consideration the player's existing rank: PlayerRank nextPRank = rankPlayer.calculateTargetPlayerRank( nextRank ); -// PlayerRank nextPRank = pRank.getTargetPlayerRankForPlayer( rankPlayer, nextRank ); - -// PlayerRank nextPRank = new PlayerRank( nextRank, pRank.getRankMultiplier() ); if ( nextPRank != null ) { - if ( sb.length() > 0 ) { - sb.append(", "); - } - - double cost = nextPRank.getRankCost(); - double balance = rankPlayer.getBalance( rank.getCurrency() ); -// double balance = getPlayerBalance(prisonPlayer,nextRank); - - double remaining = cost - balance; - - // Without the following, if the player has more money than what the rank will cost, - // then it would result in a negative amount, which is wrong. - // This is cost remaining... once they are able to afford a rankup, then remaining - // cost will be zero. - if ( remaining < 0 ) { - remaining = 0; - } - double percent = (remaining < 0 ? 0.0 : - (cost == 0.0d || remaining > cost ? 100.0 : - remaining / cost * 100.0 ) - ); - sb.append( dFmt.format( percent )); + if ( sb.length() > 0 ) { + sb.append(", "); + } + + double cost = nextPRank.getRankCost(); + double balance = rankPlayer.getBalance( rank.getCurrency() ); + // double balance = getPlayerBalance(prisonPlayer,nextRank); + + double remaining = cost - balance; + + // Without the following, if the player has more money than what the rank will cost, + // then it would result in a negative amount, which is wrong. + // This is cost remaining... once they are able to afford a rankup, then remaining + // cost will be zero. + if ( remaining < 0 ) { + remaining = 0; + } + double percent = (remaining < 0 ? 0.0 : + (cost == 0.0d || remaining > cost ? 100.0 : + remaining / cost * 100.0 ) + ); + sb.append( dFmt.format( percent )); } } } @@ -1081,7 +903,6 @@ public String getPlayerNextRankCostRemainingBar( RankPlayer rankPlayer, String l StringBuilder sb = new StringBuilder(); if ( !rankPlayer.getLadderRanks().isEmpty()) { - // DecimalFormat dFmt = Prison.get().getDecimalFormatInt(); RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); @@ -1104,37 +925,28 @@ public String getPlayerNextRankCostRemainingBar( RankPlayer rankPlayer, String l // This calculates the target rank, and takes in to consideration the player's existing rank: PlayerRank nextPRank = rankPlayer.calculateTargetPlayerRank( nextRank ); -// PlayerRank nextPRank = pRank.getTargetPlayerRankForPlayer( rankPlayer, nextRank ); - -// PlayerRank nextPRank = new PlayerRank( nextRank, pRank.getRankMultiplier() ); if ( nextPRank != null ) { - if ( sb.length() > 0 ) { - sb.append(", "); - } - - double cost = nextPRank.getRankCost(); - double balance = rankPlayer.getBalance( rank.getCurrency() ); -// double balance = getPlayerBalance(prisonPlayer,nextRank); - - double remaining = cost - balance; - - // Without the following, if the player has more money than what the rank will cost, - // then it would result in a negative amount, which is wrong. - // This is cost remaining... once they are able to afford a rankup, then remaining - // cost will be zero. - if ( remaining < 0 ) { - remaining = 0; - } - // double percent = (remaining < 0 ? 0.0 : - // (cost == 0.0d || remaining > cost ? 100.0 : - // remaining / cost * 100.0 ) - // ); - // sb.append( dFmt.format( percent )); - - sb.append( PlaceholderManagerUtils.getInstance(). - getProgressBar( remaining, cost, false, attributeBar )); + if ( sb.length() > 0 ) { + sb.append(", "); + } + + double cost = nextPRank.getRankCost(); + double balance = rankPlayer.getBalance( rank.getCurrency() ); + + double remaining = cost - balance; + + // Without the following, if the player has more money than what the rank will cost, + // then it would result in a negative amount, which is wrong. + // This is cost remaining... once they are able to afford a rankup, then remaining + // cost will be zero. + if ( remaining < 0 ) { + remaining = 0; + } + + sb.append( PlaceholderManagerUtils.getInstance(). + getProgressBar( remaining, cost, false, attributeBar )); } } @@ -1160,424 +972,336 @@ public String getPlayerNextRankCostRemainingBar( RankPlayer rankPlayer, String l */ private String getPlayerBalance( RankPlayer rankPlayer, String ladderName, boolean formatted, PlaceholderAttributeNumberFormat attributeNFormat ) { - StringBuilder sb = new StringBuilder(); - -// Player prisonPlayer = PrisonAPI.getPlayer(rankPlayer.getUUID()).orElse(null); -// if( prisonPlayer == null ) { -// -// String errorMessage = cannotLoadPlayerFile( rankPlayer.getUUID().toString() ); -// -// String message = "getPlayerBalance: " + errorMessage; -// -// if ( !getPlayerErrors().contains( message ) ) { -// getPlayerErrors().add( message ); -// Output.get().logError( message ); -// } -// -//// return "0"; -// } - - if ( !rankPlayer.getLadderRanks().isEmpty()) { - DecimalFormat dFmt = Prison.get().getDecimalFormatInt(); - - RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); - - for ( RankLadder ladder : rankPlayer.getLadderRanks().keySet() ) { - - if ( ladderName == null || - ladderName != null && ladder.getName().equalsIgnoreCase( ladderName )) { - - PlayerRank pRank = rankPlayerFactory.getRank( rankPlayer, ladder ); - Rank rank = pRank.getRank(); - if ( rank != null ) { - if ( sb.length() > 0 ) { - sb.append(", "); - } - - double balance = rankPlayer.getBalance( rank.getCurrency() ); -// double balance = getPlayerBalance(prisonPlayer,rank); - - if ( attributeNFormat != null ) { - - sb.append( attributeNFormat.format( balance ) ); - } - - else if ( formatted ) { - sb.append( PlaceholdersUtil.formattedMetricSISize( balance )); - } - else { - sb.append( dFmt.format( balance )); - } - } - } - } - } - - return sb.toString(); + StringBuilder sb = new StringBuilder(); + + if ( !rankPlayer.getLadderRanks().isEmpty()) { + DecimalFormat dFmt = Prison.get().getDecimalFormatInt(); + + RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); + + for ( RankLadder ladder : rankPlayer.getLadderRanks().keySet() ) { + + if ( ladderName == null || + ladderName != null && ladder.getName().equalsIgnoreCase( ladderName )) { + + PlayerRank pRank = rankPlayerFactory.getRank( rankPlayer, ladder ); + Rank rank = pRank.getRank(); + if ( rank != null ) { + if ( sb.length() > 0 ) { + sb.append(", "); + } + + double balance = rankPlayer.getBalance( rank.getCurrency() ); + + if ( attributeNFormat != null ) { + + sb.append( attributeNFormat.format( balance ) ); + } + + else if ( formatted ) { + sb.append( PlaceholdersUtil.formattedMetricSISize( balance )); + } + else { + sb.append( dFmt.format( balance )); + } + } + } + } + } + + return sb.toString(); } private String getPlayerAverageEarningsPerMinute( RankPlayer rankPlayer, String ladderName, boolean formatted, PlaceholderAttributeNumberFormat attributeNFormat ) { - StringBuilder sb = new StringBuilder(); - - - if ( !rankPlayer.getLadderRanks().isEmpty()) { - DecimalFormat dFmt = Prison.get().getDecimalFormatInt(); - - double epm = PlayerCache.getInstance().getPlayerEarningsPerMinute( rankPlayer ); - - if ( attributeNFormat != null ) { - - sb.append( attributeNFormat.format( epm ) ); - } - - else if ( formatted ) { - sb.append( PlaceholdersUtil.formattedMetricSISize( epm )); - } - else { - sb.append( dFmt.format( epm )); - } - - } - - return sb.toString(); + StringBuilder sb = new StringBuilder(); + + + if ( !rankPlayer.getLadderRanks().isEmpty()) { + DecimalFormat dFmt = Prison.get().getDecimalFormatInt(); + + double epm = PlayerCache.getInstance().getPlayerEarningsPerMinute( rankPlayer ); + + if ( attributeNFormat != null ) { + + sb.append( attributeNFormat.format( epm ) ); + } + + else if ( formatted ) { + sb.append( PlaceholdersUtil.formattedMetricSISize( epm )); + } + else { + sb.append( dFmt.format( epm )); + } + + } + + return sb.toString(); } private String getPlayerTokenBalance( RankPlayer rankPlayer, int formatMode, PlaceholderAttributeNumberFormat attributeNFormat ) { - StringBuilder sb = new StringBuilder(); - - DecimalFormat dFmt = Prison.get().getDecimalFormatInt(); - - long tokens = rankPlayer.getPlayerCachePlayerData().getTokens(); - - if ( attributeNFormat != null ) { - - sb.append( attributeNFormat.format( tokens ) ); - } - - else { - switch ( formatMode ) - { - case 1: { - sb.append( dFmt.format( tokens )); - - break; - } - case 2: { - sb.append( PlaceholdersUtil.formattedMetricSISize( tokens )); - - break; - } - case 3: { - sb.append( PlaceholdersUtil.formattedKmbtSISize( tokens, dFmt, " " )); - - break; + StringBuilder sb = new StringBuilder(); + + DecimalFormat dFmt = Prison.get().getDecimalFormatInt(); + + long tokens = rankPlayer.getPlayerCachePlayerData().getTokens(); + + if ( attributeNFormat != null ) { + + sb.append( attributeNFormat.format( tokens ) ); + } + + else { + switch ( formatMode ) + { + case 1: { + sb.append( dFmt.format( tokens )); + + break; + } + case 2: { + sb.append( PlaceholdersUtil.formattedMetricSISize( tokens )); + + break; + } + case 3: { + sb.append( PlaceholdersUtil.formattedKmbtSISize( tokens, dFmt, " " )); + + break; + } + default: + sb.append( Long.toString( tokens )); } - default: - sb.append( Long.toString( tokens )); - } - } - -// if ( formatted ) { -// sb.append( PlaceholdersUtil.formattedMetricSISize( tokens )); -// } -// else { -// sb.append( dFmt.format( tokens )); -// } - - return sb.toString(); + } + + return sb.toString(); } private String getPlayerTokenAverageEarningsPerMinute( RankPlayer rankPlayer, boolean formatted, PlaceholderAttributeNumberFormat attributeNFormat ) { - StringBuilder sb = new StringBuilder(); - - - if ( !rankPlayer.getLadderRanks().isEmpty()) { - DecimalFormat dFmt = Prison.get().getDecimalFormatInt(); - - - double tpm = rankPlayer.getPlayerCachePlayerData().getAverageTokensPerMinute(); - - if ( attributeNFormat != null ) { - - sb.append( attributeNFormat.format( tpm ) ); - } - - else if ( formatted ) { - sb.append( PlaceholdersUtil.formattedMetricSISize( tpm )); - } - else { - sb.append( dFmt.format( tpm )); - } - - } - - return sb.toString(); + StringBuilder sb = new StringBuilder(); + + + if ( !rankPlayer.getLadderRanks().isEmpty()) { + DecimalFormat dFmt = Prison.get().getDecimalFormatInt(); + + + double tpm = rankPlayer.getPlayerCachePlayerData().getAverageTokensPerMinute(); + + if ( attributeNFormat != null ) { + + sb.append( attributeNFormat.format( tpm ) ); + } + + else if ( formatted ) { + sb.append( PlaceholdersUtil.formattedMetricSISize( tpm )); + } + else { + sb.append( dFmt.format( tpm )); + } + + } + + return sb.toString(); } - -// /** -// *

This gets the player's balance, and if the rank is provided, it will check to -// * see if there is a custom currency that needs to be used for that rank. If there -// * is a custom currency, then it will check the balance for that player using that -// * currency. -// *

-// * -// * @param player -// * @param rank -// * @return -// */ -// public double getPlayerBalance(Player player, Rank rank) { -// double playerBalance = 0; -// -// if ( player != null ) { -// -// if ( rank != null && rank.getCurrency() != null ) { -// EconomyCurrencyIntegration currencyEcon = PrisonAPI.getIntegrationManager() -// .getEconomyForCurrency( rank.getCurrency() ); -// if ( currencyEcon != null ) { -// playerBalance = currencyEcon.getBalance( player, rank.getCurrency() ); -// } else { -// -// String errorMessage = cannotLoadEconomyCurrency( player.getName(), rank.getCurrency() ); -// -// if ( !getPlayerErrors().contains( errorMessage ) ) { -// getPlayerErrors().add( errorMessage ); -// Output.get().logError( errorMessage ); -// } -// -// } -// -// } else { -// -// EconomyIntegration economy = PrisonAPI.getIntegrationManager().getEconomy(); -// -// if ( economy != null ) { -// playerBalance = economy.getBalance( player ); -// } else { -// -// String errorMessage = cannotLoadEconomy( player.getName() ); -// -// if ( !getPlayerErrors().contains( errorMessage ) ) { -// -// getPlayerErrors().add( errorMessage ); -// Output.get().logError( errorMessage ); -// } -// -// } -// } -// } -// -// return playerBalance; -// } - public String getPlayerNextRankName( RankPlayer rankPlayer, String ladderName ) { - StringBuilder sb = new StringBuilder(); - - if ( !rankPlayer.getLadderRanks().isEmpty()) { - - RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); - - for ( RankLadder ladder : rankPlayer.getLadderRanks().keySet() ) { - - if ( ladderName == null || - ladderName != null && ladder.getName().equalsIgnoreCase( ladderName )) { - - PlayerRank pRank = rankPlayerFactory.getRank( rankPlayer, ladder ); - Rank rank = pRank.getRank(); - - if ( rank != null && rank.getRankNext() != null ) { - Rank nextRank = rank.getRankNext(); - - if ( sb.length() > 0 ) { - sb.append(" "); - } - sb.append( nextRank.getName( )); - } - } - } - } - - return sb.toString(); + StringBuilder sb = new StringBuilder(); + + if ( !rankPlayer.getLadderRanks().isEmpty()) { + + RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); + + for ( RankLadder ladder : rankPlayer.getLadderRanks().keySet() ) { + + if ( ladderName == null || + ladderName != null && ladder.getName().equalsIgnoreCase( ladderName )) { + + PlayerRank pRank = rankPlayerFactory.getRank( rankPlayer, ladder ); + Rank rank = pRank.getRank(); + + if ( rank != null && rank.getRankNext() != null ) { + Rank nextRank = rank.getRankNext(); + + if ( sb.length() > 0 ) { + sb.append(" "); + } + sb.append( nextRank.getName( )); + } + } + } + } + + return sb.toString(); } public String getPlayerNextLinkedRankTag( RankPlayer rankPlayer, String ladderName ) { - StringBuilder sb = new StringBuilder(); - - // Must always have a default rank: - PlayerRank pRankDefault = rankPlayer.getPlayerRankDefault(); - - // Prestiges ladder may not be enabled, or this may be null because they have not yet prestiged: - PlayerRank pRankPrestiges = rankPlayer.getPlayerRankPrestiges(); - - if ( ladderName == null || ladderName.equalsIgnoreCase( LadderManager.LADDER_PRESTIGES ) ) { - - - // If default rank is the last rank, or at the last prestiges rank, - // then get next prestige rank for player: - if ( pRankDefault.getRank().getRankNext() == null ) { - - // If the player does not have a prestiges rank, then get the first one: - if ( pRankPrestiges == null && PrisonRanks.getInstance().getPrestigesLadder() != null ) { - - Rank firstPrestigeRank = PrisonRanks.getInstance().getPrestigesLadder().getLowestRank().orElse(null); - if ( firstPrestigeRank != null ) { - sb.append( firstPrestigeRank.getTag() ); - } - } - // Else if player has a prestige rank, and there is a next prestige rank, get it's tag: - else if ( pRankPrestiges != null && pRankPrestiges.getRank().getRankNext() != null ) { - sb.append( pRankPrestiges.getRank().getRankNext().getTag() ); - - } - - // else, if player has a prestige rank, and it's the last one, then just get that tag: - else if ( pRankPrestiges != null ) { - sb.append( pRankPrestiges.getRank().getTag() ); - - } - - } - // else just get current prestige rank for player: - else if ( pRankPrestiges != null ) { - - sb.append( pRankPrestiges.getRank().getTag() ); - } - } - if ( ladderName == null || ladderName.equalsIgnoreCase( LadderManager.LADDER_DEFAULT ) ) { - - boolean showFirstRank = false; - boolean showNextRank = true; - - - // If at last default rank, then get the default ladder's first rank's tag or just show current tag: - if ( pRankDefault.getRank().getRankNext() == null ) { - - // Since the current default rank is the last, cannot show next default rank: - showNextRank = false; - - Rank firstPrestigeRank = PrisonRanks.getInstance().getPrestigesLadder().getLowestRank().orElse(null); - - // If firstPrestigeRank is null, then prestiges is not enabled, so cannot show first rank: - if ( firstPrestigeRank == null ) { - showFirstRank = false; -// showNextRank = false; - } - - // If current presetiges is null, then use the first prestiges rank: - else if ( pRankPrestiges == null ) { - showFirstRank = true; -// showNextRank = false; - - } - else if ( pRankPrestiges.getRank().getRankNext() == null ) { - // At the last presetiges rank... so do not reset the default ranks: - showFirstRank = false; - } - - else { - // Presetige is possible, so show first default rank: - showFirstRank = true; - - } - - } - - - if ( !showFirstRank && !showNextRank ) { - // Show current rank: - - sb.append( pRankDefault.getRank().getTag() ); - } - else if ( showFirstRank ) { - - Rank firstDefaultRank = PrisonRanks.getInstance().getDefaultLadder().getLowestRank().orElse(null); - sb.append( firstDefaultRank.getTag() ); - } - else { - // Show next rank: - - // Not at last default rank, so get next rank tag: - sb.append( pRankDefault.getRank().getRankNext().getTag() ); - } - - } - - return sb.toString(); + StringBuilder sb = new StringBuilder(); + + // Must always have a default rank: + PlayerRank pRankDefault = rankPlayer.getPlayerRankDefault(); + + // Prestiges ladder may not be enabled, or this may be null because they have not yet prestiged: + PlayerRank pRankPrestiges = rankPlayer.getPlayerRankPrestiges(); + + if ( ladderName == null || ladderName.equalsIgnoreCase( LadderManager.LADDER_PRESTIGES ) ) { + + + // If default rank is the last rank, or at the last prestiges rank, + // then get next prestige rank for player: + if ( pRankDefault.getRank().getRankNext() == null ) { + + // If the player does not have a prestiges rank, then get the first one: + if ( pRankPrestiges == null && PrisonRanks.getInstance().getPrestigesLadder() != null ) { + + Rank firstPrestigeRank = PrisonRanks.getInstance().getPrestigesLadder().getLowestRank().orElse(null); + if ( firstPrestigeRank != null ) { + sb.append( firstPrestigeRank.getTag() ); + } + } + // Else if player has a prestige rank, and there is a next prestige rank, get it's tag: + else if ( pRankPrestiges != null && pRankPrestiges.getRank().getRankNext() != null ) { + sb.append( pRankPrestiges.getRank().getRankNext().getTag() ); + + } + + // else, if player has a prestige rank, and it's the last one, then just get that tag: + else if ( pRankPrestiges != null ) { + sb.append( pRankPrestiges.getRank().getTag() ); + + } + + } + // else just get current prestige rank for player: + else if ( pRankPrestiges != null ) { + + sb.append( pRankPrestiges.getRank().getTag() ); + } + } + if ( ladderName == null || ladderName.equalsIgnoreCase( LadderManager.LADDER_DEFAULT ) ) { + + boolean showFirstRank = false; + boolean showNextRank = true; + + + // If at last default rank, then get the default ladder's first rank's tag or just show current tag: + if ( pRankDefault.getRank().getRankNext() == null ) { + + // Since the current default rank is the last, cannot show next default rank: + showNextRank = false; + + Rank firstPrestigeRank = PrisonRanks.getInstance().getPrestigesLadder().getLowestRank().orElse(null); + + // If firstPrestigeRank is null, then prestiges is not enabled, so cannot show first rank: + if ( firstPrestigeRank == null ) { + showFirstRank = false; + } + + // If current presetiges is null, then use the first prestiges rank: + else if ( pRankPrestiges == null ) { + showFirstRank = true; + + } + else if ( pRankPrestiges.getRank().getRankNext() == null ) { + // At the last presetiges rank... so do not reset the default ranks: + showFirstRank = false; + } + + else { + // Presetige is possible, so show first default rank: + showFirstRank = true; + + } + + } + + + if ( !showFirstRank && !showNextRank ) { + // Show current rank: + + sb.append( pRankDefault.getRank().getTag() ); + } + else if ( showFirstRank ) { + + Rank firstDefaultRank = PrisonRanks.getInstance().getDefaultLadder().getLowestRank().orElse(null); + sb.append( firstDefaultRank.getTag() ); + } + else { + // Show next rank: + + // Not at last default rank, so get next rank tag: + sb.append( pRankDefault.getRank().getRankNext().getTag() ); + } + + } + + return sb.toString(); } public String getPlayerNextRankTag( RankPlayer rankPlayer, String ladderName ) { - StringBuilder sb = new StringBuilder(); - -// boolean hasDefault = false; -// boolean hasPrestige = false; - - if ( !rankPlayer.getLadderRanks().isEmpty()) { - - RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); - - for ( RankLadder ladder : rankPlayer.getLadderRanks().keySet() ) { - - if ( ladderName == null || - ladderName != null && ladder.getName().equalsIgnoreCase( ladderName )) { - - PlayerRank pRank = rankPlayerFactory.getRank( rankPlayer, ladder ); - Rank rank = pRank.getRank(); - - if ( rank.getLadder() != null && rank.getLadder().isDefault() && - rank.getRankNext() == null ) { - PlayerRank prestigeRank = rankPlayer.getPlayerRankPrestiges(); - - if ( prestigeRank == null ) { - RankLadder prestigeLadder = PrisonRanks.getInstance() - .getLadderManager().getLadderPrestiges(); - if ( prestigeLadder != null ) { - - // Player does not have any prestige rank, so use the lowest prestige rank: - Rank nextRank = prestigeLadder.getLowestRank().orElseGet( null ); - sb.append( nextRank.getTag() ); - continue; - } - } - else { - // Get current prestige rank - rank = prestigeRank.getRank(); - } - - } - - if ( rank != null && rank.getRankNext() != null ) { - Rank nextRank = rank.getRankNext(); - -// if ( sb.length() > 0 ) { -// sb.append(", "); -// } - - sb.append( nextRank.getTag() ); - } - } - } - } - - - // NOTE: Only for the last rank on the default ladder, use the text value - // from the language file to display in the place of the empty tag. - // The idea is that if prestiges is enabled, then this is a way to - // indicate the player could prestige as the next step. - if ( sb.length() == 0 && LadderManager.LADDER_DEFAULT.equalsIgnoreCase( ladderName ) ) { - String replacementText = lastRankMessageForDefaultLadder(); - if ( replacementText != null && !replacementText.trim().isEmpty() ) { - - sb.append( replacementText ); - } - } - - return sb.toString(); + StringBuilder sb = new StringBuilder(); + + if ( !rankPlayer.getLadderRanks().isEmpty()) { + + RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); + + for ( RankLadder ladder : rankPlayer.getLadderRanks().keySet() ) { + + if ( ladderName == null || + ladderName != null && ladder.getName().equalsIgnoreCase( ladderName )) { + + PlayerRank pRank = rankPlayerFactory.getRank( rankPlayer, ladder ); + Rank rank = pRank.getRank(); + + if ( rank.getLadder() != null && rank.getLadder().isDefault() && + rank.getRankNext() == null ) { + PlayerRank prestigeRank = rankPlayer.getPlayerRankPrestiges(); + + if ( prestigeRank == null ) { + RankLadder prestigeLadder = PrisonRanks.getInstance() + .getLadderManager().getLadderPrestiges(); + if ( prestigeLadder != null ) { + + // Player does not have any prestige rank, so use the lowest prestige rank: + Rank nextRank = prestigeLadder.getLowestRank().orElseGet( null ); + sb.append( nextRank.getTag() ); + continue; + } + } + else { + // Get current prestige rank + rank = prestigeRank.getRank(); + } + + } + + if ( rank != null && rank.getRankNext() != null ) { + Rank nextRank = rank.getRankNext(); + + sb.append( nextRank.getTag() ); + } + } + } + } + + + // NOTE: Only for the last rank on the default ladder, use the text value + // from the language file to display in the place of the empty tag. + // The idea is that if prestiges is enabled, then this is a way to + // indicate the player could prestige as the next step. + if ( sb.length() == 0 && LadderManager.LADDER_DEFAULT.equalsIgnoreCase( ladderName ) ) { + String replacementText = lastRankMessageForDefaultLadder(); + if ( replacementText != null && !replacementText.trim().isEmpty() ) { + + sb.append( replacementText ); + } + } + + return sb.toString(); } @@ -1611,7 +1335,7 @@ private String getPlayerSellallMultiplier( RankPlayer rankPlayer, PlaceholderAtt public String getTranslatePlayerPlaceHolder( PlaceholderIdentifier identifier ) { - Player player = identifier.getPlayer(); + Player player = identifier.getPlayer(); PlayerManager pm = PrisonRanks.getInstance().getPlayerManager(); RankPlayer rankPlayer = null; @@ -1643,9 +1367,6 @@ public String getTranslatePlayerPlaceHolder( PlaceholderIdentifier identifier ) PlaceholderAttributeNumberFormat attributeNFormat = identifier.getAttributeNFormat(); PlaceholderAttributeText attributeText = identifier.getAttributeText(); -// int sequence = identifier.getSequence(); - - PrisonPlaceHolders placeHolder = placeHolderKey.getPlaceholder(); @@ -2109,7 +1830,6 @@ public String getTranslatePlayerPlaceHolder( PlaceholderIdentifier identifier ) // results = applySecondaryPlaceholders( rankPlayer, results ); - if ( attributeText != null && results != null ) { results = attributeText.format( results ); @@ -2214,83 +1934,68 @@ private String applySecondaryPlaceholdersCheck( String placeholder, String value @Override public List getTranslatedPlaceHolderKeys() { - if ( translatedPlaceHolderKeys == null ) { - translatedPlaceHolderKeys = new ArrayList<>(); - - // This generates all of the placeholders for the player ranks: - List placeHolders = PrisonPlaceHolders.getTypes( PlaceholderFlags.PLAYER ); - for ( PrisonPlaceHolders ph : placeHolders ) { - PlaceHolderKey placeholder = new PlaceHolderKey(ph.name(), ph ); - if ( ph.getAlias() != null ) { - String aliasName = ph.getAlias().name(); - placeholder.setAliasName( aliasName ); - } - - translatedPlaceHolderKeys.add( placeholder ); - - // Getting too many placeholders... add back the extended prefix when looking up: - -// // Now generate a new key based upon the first key, but without the prison_ prefix: -// String key2 = ph.name().replace( -// IntegrationManager.PRISON_PLACEHOLDER_PREFIX_EXTENDED, "" ); -// PlaceHolderKey placeholder2 = new PlaceHolderKey(key2, ph, false ); -// translatedPlaceHolderKeys.add( placeholder2 ); - } - - - // This generates all of the placeholders for the ladders: - placeHolders = PrisonPlaceHolders.getTypes( PlaceholderFlags.LADDERS ); - - List ladders = PrisonRanks.getInstance().getLadderManager().getLadders(); - for ( RankLadder ladder : ladders ) { - for ( PrisonPlaceHolders ph : placeHolders ) { - - if ( ph.hasFlag( PlaceholderFlags.ONLY_DEFAULT_OR_PRESTIGES ) && - !ladder.getName().equalsIgnoreCase( LadderManager.LADDER_DEFAULT ) && - !ladder.getName().equalsIgnoreCase( LadderManager.LADDER_PRESTIGES ) - ) { - // Placeholder is invalid for ladders that are not default or prestiges, so skip: - continue; - } - - String key = ph.name().replace( - PlaceholderManager.PRISON_PLACEHOLDER_LADDERNAME_SUFFIX, "_" + ladder.getName() ). - toLowerCase(); - - PlaceHolderKey placeholder = new PlaceHolderKey(key, ph, ladder.getName() ); - if ( ph.getAlias() != null ) { - String aliasName = ph.getAlias().name().replace( - PlaceholderManager.PRISON_PLACEHOLDER_LADDERNAME_SUFFIX, "_" + ladder.getName() ). - toLowerCase(); - placeholder.setAliasName( aliasName ); - } - translatedPlaceHolderKeys.add( placeholder ); - - // Getting too many placeholders... add back the extended prefix when looking up: - -// // Now generate a new key based upon the first key, but without the prison_ prefix: -// String key2 = key.replace( -// IntegrationManager.PRISON_PLACEHOLDER_PREFIX_EXTENDED, "" ); -// PlaceHolderKey placeholder2 = new PlaceHolderKey(key2, ph, ladder.name, false ); -// translatedPlaceHolderKeys.add( placeholder2 ); - - } - - } - - } - - return translatedPlaceHolderKeys; + if ( translatedPlaceHolderKeys == null ) { + translatedPlaceHolderKeys = new ArrayList<>(); + + // This generates all of the placeholders for the player ranks: + List placeHolders = PrisonPlaceHolders.getTypes( PlaceholderFlags.PLAYER ); + for ( PrisonPlaceHolders ph : placeHolders ) { + PlaceHolderKey placeholder = new PlaceHolderKey(ph.name(), ph ); + if ( ph.getAlias() != null ) { + String aliasName = ph.getAlias().name(); + placeholder.setAliasName( aliasName ); + } + + translatedPlaceHolderKeys.add( placeholder ); + + } + + + // This generates all of the placeholders for the ladders: + placeHolders = PrisonPlaceHolders.getTypes( PlaceholderFlags.LADDERS ); + + List ladders = PrisonRanks.getInstance().getLadderManager().getLadders(); + for ( RankLadder ladder : ladders ) { + for ( PrisonPlaceHolders ph : placeHolders ) { + + if ( ph.hasFlag( PlaceholderFlags.ONLY_DEFAULT_OR_PRESTIGES ) && + !ladder.getName().equalsIgnoreCase( LadderManager.LADDER_DEFAULT ) && + !ladder.getName().equalsIgnoreCase( LadderManager.LADDER_PRESTIGES ) + ) { + // Placeholder is invalid for ladders that are not default or prestiges, so skip: + continue; + } + + String key = ph.name().replace( + PlaceholderManager.PRISON_PLACEHOLDER_LADDERNAME_SUFFIX, "_" + ladder.getName() ). + toLowerCase(); + + PlaceHolderKey placeholder = new PlaceHolderKey(key, ph, ladder.getName() ); + if ( ph.getAlias() != null ) { + String aliasName = ph.getAlias().name().replace( + PlaceholderManager.PRISON_PLACEHOLDER_LADDERNAME_SUFFIX, "_" + ladder.getName() ). + toLowerCase(); + placeholder.setAliasName( aliasName ); + } + translatedPlaceHolderKeys.add( placeholder ); + + } + + } + + } + + return translatedPlaceHolderKeys; } @Override public void reloadPlaceholders() { - // clear the class variable so they will regenerate: - translatedPlaceHolderKeys = null; - - // Regenerate the translated placeholders: - getTranslatedPlaceHolderKeys(); + // clear the class variable so they will regenerate: + translatedPlaceHolderKeys = null; + + // Regenerate the translated placeholders: + getTranslatedPlaceHolderKeys(); } public void unloadAllPlayers() { diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManagerMessages.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManagerMessages.java index 03a075179..88cec16e5 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManagerMessages.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManagerMessages.java @@ -87,7 +87,4 @@ protected String lastRankMessageForDefaultLadder() { .localize(); } - - - } 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 8d492f11b..8bc53ba50 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 @@ -68,10 +68,6 @@ public class RankManager implements ManagerPlaceholders { - /* - * Fields & Constants - */ - private Collection collection; private List loadedRanks; @@ -88,62 +84,55 @@ public class RankManager private transient boolean enabled; public enum RanksByLadderOptions { - playersOnly("players"), - allRanks("all"), - full; - - - private final String altName; - - private RanksByLadderOptions() { - this.altName = null; - } - - private RanksByLadderOptions( String altName ) { - this.altName = altName; - } - - public static RanksByLadderOptions fromString( String value ) { - RanksByLadderOptions results = null; - - for ( RanksByLadderOptions opt : values() ) { - if ( opt.name().equalsIgnoreCase( value ) || - opt.getAltName() != null && opt.getAltName().equalsIgnoreCase( value )) { - results = opt; - break; + playersOnly("players"), + allRanks("all"), + full; + + + private final String altName; + + private RanksByLadderOptions() { + this.altName = null; + } + + private RanksByLadderOptions( String altName ) { + this.altName = altName; + } + + public static RanksByLadderOptions fromString( String value ) { + RanksByLadderOptions results = null; + + for ( RanksByLadderOptions opt : values() ) { + if ( opt.name().equalsIgnoreCase( value ) || + opt.getAltName() != null && opt.getAltName().equalsIgnoreCase( value )) { + results = opt; + break; + } } - } - - return results; - } + + return results; + } public String getAltName() { return altName; } } - /* - * Constructor - */ - public RankManager() { - this.collection = null; - - this.loadedRanks = new ArrayList<>(); - this.ranksByName = new TreeMap<>(); - this.ranksById = new TreeMap<>(); - - this.enabled = false; + this.collection = null; + + this.loadedRanks = new ArrayList<>(); + this.ranksByName = new TreeMap<>(); + this.ranksById = new TreeMap<>(); + + this.enabled = false; } - /** - * Instantiate this {@link RankManager}. - */ public RankManager(Collection collection) { - this(); - - this.enabled = true; + this(); + + this.enabled = true; this.collection = collection; @@ -156,48 +145,48 @@ public boolean isEnabled() { private void addRank( Rank rank ) { - if ( rank != null ) { - getLoadedRanks().add( rank ); - String rankName = rank.getName(); - getRanksByName().put( rankName.toLowerCase(), rank ); - - if ( rank.getId() != -1 ) { - getRanksById().put( rank.getId(), rank ); - } - - // Do not have to reset position number since the new rank is - // added to the end of the ladder's rank List, and therefore - // no other rank is impacted. - } + if ( rank != null ) { + getLoadedRanks().add( rank ); + String rankName = rank.getName(); + getRanksByName().put( rankName.toLowerCase(), rank ); + + if ( rank.getId() != -1 ) { + getRanksById().put( rank.getId(), rank ); + } + + // Do not have to reset position number since the new rank is + // added to the end of the ladder's rank List, and therefore + // no other rank is impacted. + } } private void removeRankFromCollections( Rank rank ) { - if ( rank != null ) { - getLoadedRanks().remove( rank ); - getRanksByName().remove( rank.getName().toLowerCase() ); - - if ( rank.getId() != -1 && getRanksById().containsKey( rank.getId() ) ) { - - getRanksById().remove( rank.getId() ); - } - - // Since the removal of a rank could shift the position of - // more than one rank, then all positions should be reset. - - resetRankPositions( rank ); - } + if ( rank != null ) { + getLoadedRanks().remove( rank ); + getRanksByName().remove( rank.getName().toLowerCase() ); + + if ( rank.getId() != -1 && getRanksById().containsKey( rank.getId() ) ) { + + getRanksById().remove( rank.getId() ); + } + + // Since the removal of a rank could shift the position of + // more than one rank, then all positions should be reset. + + resetRankPositions( rank ); + } } private void resetRankPositions( Rank rank ) { - if ( rank != null && rank.getLadder() != null ) { - - for ( Rank r : rank.getLadder().getRanks() ) { - r.resetPosition(); - } - } + if ( rank != null && rank.getLadder() != null ) { + + for ( Rank r : rank.getLadder().getRanks() ) { + r.resetPosition(); + } + } } @@ -214,7 +203,6 @@ public void loadRank(String rankFile) throws IOException { RankFactory rankFactory = new RankFactory(); addRank( rankFactory.createRank( document ) ); -// loadedRanks.add(new Rank(document)); } /** @@ -230,19 +218,17 @@ public void loadRanks() throws IOException { for ( Document rankDocument : ranks ) { - Rank rank = rankFactory.createRank( rankDocument ); - addRank( rank ); - - // If old file exists, then set dirty so it can be saved and update the file name: - checkIfOldFileExists( rank ); - - if ( rank.isDirty() ) { - saveRank(rank); - } + Rank rank = rankFactory.createRank( rankDocument ); + addRank( rank ); + + // If old file exists, then set dirty so it can be saved and update the file name: + checkIfOldFileExists( rank ); + + if ( rank.isDirty() ) { + saveRank(rank); + } } -// ranks.forEach(document -> addRank(new Rank(document))); -// ranks.forEach(document -> loadedRanks.add(new Rank(document))); } @@ -253,9 +239,9 @@ public void loadRanks() throws IOException { * @param ladder */ private void checkIfOldFileExists(Rank rank) { - if ( collection.exists( rank.filenameOld() )) { - rank.setDirty( true ); - } + if ( collection.exists( rank.filenameOld() )) { + rank.setDirty( true ); + } } /** @@ -266,9 +252,9 @@ private void checkIfOldFileExists(Rank rank) { */ public void saveRank(Rank rank, String saveFileNew, String saveFileOld ) { - RankFactory rankFactory = new RankFactory(); - - collection.save(saveFileNew, rankFactory.toDocument( rank ), saveFileOld, "Ranks" ); + RankFactory rankFactory = new RankFactory(); + + collection.save(saveFileNew, rankFactory.toDocument( rank ), saveFileOld, "Ranks" ); } /** @@ -304,16 +290,12 @@ public void saveRanks() { public Optional createRank(String name, String tag, double cost) { // Set the default values... - // rank id is no longer used, so use -1: + // rank id is no longer used, so use -1: Rank newRank = new Rank( -1, name, tag, cost ); -// Rank newRank = new Rank( getNextAvailableId(), name, tag, cost ); // ... add it to the list... addRank(newRank); -// // Reset the rank relationships: -// connectRanks(); - // ...and return it. return Optional.of(newRank); } @@ -327,32 +309,15 @@ public Optional createRank(String name, String tag, double cost) { @SuppressWarnings("unused") private int getNextAvailableId() { - int current = -1; - - for (Rank rank : loadedRanks) { + int current = -1; + + for (Rank rank : loadedRanks) { if ( rank.getId() != -1 && rank.getId() > current ) { current = rank.getId(); } } - - return current + 1; - -// current = (getRanksById().size() == 0 ? -// -1 : getRanksById().lastKey().intValue()); -// -// return current + 1; - -// // Set the highest to -1 for now, since we'll add one at the end -// int highest = -1; -// -// // If anything's higher, it's now the highest... -// for (Rank rank : loadedRanks) { -// if (highest < rank.id) { -// highest = rank.id; -// } -// } -// -// return highest + 1; + + return current + 1; } /** @@ -378,20 +343,11 @@ public Optional getRankOptional(String name) { * @return */ public Rank getRank(String name) { - return name == null || !isEnabled() ? - null : - getRanksByName().get( name.toLowerCase() ); + return name == null || !isEnabled() ? + null : + getRanksByName().get( name.toLowerCase() ); } - -// Not used anywhere... -// /** -// * Returns the first rank that has an escaped name that has the & replaced with -. -// */ -// public Rank getRankEscaped(String name) { -// return loadedRanks.stream().filter(rank -> -// rank.getName().replace( "&", "-" ).equals(name)).findFirst().orElse( null ); -// } /** * Removes the provided rank. This will go through the process of removing the rank from the loaded @@ -405,108 +361,86 @@ public Rank getRank(String name) { public boolean removeRank(Rank rank) { // ... remove it from each user, bumping them down to the next lowest rank... - final Rank newRank = ( rank.getRankPrior() != null ? - rank.getRankPrior() : - rank.getRankNext() ); - if ( newRank == null ) { - Localizable localManagerLog = PrisonRanks.getInstance().getRanksMessages() - .getLocalizable( "ranks_rankManager__remove_rank_warning" ); - - Output.get().logError( localManagerLog.localize() ); - } - - - boolean success = true; - - RankLadder ladder = rank.getLadder(); + final Rank newRank = ( rank.getRankPrior() != null ? + rank.getRankPrior() : + rank.getRankNext() ); + if ( newRank == null ) { + Localizable localManagerLog = PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( "ranks_rankManager__remove_rank_warning" ); + + Output.get().logError( localManagerLog.localize() ); + } + + + boolean success = true; + + RankLadder ladder = rank.getLadder(); // for (RankLadder ladder : PrisonRanks.getInstance().getLadderManager() .getLadder( rank )) { - RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); + RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); // Move each player in this ladder to the new rank PrisonRanks.getInstance().getPlayerManager().getPlayers().forEach(rankPlayer -> { - PlayerRank pRank = rankPlayerFactory.getRank( rankPlayer, ladder ); - if ( pRank != null && pRank.getRank() != null ) { - - Rank curRank = pRank.getRank(); - if ( curRank != null && rank.equals( curRank ) ) { - rankPlayer.removeRank(curRank); - if ( newRank != null ) { - rankPlayer.addRank(newRank); - } - - rankPlayer.setDirty( true ); - - PrisonRanks.getInstance().getPlayerManager().savePlayer(rankPlayer); - - -// try { -// } catch (IOException e) { -// Localizable localManagerLog = PrisonRanks.getInstance().getRanksMessages() -// .getLocalizable( "ranks_rankManager__cannot_save_player_file" ); -// -// Output.get().logError( localManagerLog.localize() ); -// } - - Localizable localManagerLog = PrisonRanks.getInstance().getRanksMessages() - .getLocalizable( "ranks_rankManager__cannot_save_player_file" ) - .withReplacements( - rankPlayer.getName(), - newRank.getName() ); - PrisonAPI.debug( localManagerLog.localize() ); - } - } + PlayerRank pRank = rankPlayerFactory.getRank( rankPlayer, ladder ); + if ( pRank != null && pRank.getRank() != null ) { + + Rank curRank = pRank.getRank(); + if ( curRank != null && rank.equals( curRank ) ) { + rankPlayer.removeRank(curRank); + if ( newRank != null ) { + rankPlayer.addRank(newRank); + } + + rankPlayer.setDirty( true ); + + PrisonRanks.getInstance().getPlayerManager().savePlayer(rankPlayer); + + Localizable localManagerLog = PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( "ranks_rankManager__cannot_save_player_file" ) + .withReplacements( + rankPlayer.getName(), + newRank.getName() ); + PrisonAPI.debug( localManagerLog.localize() ); + } + } }); // ... remove it from each ladder it was in... ladder.removeRank( rank ); -// ladder.removeRank(ladder.getPositionOfRank(rank)); if ( !PrisonRanks.getInstance().getLadderManager().save(ladder) ) { - success = false; - - Localizable localManagerLog = PrisonRanks.getInstance().getRanksMessages() - .getLocalizable( "ranks_rankManager__cannot_save_ladder_file" ) - .withReplacements( ladder.getName() ); - - Output.get().logError( localManagerLog.localize() ); + success = false; + + Localizable localManagerLog = PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( "ranks_rankManager__cannot_save_ladder_file" ) + .withReplacements( ladder.getName() ); + + Output.get().logError( localManagerLog.localize() ); } } if( success ) { - // Remove it from the list... - removeRankFromCollections( rank ); - - // Reset the rank relationships: - // connectRanks(); - - // ... and remove the rank's save files. - // try both the old and new names: - collection.delete(rank.filenameNew()); - collection.delete(rank.filenameOld()); + // Remove it from the list... + removeRankFromCollections( rank ); + + + // ... and remove the rank's save files. + // try both the old and new names: + collection.delete(rank.filenameNew()); + collection.delete(rank.filenameOld()); } return success; } -// /** -// * Returns the rank with the specified ID. -// * -// * @param id The rank's ID. -// * @return An optional containing either the {@link Rank} if it could be found, or empty if it does not exist by the specified id. -// */ -// @Deprecated -// public Optional getRankOptional(int id) { -// return loadedRanks.stream().filter(rank -> rank.getId() == id).findFirst(); -// } public Rank getRank( int id ) { - return getRanksById().get( id ); + return getRanksById().get( id ); } /** @@ -518,46 +452,6 @@ public List getRanks() { return loadedRanks; } -// /** -// *

This should be ran after the RanksManager and LadderManger are loaded. Or any -// * time a rank is add, removed, or position changed within a ladder. -// *

-// * -// *

This function will set the temporal rankPrior and rankNext value in -// * each rank based upon each ladder. This will greatly simplify walking the -// * ladder by using the linked ranks without having to perform any expensive -// * calculations. -// *

-// */ -// public void connectRanks() { -// LadderManager lman = PrisonRanks.getInstance().getLadderManager(); -// -// for ( RankLadder rLadder : lman.getLadders() ) { -// -// rLadder.getPositionRanks().sort(Comparator.comparingInt(PositionRank::getPosition)); -// -// Rank rankLast = null; -// for ( PositionRank pRank : rLadder.getPositionRanks() ) { -// if ( pRank != null && pRank.getPosition() >= 0 ) { -// Optional opRank = rLadder.getByPosition(pRank.getPosition()); -// if ( opRank.isPresent() ) { -// Rank rank = opRank.get(); -// -// // reset the rankPrior and rankNext in case there are no hookups: -// // Important if ranks are removed, or inserted, or moved: -// rank.setRankPrior( null ); -// rank.setRankNext( null ); -// -// if ( rankLast != null ) { -// rank.setRankPrior( rankLast ); -// rankLast.setRankNext( rank ); -// } -// rankLast = rank; -// } -// } -// } -// } -// } /* *

This function will go through ranks and find ranks that have defined currencies. @@ -578,7 +472,7 @@ public List getRanks() { * */ public void identifyAllRankCurrencies( List prisonStartupDetails ) { - for ( Rank rank : loadedRanks ) { + for ( Rank rank : loadedRanks ) { if ( rank.getCurrency() != null ) { EconomyCurrencyIntegration currencyEcon = PrisonAPI.getIntegrationManager() .getEconomyForCurrency( rank.getCurrency() ); @@ -588,7 +482,7 @@ public void identifyAllRankCurrencies( List prisonStartupDetails ) { .getLocalizable( "ranks_rankManager__failure_no_economy" ) .withReplacements( rank.getCurrency(), rank.getName() ); - Output.get().logError( localManagerLog.localize() ); + Output.get().logError( localManagerLog.localize() ); prisonStartupDetails.add( localManagerLog.localize() ); } @@ -600,68 +494,58 @@ public void identifyAllRankCurrencies( List prisonStartupDetails ) { public String listAllRanks( String ladderName, List ranks, RanksByLadderOptions option ) { - StringBuilder sb = new StringBuilder(); - - sb.append( "&7 " ); - sb.append( ladderName ); - sb.append( ": " ); - -// PlayerManager playerManager = PrisonRanks.getInstance().getPlayerManager(); - - int count = 0; - for (Rank rank : ranks ) { - - int players = rank.getPlayers().size(); - - // Get the players per rank!! -// List playersList = -// playerManager.getPlayers().stream() -// .filter(rankPlayer -> rankPlayer.getLadderRanks().values().contains(rank)) -// .collect(Collectors.toList()); -// int players = playersList.size(); - - if ( option == RanksByLadderOptions.allRanks || - option == RanksByLadderOptions.full || players > 0 ) { - if ( count++ > 0 ) { - sb.append( ", " ); - - if ( count >= 10 && (count - 1) % 15 == 0 ) { - sb.append( "{br} " ); - } - } - - - sb.append( " " ).append( rank.getName() ); - - if ( players > 0 ) { - - sb.append( " (" ).append( players ).append( ")" ); - - if ( option == RanksByLadderOptions.full ) { - sb.append( "[" ); - - for ( RankPlayer rankPlayer : rank.getPlayers() ) - { - if ( rankPlayer.getName() != null ) { - - sb.append( rankPlayer.getName() ).append( " " ); - } + StringBuilder sb = new StringBuilder(); + + sb.append( "&7 " ); + sb.append( ladderName ); + sb.append( ": " ); + + int count = 0; + for (Rank rank : ranks ) { + + int players = rank.getPlayers().size(); + + if ( option == RanksByLadderOptions.allRanks || + option == RanksByLadderOptions.full || players > 0 ) { + if ( count++ > 0 ) { + sb.append( ", " ); + + if ( count >= 10 && (count - 1) % 15 == 0 ) { + sb.append( "{br} " ); + } + } + + + sb.append( " " ).append( rank.getName() ); + + if ( players > 0 ) { + + sb.append( " (" ).append( players ).append( ")" ); + + if ( option == RanksByLadderOptions.full ) { + sb.append( "[" ); + + for ( RankPlayer rankPlayer : rank.getPlayers() ) { + if ( rankPlayer.getName() != null ) { + + sb.append( rankPlayer.getName() ).append( " " ); + } } - - // if last character is a space, then remove it: - if ( sb.charAt( sb.length() - 1 ) == ' ' ) { - sb.setLength( sb.length() - 1 ); - } - sb.append( "]" ); - } - - } - - - } + + // if last character is a space, then remove it: + if ( sb.charAt( sb.length() - 1 ) == ' ' ) { + sb.setLength( sb.length() - 1 ); + } + sb.append( "]" ); + } + + } + + + } } - - return sb.toString(); + + return sb.toString(); } @@ -672,13 +556,13 @@ public String listAllRanks( String ladderName, List ranks, RanksByLadderOp * @param includeAll If true then includes all ranks, otherwise just ranks within one more players */ public List ranksByLadders() { - return ranksByLadders( "all", RanksByLadderOptions.allRanks ); + return ranksByLadders( "all", RanksByLadderOptions.allRanks ); } public void ranksByLadders( CommandSender sender, RanksByLadderOptions option ) { - List results = ranksByLadders( "all", option ); - for (String msg : results) { - rankByLadderOutput( sender, msg ); + List results = ranksByLadders( "all", option ); + for (String msg : results) { + rankByLadderOutput( sender, msg ); } } @@ -691,46 +575,46 @@ public void ranksByLadders( CommandSender sender, String ladderName, RanksByLadd } private List ranksByLadders( String ladderName, RanksByLadderOptions option ) { - List results = new ArrayList<>(); - - - Localizable localManagerLog = PrisonRanks.getInstance().getRanksMessages() - .getLocalizable( "ranks_rankManager__ranks_by_ladders" ); - - results.add( localManagerLog.localize() ); - - // Track which ranks were included in the ladders listed: - List ranksIncluded = new ArrayList<>(); - - for ( RankLadder ladder : PrisonRanks.getInstance().getLadderManager().getLadders() ) { - if ( ladderName.equalsIgnoreCase( "all" ) || ladderName.equalsIgnoreCase( ladder.getName() ) ) { - - List ladderRanks = ladder.getRanks(); - ranksIncluded.addAll( ladderRanks ); - - String ranksByLadder = listAllRanks( ladder.getName(), ladderRanks, option ); - - results.add( ranksByLadder ); - } - } - - if ( ladderName.equalsIgnoreCase( "all" ) || ladderName.equalsIgnoreCase( "none" ) ) { - - // Next we need to get a list of all ranks that were not included. Use set - List ranksExcluded = new ArrayList<>( loadedRanks ); - ranksExcluded.removeAll( ranksIncluded ); - - // Next generate a list of ranks that are not associated with any ladder: - // NOTE: No players should be associated with ranks that are not tied to a ladder, - // so enable "true" for includeAll to list all ranks that are not tied to ladders - // since player count will always be zero. - // Update: Set the RanksByLadderOptions to full - String ranksByLadder = listAllRanks( "(*no-ladder*)", ranksExcluded, RanksByLadderOptions.full ); - - results.add( ranksByLadder ); - } - - return results; + List results = new ArrayList<>(); + + + Localizable localManagerLog = PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( "ranks_rankManager__ranks_by_ladders" ); + + results.add( localManagerLog.localize() ); + + // Track which ranks were included in the ladders listed: + List ranksIncluded = new ArrayList<>(); + + for ( RankLadder ladder : PrisonRanks.getInstance().getLadderManager().getLadders() ) { + if ( ladderName.equalsIgnoreCase( "all" ) || ladderName.equalsIgnoreCase( ladder.getName() ) ) { + + List ladderRanks = ladder.getRanks(); + ranksIncluded.addAll( ladderRanks ); + + String ranksByLadder = listAllRanks( ladder.getName(), ladderRanks, option ); + + results.add( ranksByLadder ); + } + } + + if ( ladderName.equalsIgnoreCase( "all" ) || ladderName.equalsIgnoreCase( "none" ) ) { + + // Next we need to get a list of all ranks that were not included. Use set + List ranksExcluded = new ArrayList<>( loadedRanks ); + ranksExcluded.removeAll( ranksIncluded ); + + // Next generate a list of ranks that are not associated with any ladder: + // NOTE: No players should be associated with ranks that are not tied to a ladder, + // so enable "true" for includeAll to list all ranks that are not tied to ladders + // since player count will always be zero. + // Update: Set the RanksByLadderOptions to full + String ranksByLadder = listAllRanks( "(*no-ladder*)", ranksExcluded, RanksByLadderOptions.full ); + + results.add( ranksByLadder ); + } + + return results; } private void rankByLadderOutput( CommandSender sender, String ranksByLadder ) { @@ -766,12 +650,12 @@ else if ( formatted ) { public String getTranslateRanksPlaceHolder( PlaceholderIdentifier identifier ) { - Player player = identifier.getPlayer(); + Player player = identifier.getPlayer(); PlayerManager pm = PrisonRanks.getInstance().getPlayerManager(); RankPlayer rankPlayer = pm.getPlayer( player ); - PlaceHolderKey placeHolderKey = identifier.getPlaceholderKey(); + PlaceHolderKey placeHolderKey = identifier.getPlaceholderKey(); String rankName = placeHolderKey.getData(); @@ -779,10 +663,10 @@ public String getTranslateRanksPlaceHolder( PlaceholderIdentifier identifier ) { - PlaceholderAttributeBar attributeBar = identifier.getAttributeBar(); - PlaceholderAttributeNumberFormat attributeNFormat = identifier.getAttributeNFormat(); - PlaceholderAttributeText attributeText = identifier.getAttributeText(); - @SuppressWarnings("unused") + PlaceholderAttributeBar attributeBar = identifier.getAttributeBar(); + PlaceholderAttributeNumberFormat attributeNFormat = identifier.getAttributeNFormat(); + PlaceholderAttributeText attributeText = identifier.getAttributeText(); + @SuppressWarnings("unused") PlaceholderAttributeTime attributeTime = identifier.getAttributeTime(); int sequence = identifier.getSequence(); @@ -803,11 +687,6 @@ public String getTranslateRanksPlaceHolder( PlaceholderIdentifier identifier ) { ) { -// if ( !( isStatsPlayers ) && -// rank != null && -// ( rankPlayer != null || -// rankPlayer == null && isStatsRank ) ) { - identifier.setFoundAMatch( true ); switch ( placeHolder ) { @@ -836,7 +715,7 @@ public String getTranslateRanksPlaceHolder( PlaceholderIdentifier identifier ) { if ( attributeNFormat != null ) { results = attributeNFormat.format( cost ); - } + } else { results = PlaceholdersUtil.formattedMetricSISize( cost ); @@ -850,18 +729,17 @@ public String getTranslateRanksPlaceHolder( PlaceholderIdentifier identifier ) { { double cost = calculateRankCost( rankPlayer, rank ); double balance = rankPlayer.getBalance( rank.getCurrency() ); -// double balance = pm.getPlayerBalance( rankPlayer, rank); double remaining = cost - balance; if ( remaining < 0 ) { - remaining = 0; - } + remaining = 0; + } if ( attributeNFormat != null ) { results = attributeNFormat.format( remaining ); - } + } else { results = dFmt.format( remaining ); @@ -874,18 +752,17 @@ public String getTranslateRanksPlaceHolder( PlaceholderIdentifier identifier ) { { double cost = calculateRankCost( rankPlayer, rank ); double balance = rankPlayer.getBalance( rank.getCurrency() ); -// double balance = pm.getPlayerBalance( rankPlayer, rank); double remaining = cost - balance; if ( remaining < 0 ) { remaining = 0; - } + } if ( attributeNFormat != null ) { results = attributeNFormat.format( remaining ); - } + } else { results = PlaceholdersUtil.formattedMetricSISize( remaining ); @@ -902,13 +779,12 @@ public String getTranslateRanksPlaceHolder( PlaceholderIdentifier identifier ) { { double cost = calculateRankCost( rankPlayer, rank ); double balance = rankPlayer.getBalance( rank.getCurrency() ); -// double balance = pm.getPlayerBalance( rankPlayer, rank); double percent = (balance < 0 ? 0 : (cost == 0.0d || balance > cost ? 100.0 : balance / cost * 100.0 ) ); - results = dFmt.format( percent ); + results = dFmt.format( percent ); } break; @@ -917,7 +793,6 @@ public String getTranslateRanksPlaceHolder( PlaceholderIdentifier identifier ) { { double cost = calculateRankCost( rankPlayer, rank ); double balance = rankPlayer.getBalance( rank.getCurrency() ); -// double balance = pm.getPlayerBalance( rankPlayer, rank); results = PlaceholderManagerUtils.getInstance(). getProgressBar( balance, cost, false, attributeBar ); @@ -1091,7 +966,7 @@ else if ( placeHolder == PrisonPlaceHolders.prison_top_player_balance_raw_nnn_tp if ( attributeNFormat != null ) { results = attributeNFormat.format( rankScore ); - } + } else { results = dFmt.format(rankScore); } @@ -1141,7 +1016,7 @@ else if ( placeHolder == PrisonPlaceHolders.prison_top_player_balance_raw_nnn_tp if ( attributeNFormat != null ) { results = attributeNFormat.format( rsPenalty ); - } + } else if ( placeHolder == PrisonPlaceHolders.prison_top_player_penalty_formatted_nnn_tp || placeHolder == PrisonPlaceHolders.prison_tppf_nnn_tp ) { @@ -1275,9 +1150,6 @@ else if ( placeHolder == PrisonPlaceHolders.prison_top_player_penalty_raw_nnn_tp PlayerRank pRank = rankPlayer.calculateTargetPlayerRank( rank ); -// RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); -// PlayerRank pRank = rankPlayerFactory.createPlayerRank( rank ); - if ( pRank == null ) { results = ""; } @@ -1379,7 +1251,7 @@ else if ( Output.get().isDebug() ) { private RankPlayer getTopNRankPlayer( int rankPosition ) { - return TopNPlayers.getInstance().getTopNRankPlayer( rankPosition ); + return TopNPlayers.getInstance().getTopNRankPlayer( rankPosition ); } @@ -1429,42 +1301,6 @@ private double calculateRankCost( RankPlayer rankPlayer, Rank targetRank ) } -// PlayerRank playerRank = rankPlayerFactory.getRank( rankPlayer, targetRank.getLadder() ); - - -// if ( playerRank != null ) { -// -// -//// List -// -// -// // If the player is at a higher rank, or the same rank, then the cost will be -// // zero for the rank that is being passed in, since the player has -// // already paid for that rank. -// if ( rank.getPosition() <= playerRank.getRank().getPosition() ) { -// cost = 0; -// } -// else { -// //cost = playerRank.getRankCost(); -// Rank nextRank = playerRank.getRank(); -// -// while ( nextRank != null && -// nextRank.getPosition() <= targetRank.getPosition() ) { -// -// // Need to calculate the next PlayerRank value for the next rank: -// -// // This calculates the target rank, and takes in to consideration the player's existing rank: -// playerRank = playerRank.getTargetPlayerRankForPlayer( rankPlayer, nextRank ); -// -// -//// playerRank = rankPlayerFactory.createPlayerRank( nextRank ); -//// playerRank = new PlayerRank(nextRank); -// -// cost += playerRank.getRankCost(); -// nextRank = nextRank.getRankNext(); -// } -// } -// } return cost; } @@ -1577,68 +1413,68 @@ private Rank findNextRanksOnDefaultLadder( Rank rankDefault, Rank targetRank, Ar @Override public List getTranslatedPlaceHolderKeys() { - if ( translatedPlaceHolderKeys == null ) { - translatedPlaceHolderKeys = new ArrayList<>(); - - // This generates all the placeholders for all ranks: - List placeHolders = PrisonPlaceHolders.getTypes( PlaceholderFlags.RANKS ); - - placeHolders.addAll( PrisonPlaceHolders.getTypes( PlaceholderFlags.RANKPLAYERS ) ); - - placeHolders.addAll( PrisonPlaceHolders.getTypes( PlaceholderFlags.STATSRANKS ) ); - - - List ranks = PrisonRanks.getInstance().getRankManager().getRanks(); - for ( Rank rank : ranks ) { - for ( PrisonPlaceHolders ph : placeHolders ) { - - String rankName = rank.getName().toLowerCase(); - - String key = ph.name().replace( - PlaceholderManager.PRISON_PLACEHOLDER_RANKNAME_SUFFIX, "_" + rankName ). - toLowerCase(); - - PlaceHolderKey placeholder = new PlaceHolderKey(key, ph, rankName ); - if ( ph.getAlias() != null ) { - String aliasName = ph.getAlias().name().replace( - PlaceholderManager.PRISON_PLACEHOLDER_RANKNAME_SUFFIX, "_" + rankName ). - toLowerCase(); - placeholder.setAliasName( aliasName ); - } - translatedPlaceHolderKeys.add( placeholder ); - - } - - } - - - // This generates all the placeholders for all ranks: - List placeHolders2 = PrisonPlaceHolders.getTypes( PlaceholderFlags.STATSPLAYERS ); - - for ( PrisonPlaceHolders ph : placeHolders2 ) { - String key = ph.name(); - - PlaceHolderKey placeholder = new PlaceHolderKey(key, ph ); - if ( ph.getAlias() != null ) { - String aliasName = ph.getAlias().name(); - placeholder.setAliasName( aliasName ); - } - translatedPlaceHolderKeys.add( placeholder ); - } - - } - - return translatedPlaceHolderKeys; + if ( translatedPlaceHolderKeys == null ) { + translatedPlaceHolderKeys = new ArrayList<>(); + + // This generates all the placeholders for all ranks: + List placeHolders = PrisonPlaceHolders.getTypes( PlaceholderFlags.RANKS ); + + placeHolders.addAll( PrisonPlaceHolders.getTypes( PlaceholderFlags.RANKPLAYERS ) ); + + placeHolders.addAll( PrisonPlaceHolders.getTypes( PlaceholderFlags.STATSRANKS ) ); + + + List ranks = PrisonRanks.getInstance().getRankManager().getRanks(); + for ( Rank rank : ranks ) { + for ( PrisonPlaceHolders ph : placeHolders ) { + + String rankName = rank.getName().toLowerCase(); + + String key = ph.name().replace( + PlaceholderManager.PRISON_PLACEHOLDER_RANKNAME_SUFFIX, "_" + rankName ). + toLowerCase(); + + PlaceHolderKey placeholder = new PlaceHolderKey(key, ph, rankName ); + if ( ph.getAlias() != null ) { + String aliasName = ph.getAlias().name().replace( + PlaceholderManager.PRISON_PLACEHOLDER_RANKNAME_SUFFIX, "_" + rankName ). + toLowerCase(); + placeholder.setAliasName( aliasName ); + } + translatedPlaceHolderKeys.add( placeholder ); + + } + + } + + + // This generates all the placeholders for all ranks: + List placeHolders2 = PrisonPlaceHolders.getTypes( PlaceholderFlags.STATSPLAYERS ); + + for ( PrisonPlaceHolders ph : placeHolders2 ) { + String key = ph.name(); + + PlaceHolderKey placeholder = new PlaceHolderKey(key, ph ); + if ( ph.getAlias() != null ) { + String aliasName = ph.getAlias().name(); + placeholder.setAliasName( aliasName ); + } + translatedPlaceHolderKeys.add( placeholder ); + } + + } + + return translatedPlaceHolderKeys; } @Override public void reloadPlaceholders() { - - // clear the class variable so they will regenerate: - translatedPlaceHolderKeys = null; - - // Regenerate the translated placeholders: - getTranslatedPlaceHolderKeys(); + + // clear the class variable so they will regenerate: + translatedPlaceHolderKeys = null; + + // Regenerate the translated placeholders: + getTranslatedPlaceHolderKeys(); } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/tasks/PlayerNewFileNameCheckAsyncTask.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/tasks/PlayerNewFileNameCheckAsyncTask.java index b1ce192b4..d6a90d082 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/tasks/PlayerNewFileNameCheckAsyncTask.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/tasks/PlayerNewFileNameCheckAsyncTask.java @@ -108,7 +108,6 @@ public void run() { oldPlayerFile.renameTo(newPlayerFile); -// Files.move( oldPlayerFile, newPlayerFile ); changedPlayRankFiles++; } } @@ -127,7 +126,6 @@ public void run() { File newCacheFile = new File( playerCachePath, newFilename ); oldCacheFile.renameTo(newCacheFile); -// Files.move( oldCacheFile, newCacheFile ); changedCacheFiles++; // The player's cache data object contains a File object pointing to @@ -153,110 +151,9 @@ public void run() { changedPlayRankFiles, changedCacheFiles ); -// if ( changedCacheFiles > 0 || changedCacheFiles > 0 ) { -// saveStatusDetailLog( changedPlayRankFiles, changedCacheFiles ); -// } -// else if ( players.size() > 0 ) { -// Output.get().logInfo( -// "&3PlayerFileNameCheck Task: It appears as if all player files have " -// + "already been converted." ); -// } - -// List msgs = getStatusDetails(); -// -// for (String msg : msgs) { -// -// Output.get().logInfo( msg ); -// } - } -// public void saveStatusDetailLog( int changedPlayRankFiles, int changedCacheFiles ) { -// // Need to log it: -// TreeMap settings = PrisonSystemSettings.getInstance() -// .getRootSetting( SystemSettingsKey.PlayerFileNameUpdate ); -// -// if ( !settings.containsKey( "converted") ) { -// settings.put("converted", Boolean.TRUE ); -// } -// -// if ( !settings.containsKey( "logs") ) { -// settings.put("logs", new ArrayList() ); -// } -// -// @SuppressWarnings("unchecked") -// ArrayList logs = (ArrayList) settings.get("logs"); -// -// TreeMap log = new TreeMap<>(); -// -// SimpleDateFormat sdFmt = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss"); -// log.put("run-date", sdFmt.format(new Date()) ); -// log.put("player-cache-files-changed", Integer.valueOf(changedPlayRankFiles) ); -// log.put("player-rank-files-changed", Integer.valueOf(changedCacheFiles) ); -// -// logs.add( log ); -// -// // Save the update: -// PrisonSystemSettings.getInstance().save(); -// -// // Unload the data: -//// PrisonSystemSettings.getInstance().unload(); -// -// -// } -// public List getStatusDetails() { -// List msg = new ArrayList<>(); -// -// String msgFmt = " %-22s %7s %7s"; -// -// boolean useNewFormat = Prison.get().getPlatform() -// .getConfigBooleanFalse( PrisonSystemSettings.PRISON_SYSTEM_SETTING_FRIENDLY_PLAYER_FILE_NAMES ); -// -// TreeMap pfnUpdate = -// PrisonSystemSettings.getInstance().getRootSetting( SystemSettingsKey.PlayerFileNameUpdate ); -// -// // Unload the data: -//// PrisonSystemSettings.getInstance().unload(); -// -// boolean converted = !pfnUpdate.containsKey("converted") ? -// false : (Boolean) pfnUpdate.get("converted"); -// -// msg.add( "PlayerFileNameUpdate: status: " ); -// msg.add( " '" + PrisonSystemSettings.PRISON_SYSTEM_SETTING_FRIENDLY_PLAYER_FILE_NAMES + "': " + -// Boolean.toString(useNewFormat) ); -// msg.add( " converted: " + Boolean.toString(converted) ); -// -// if ( converted ) { -// -// @SuppressWarnings("unchecked") -// ArrayList logs = (ArrayList) pfnUpdate.get("logs"); -// -// msg.add( String.format(msgFmt, "", "Changed", "Changed")); -// msg.add( String.format(msgFmt, "Date", "P-Ranks", "P-Cache")); -// msg.add( String.format(msgFmt, "-----------------", "-------", "-------")); -// -// for (Object logObj : logs) { -// @SuppressWarnings("unchecked") -// TreeMap log = (TreeMap) logObj; -// -// String runDate = (String) log.get("run-date"); -// int changedPlayRankFiles = (Integer) log.get("player-cache-files-changed"); -// int changedCacheFiles = (Integer) log.get("player-rank-files-changed"); -// -// msg.add( String.format(msgFmt, -// runDate, -// Integer.toString(changedCacheFiles), -// Integer.toString(changedPlayRankFiles))); -// } -// -// } -// -// // msg.add( "" ); -// -// -// return msg; -// } /** From 51949f84cec3e9c254e873784197b9efd2dc0a7e Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 6 Mar 2026 11:53:10 -0500 Subject: [PATCH 304/323] Renamed an enum to BlockEventCustomPlaceholders since it was not clear it was related to block events and that this has nothing to do with the standard placeholders. --- docs/changelog_v3.3.x.md | 4 +- .../prison/tasks/PrisonCommandTaskData.java | 17 ++++--- .../PrisonCommandTaskPlaceholderData.java | 10 ++-- .../prison/mines/commands/MinesCommands.java | 8 ++-- .../prison/mines/data/MineScheduler.java | 48 +++++++++---------- .../tech/mcprison/prison/ranks/RankUtil.java | 22 ++++----- .../ranks/commands/CommandCommands.java | 8 ++-- 7 files changed, 62 insertions(+), 55 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 7cb12df79..6b2bc56c6 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.19j 2026-03-04 +# 3.3.0-alpha.19j 2026-03-06 +* **Renamed an enum to BlockEventCustomPlaceholders since it was not clear it was related to block events and that this has nothing to do with the standard placeholders.** + * **Prison Cleanup: prison-ranks: Removed obsolete and unneeded comments and fix indentation where needed.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonCommandTaskData.java b/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonCommandTaskData.java index f04308df9..40c324c1e 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonCommandTaskData.java +++ b/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonCommandTaskData.java @@ -84,7 +84,12 @@ public enum CommandEnvironment { ; } - public enum CustomPlaceholders { + + /** + *

These are placeholders used within Block Events. + *

+ */ + public enum BlockEventCustomPlaceholders { player(CommandEnvironment.all_commands, "{player} provides a player's name."), @@ -221,17 +226,17 @@ public enum CustomPlaceholders { private final String description; private final String exampleUsage; - private CustomPlaceholders( CommandEnvironment environment ) { + private BlockEventCustomPlaceholders( CommandEnvironment environment ) { this.environment = environment; this.description = null; this.exampleUsage = null; } - private CustomPlaceholders( CommandEnvironment environment, String description ) { + private BlockEventCustomPlaceholders( CommandEnvironment environment, String description ) { this.environment = environment; this.description = description; this.exampleUsage = null; } - private CustomPlaceholders( CommandEnvironment environment, String description, + private BlockEventCustomPlaceholders( CommandEnvironment environment, String description, String exampleUsage ) { this.environment = environment; this.description = description; @@ -243,7 +248,7 @@ public static String listPlaceholders( CommandEnvironment environment ) { if ( environment != null ) { - for ( CustomPlaceholders cp : values() ) { + for ( BlockEventCustomPlaceholders cp : values() ) { if ( environment.equals( cp.getEnvironment() ) ) { if ( sb.length() > 0 ) { @@ -618,7 +623,7 @@ private String translateCommand( Player player, String command ) { * characters. * @param value The value that is used to replace the placeholder. */ - public void addCustomPlaceholder( CustomPlaceholders placeholder, String value ) { + public void addCustomPlaceholder( BlockEventCustomPlaceholders placeholder, String value ) { PrisonCommandTaskPlaceholderData cph = new PrisonCommandTaskPlaceholderData( placeholder, value); getCustomPlaceholders().add( cph ); } diff --git a/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonCommandTaskPlaceholderData.java b/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonCommandTaskPlaceholderData.java index 407441a20..a9d884db5 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonCommandTaskPlaceholderData.java +++ b/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonCommandTaskPlaceholderData.java @@ -1,13 +1,13 @@ package tech.mcprison.prison.tasks; -import tech.mcprison.prison.tasks.PrisonCommandTaskData.CustomPlaceholders; +import tech.mcprison.prison.tasks.PrisonCommandTaskData.BlockEventCustomPlaceholders; public class PrisonCommandTaskPlaceholderData { - private CustomPlaceholders placeholder; + private BlockEventCustomPlaceholders placeholder; private String value; - public PrisonCommandTaskPlaceholderData( CustomPlaceholders placeholder, String value ) { + public PrisonCommandTaskPlaceholderData( BlockEventCustomPlaceholders placeholder, String value ) { super(); this.placeholder = placeholder; @@ -27,10 +27,10 @@ public String replace( String text ) { return results; } - public CustomPlaceholders getPlaceholder() { + public BlockEventCustomPlaceholders getPlaceholder() { return placeholder; } - public void setPlaceholder( CustomPlaceholders placeholder ) { + public void setPlaceholder( BlockEventCustomPlaceholders placeholder ) { this.placeholder = placeholder; } 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 e8e19ed5f..055e9b92f 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 @@ -3788,10 +3788,10 @@ public void blockEventAdd(CommandSender sender, String placeholders = - PrisonCommandTaskData.CustomPlaceholders.listPlaceholders( + PrisonCommandTaskData.BlockEventCustomPlaceholders.listPlaceholders( PrisonCommandTaskData.CommandEnvironment.all_commands ) + " " + - PrisonCommandTaskData.CustomPlaceholders.listPlaceholders( + PrisonCommandTaskData.BlockEventCustomPlaceholders.listPlaceholders( PrisonCommandTaskData.CommandEnvironment.blockevent_commands ); String message = String.format( "Valid Placeholders that can be used with blockEvents: [%s]", @@ -4835,10 +4835,10 @@ public void commandAdd(CommandSender sender, String placeholders = - PrisonCommandTaskData.CustomPlaceholders.listPlaceholders( + PrisonCommandTaskData.BlockEventCustomPlaceholders.listPlaceholders( PrisonCommandTaskData.CommandEnvironment.all_commands ) + " " + - PrisonCommandTaskData.CustomPlaceholders.listPlaceholders( + PrisonCommandTaskData.BlockEventCustomPlaceholders.listPlaceholders( PrisonCommandTaskData.CommandEnvironment.mine_commands ); String message = String.format( "Valid Placeholders that can be used with mine commands: [%s]", diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineScheduler.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineScheduler.java index 272c1237e..35ff5fd63 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineScheduler.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineScheduler.java @@ -21,7 +21,7 @@ import tech.mcprison.prison.mines.tasks.MinePagedResetAsyncTask; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.tasks.PrisonCommandTaskData; -import tech.mcprison.prison.tasks.PrisonCommandTaskData.CustomPlaceholders; +import tech.mcprison.prison.tasks.PrisonCommandTaskData.BlockEventCustomPlaceholders; import tech.mcprison.prison.tasks.PrisonRunnable; import tech.mcprison.prison.tasks.PrisonTaskSubmitter; import tech.mcprison.prison.tasks.PrisonCommandTasks; @@ -591,50 +591,50 @@ private int processBlockEventDetails( Player player, PrisonBlock prisonBlock, cmdTask.setTaskMode( blockEvent.getTaskMode() ); - cmdTask.addCustomPlaceholder( CustomPlaceholders.blockName, originalBlock.getBlockName() ); - cmdTask.addCustomPlaceholder( CustomPlaceholders.mineName, getName() ); + cmdTask.addCustomPlaceholder( BlockEventCustomPlaceholders.blockName, originalBlock.getBlockName() ); + cmdTask.addCustomPlaceholder( BlockEventCustomPlaceholders.mineName, getName() ); if ( targetBlock.getLocation() != null ) { Location location = targetBlock.getLocation(); - cmdTask.addCustomPlaceholder( CustomPlaceholders.locationWorld, location.getWorld().getName() ); - cmdTask.addCustomPlaceholder( CustomPlaceholders.locationX, Integer.toString( location.getBlockX() )); - cmdTask.addCustomPlaceholder( CustomPlaceholders.locationY, Integer.toString( location.getBlockY() )); - cmdTask.addCustomPlaceholder( CustomPlaceholders.locationZ, Integer.toString( location.getBlockZ() )); + cmdTask.addCustomPlaceholder( BlockEventCustomPlaceholders.locationWorld, location.getWorld().getName() ); + cmdTask.addCustomPlaceholder( BlockEventCustomPlaceholders.locationX, Integer.toString( location.getBlockX() )); + cmdTask.addCustomPlaceholder( BlockEventCustomPlaceholders.locationY, Integer.toString( location.getBlockY() )); + cmdTask.addCustomPlaceholder( BlockEventCustomPlaceholders.locationZ, Integer.toString( location.getBlockZ() )); - cmdTask.addCustomPlaceholder( CustomPlaceholders.coordinates, location.toCoordinates() ); - cmdTask.addCustomPlaceholder( CustomPlaceholders.worldCoordinates, location.toWorldCoordinates() ); + cmdTask.addCustomPlaceholder( BlockEventCustomPlaceholders.coordinates, location.toCoordinates() ); + cmdTask.addCustomPlaceholder( BlockEventCustomPlaceholders.worldCoordinates, location.toWorldCoordinates() ); - cmdTask.addCustomPlaceholder( CustomPlaceholders.blockCoordinates, targetBlock.getBlockCoordinates() ); + cmdTask.addCustomPlaceholder( BlockEventCustomPlaceholders.blockCoordinates, targetBlock.getBlockCoordinates() ); } // cmdTask.addCustomPlaceholder( CustomPlaceholders.blockCoordinates, prisonBlock.getBlockCoordinates() ); - cmdTask.addCustomPlaceholder( CustomPlaceholders.blockChance, dFmt.format( originalBlock.getChance() ) ); + cmdTask.addCustomPlaceholder( BlockEventCustomPlaceholders.blockChance, dFmt.format( originalBlock.getChance() ) ); - cmdTask.addCustomPlaceholder( CustomPlaceholders.blocksPlaced, Integer.toString( originalBlock.getBlockPlacedCount() )); - cmdTask.addCustomPlaceholder( CustomPlaceholders.blockRemaining, Long.toString( originalBlock.getBlockCountUnsaved() )); + cmdTask.addCustomPlaceholder( BlockEventCustomPlaceholders.blocksPlaced, Integer.toString( originalBlock.getBlockPlacedCount() )); + cmdTask.addCustomPlaceholder( BlockEventCustomPlaceholders.blockRemaining, Long.toString( originalBlock.getBlockCountUnsaved() )); - cmdTask.addCustomPlaceholder( CustomPlaceholders.blocksMinedTotal, Long.toString( originalBlock.getBlockCountSession() ) ); + cmdTask.addCustomPlaceholder( BlockEventCustomPlaceholders.blocksMinedTotal, Long.toString( originalBlock.getBlockCountSession() ) ); - cmdTask.addCustomPlaceholder( CustomPlaceholders.mineBlocksRemaining, Integer.toString( getRemainingBlockCount() )); - cmdTask.addCustomPlaceholder( CustomPlaceholders.mineBlocksRemainingPercent, Double.toString( getPercentRemainingBlockCount() ) ); - cmdTask.addCustomPlaceholder( CustomPlaceholders.mineBlocksTotalMined, Long.toString( getTotalBlocksMined() )); - cmdTask.addCustomPlaceholder( CustomPlaceholders.mineBlocksSize, Integer.toString( getBounds().getTotalBlockCount() )); + cmdTask.addCustomPlaceholder( BlockEventCustomPlaceholders.mineBlocksRemaining, Integer.toString( getRemainingBlockCount() )); + cmdTask.addCustomPlaceholder( BlockEventCustomPlaceholders.mineBlocksRemainingPercent, Double.toString( getPercentRemainingBlockCount() ) ); + cmdTask.addCustomPlaceholder( BlockEventCustomPlaceholders.mineBlocksTotalMined, Long.toString( getTotalBlocksMined() )); + cmdTask.addCustomPlaceholder( BlockEventCustomPlaceholders.mineBlocksSize, Integer.toString( getBounds().getTotalBlockCount() )); - cmdTask.addCustomPlaceholder( CustomPlaceholders.blockIsAir, Boolean.toString( targetBlock.getPrisonBlock().isAir() )); + cmdTask.addCustomPlaceholder( BlockEventCustomPlaceholders.blockIsAir, Boolean.toString( targetBlock.getPrisonBlock().isAir() )); if ( prisonBlock != null ) { - cmdTask.addCustomPlaceholder( CustomPlaceholders.blockMinedName, prisonBlock.getBlockName() ); - cmdTask.addCustomPlaceholder( CustomPlaceholders.blockMinedNameFormal, prisonBlock.getBlockNameFormal() ); - cmdTask.addCustomPlaceholder( CustomPlaceholders.blockMinedBlockType, prisonBlock.getBlockType().name() ); + cmdTask.addCustomPlaceholder( BlockEventCustomPlaceholders.blockMinedName, prisonBlock.getBlockName() ); + cmdTask.addCustomPlaceholder( BlockEventCustomPlaceholders.blockMinedNameFormal, prisonBlock.getBlockNameFormal() ); + cmdTask.addCustomPlaceholder( BlockEventCustomPlaceholders.blockMinedBlockType, prisonBlock.getBlockType().name() ); } - cmdTask.addCustomPlaceholder( CustomPlaceholders.eventType, eventType.name() ); - cmdTask.addCustomPlaceholder( CustomPlaceholders.eventTriggered, triggered ); + cmdTask.addCustomPlaceholder( BlockEventCustomPlaceholders.eventType, eventType.name() ); + cmdTask.addCustomPlaceholder( BlockEventCustomPlaceholders.eventTriggered, triggered ); cmdTasks.add( cmdTask ); diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/RankUtil.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/RankUtil.java index b59936bfa..1c324a2e7 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/RankUtil.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/RankUtil.java @@ -37,7 +37,7 @@ import tech.mcprison.prison.ranks.events.RankUpEvent; import tech.mcprison.prison.ranks.managers.LadderManager; import tech.mcprison.prison.tasks.PrisonCommandTaskData; -import tech.mcprison.prison.tasks.PrisonCommandTaskData.CustomPlaceholders; +import tech.mcprison.prison.tasks.PrisonCommandTaskData.BlockEventCustomPlaceholders; /** * Utilities for changing the ranks of players. @@ -654,25 +654,25 @@ else if ( pForceCharge == PromoteForceCharge.refund_player) { cmdTask.setRankOriginal( opRank ); - cmdTask.addCustomPlaceholder( CustomPlaceholders.balanceInitial, Double.toString( results.getBalanceInitial()) ); - cmdTask.addCustomPlaceholder( CustomPlaceholders.balanceFinal, Double.toString( results.getBalanceFinal()) ); - cmdTask.addCustomPlaceholder( CustomPlaceholders.currency, results.getCurrency() ); + cmdTask.addCustomPlaceholder( BlockEventCustomPlaceholders.balanceInitial, Double.toString( results.getBalanceInitial()) ); + cmdTask.addCustomPlaceholder( BlockEventCustomPlaceholders.balanceFinal, Double.toString( results.getBalanceFinal()) ); + cmdTask.addCustomPlaceholder( BlockEventCustomPlaceholders.currency, results.getCurrency() ); - cmdTask.addCustomPlaceholder( CustomPlaceholders.originalRankCost, + cmdTask.addCustomPlaceholder( BlockEventCustomPlaceholders.originalRankCost, opRank == null ? "" : Double.toString( opRank.getRankCost() ) ); - cmdTask.addCustomPlaceholder( CustomPlaceholders.rankupCost, + cmdTask.addCustomPlaceholder( BlockEventCustomPlaceholders.rankupCost, tpRank == null ? "" : Double.toString( tpRank.getRankCost() ) ); - cmdTask.addCustomPlaceholder( CustomPlaceholders.ladder, results.getLadderName() ); + cmdTask.addCustomPlaceholder( BlockEventCustomPlaceholders.ladder, results.getLadderName() ); - cmdTask.addCustomPlaceholder( CustomPlaceholders.rank, + cmdTask.addCustomPlaceholder( BlockEventCustomPlaceholders.rank, (oRank == null ? "none" : oRank.getName()) ); - cmdTask.addCustomPlaceholder( CustomPlaceholders.rankTag, + cmdTask.addCustomPlaceholder( BlockEventCustomPlaceholders.rankTag, (oRank == null ? "none" : oRank.getTag()) ); - cmdTask.addCustomPlaceholder( CustomPlaceholders.targetRank, + cmdTask.addCustomPlaceholder( BlockEventCustomPlaceholders.targetRank, (tRank == null ? "none" : tRank.getName()) ); - cmdTask.addCustomPlaceholder( CustomPlaceholders.targetRankTag, + cmdTask.addCustomPlaceholder( BlockEventCustomPlaceholders.targetRankTag, (tRank == null ? "none" : tRank.getTag()) ); diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/CommandCommands.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/CommandCommands.java index 9c250f532..1c7e36dfd 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/CommandCommands.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/CommandCommands.java @@ -58,10 +58,10 @@ public void commandAdd(CommandSender sender, String placeholders = - PrisonCommandTaskData.CustomPlaceholders.listPlaceholders( + PrisonCommandTaskData.BlockEventCustomPlaceholders.listPlaceholders( PrisonCommandTaskData.CommandEnvironment.all_commands ) + " " + - PrisonCommandTaskData.CustomPlaceholders.listPlaceholders( + PrisonCommandTaskData.BlockEventCustomPlaceholders.listPlaceholders( PrisonCommandTaskData.CommandEnvironment.rank_commands ); String message = ranksCommandAddPlaceholdersMsg( placeholders ); @@ -236,10 +236,10 @@ public void commandLadderAdd(CommandSender sender, if ( ladderName != null && "placeholders".equalsIgnoreCase( ladderName ) ) { - String placeholders = PrisonCommandTaskData.CustomPlaceholders.listPlaceholders( + String placeholders = PrisonCommandTaskData.BlockEventCustomPlaceholders.listPlaceholders( PrisonCommandTaskData.CommandEnvironment.all_commands ) + " " + - PrisonCommandTaskData.CustomPlaceholders.listPlaceholders( + PrisonCommandTaskData.BlockEventCustomPlaceholders.listPlaceholders( PrisonCommandTaskData.CommandEnvironment.rank_commands ); String message = ladderCommandAddPlaceholdersMsg( placeholders ); From 4fe6116636cef5fea9d0b54896d1bd266ea6e48f Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 6 Mar 2026 12:22:41 -0500 Subject: [PATCH 305/323] Removed some uses of the old block model. Breaking change: This removal should not actually break anything, but if upgrading from a version using the old block models, upgrade to an earlier release first to take advantage of the automatic conversion. Removed a few other unused source related to the old non-functional troubleshooting. --- docs/changelog_v3.3.x.md | 5 + .../java/tech/mcprison/prison/PrisonAPI.java | 6 +- .../tech/mcprison/prison/PrisonCommand.java | 42 +-- .../inbuilt/ItemTroubleshooter.java | 39 +-- .../mcprison/prison/mines/data/BlockOld.java | 191 +++++++------ .../tech/mcprison/prison/mines/data/Mine.java | 255 +++++++++--------- .../mcprison/prison/mines/data/MineData.java | 20 +- 7 files changed, 268 insertions(+), 290 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 6b2bc56c6..33e246b18 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.19j 2026-03-06 +* **Removed some uses of the old block model. Breaking change: This removal should not actually break anything, but if upgrading from a version using the old block models, upgrade to an earlier release first to take advantage of the automatic conversion.** + +* **Removed a few other unused source related to the old non-functional troubleshooting.** + + * **Renamed an enum to BlockEventCustomPlaceholders since it was not clear it was related to block events and that this has nothing to do with the standard placeholders.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/PrisonAPI.java b/prison-core/src/main/java/tech/mcprison/prison/PrisonAPI.java index fbe6ade48..fc9fe7280 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/PrisonAPI.java +++ b/prison-core/src/main/java/tech/mcprison/prison/PrisonAPI.java @@ -127,9 +127,9 @@ public static ScoreboardManager getScoreboardManager() { return Prison.get().getPlatform().getScoreboardManager(); } - public static TroubleshootManager getTroubleshootManager() { - return Prison.get().getTroubleshootManager(); - } +// public static TroubleshootManager getTroubleshootManager() { +// return Prison.get().getTroubleshootManager(); +// } public static IntegrationManager getIntegrationManager() { return Prison.get().getIntegrationManager(); 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 a8f2f15e9..79b9c5cf0 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java +++ b/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java @@ -504,18 +504,18 @@ public void troubleshootCommand(CommandSender sender, return; } - TroubleshootResult result = - PrisonAPI.getTroubleshootManager().invokeTroubleshooter(name, sender); - if (result == null) { - Output.get().sendError(sender, "The troubleshooter %s doesn't exist.", name); - return; - } - - ChatDisplay display = new ChatDisplay("Result Summary"); - display.addText("&7Troubleshooter name: &b%s", name.toLowerCase()) // - .addText("&7Result type: &b%s", result.getResult().name()) // - .addText("&7Result details: &b%s", result.getDescription()) // - .send(sender); +// TroubleshootResult result = +// PrisonAPI.getTroubleshootManager().invokeTroubleshooter(name, sender); +// if (result == null) { +// Output.get().sendError(sender, "The troubleshooter %s doesn't exist.", name); +// return; +// } +// +// ChatDisplay display = new ChatDisplay("Result Summary"); +// display.addText("&7Troubleshooter name: &b%s", name.toLowerCase()) // +// .addText("&7Result type: &b%s", result.getResult().name()) // +// .addText("&7Result details: &b%s", result.getDescription()) // +// .send(sender); } @@ -525,15 +525,15 @@ public void troubleshootListCommand(CommandSender sender) { ChatDisplay display = new ChatDisplay("Troubleshooters"); display.addText("&8Type /prison troubleshoot to run a troubleshooter."); - BulletedListComponent.BulletedListBuilder builder = - new BulletedListComponent.BulletedListBuilder(); - for (Troubleshooter troubleshooter : PrisonAPI.getTroubleshootManager() - .getTroubleshooters()) { - builder.add("&b%s &8- &7%s", troubleshooter.getName(), troubleshooter.getDescription()); - } - display.addComponent(builder.build()); - - display.send(sender); +// BulletedListComponent.BulletedListBuilder builder = +// new BulletedListComponent.BulletedListBuilder(); +// for (Troubleshooter troubleshooter : PrisonAPI.getTroubleshootManager() +// .getTroubleshooters()) { +// builder.add("&b%s &8- &7%s", troubleshooter.getName(), troubleshooter.getDescription()); +// } +// display.addComponent(builder.build()); +// +// display.send(sender); } diff --git a/prison-core/src/main/java/tech/mcprison/prison/troubleshoot/inbuilt/ItemTroubleshooter.java b/prison-core/src/main/java/tech/mcprison/prison/troubleshoot/inbuilt/ItemTroubleshooter.java index d11e77076..b76ae86c7 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/troubleshoot/inbuilt/ItemTroubleshooter.java +++ b/prison-core/src/main/java/tech/mcprison/prison/troubleshoot/inbuilt/ItemTroubleshooter.java @@ -4,39 +4,14 @@ * Inbuilt troubleshooter to scan the 'items.csv' file to ensure it's valid. * * @author Faizaan A. Datoo + * + * @deprecated */ public class ItemTroubleshooter -// extends Troubleshooter - { +{ + + // NOTE: The commented out source in this class has been removed. See git's history to view it. + // This class was related to the old block model and would search through the old block + // text file to find something that may have matched a key phrase. -// public ItemTroubleshooter() { -// super("item_scan", "Run this if you have trouble with the items.csv file."); -// } -// -// @Override public TroubleshootResult invoke(CommandSender invoker) { -// -// // Let's do our own test of initializing the ItemManager. -// try { -// ItemManager ourManager = new ItemManager(); -// ourManager.getItems(); -// } catch (Exception e) { -// // OK, so something's wrong -// // Let's try deleting the file and telling the user to relaunch. -// -// File itemsCsv = new File(PrisonAPI.getPluginDirectory(), "items.csv"); -// boolean deleted = itemsCsv.delete(); -// if (deleted) { -// return new TroubleshootResult(TroubleshootResult.Result.USER_ACTION, -// "We've found a problem with your items.csv file. We deleted it so that a new and non-corrupted one is generated. Please restart your server for the changes to take effect."); -// } else { -// // We can only hot delete on *NIX systems. -// return new TroubleshootResult(TroubleshootResult.Result.FAILURE, -// "We've found a problem with your items.csv file. We tried deleting it, but it could not be successfully deleted. Please stop your server, delete '/plugins/Prison/items.csv', and start your server again."); -// } -// } -// -// // Nothing is wrong. -// return new TroubleshootResult(TroubleshootResult.Result.SUCCESS, -// "No problems were found with your item manager or items.csv file."); -// } } diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/BlockOld.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/BlockOld.java index d82aeaccc..70e757b30 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/BlockOld.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/BlockOld.java @@ -18,112 +18,109 @@ package tech.mcprison.prison.mines.data; -import tech.mcprison.prison.internal.block.PrisonBlock.PrisonBlockType; -import tech.mcprison.prison.internal.block.PrisonBlockStatusData; -import tech.mcprison.prison.util.ObsoleteBlockType; - /** * Represents a block in a mine * * @deprecated */ -@SuppressWarnings("deprecation") +//@SuppressWarnings("deprecation") public class BlockOld - extends PrisonBlockStatusData - implements Comparable { - - public static final BlockOld AIR = new BlockOld( ObsoleteBlockType.AIR ); - public static final BlockOld IGNORE = new BlockOld( ObsoleteBlockType.IGNORE ); - public static final BlockOld NULL_BLOCK = new BlockOld( ObsoleteBlockType.NULL_BLOCK ); - - /** - * The {@link BlockType} represented by this {@link BlockOld} - */ - private ObsoleteBlockType type; // = BlockType.AIR; - /** - * The chance of this block appearing in it's associated mine - */ -// private double chance; // = 100.0d; - - - protected BlockOld( ObsoleteBlockType block ) { - this( block, 0.0d, 0L ); - } - - /** - * Assigns the type and chance - */ - public BlockOld(ObsoleteBlockType block, double chance, long blockCountTotal) { - super( PrisonBlockType.minecraft, (block == null ? BlockOld.AIR.getBlockName() : block.name()), chance, blockCountTotal); - - this.type = block; -// this.chance = chance; - } - - public BlockOld(String blockType, double chance, long blockCountTotal) { - super( PrisonBlockType.minecraft, blockType, chance, blockCountTotal); - -// this.chance = chance; - - ObsoleteBlockType block = ObsoleteBlockType.fromString( blockType ); - this.type = block; - // Update blockName since mapping to BlockType may result in a different name: - setBlockName( block.name() ); - - } - - @Override - public String toString() { - return getType().name() + " " + Double.toString( getChance() ); - } - - - @Override - public boolean equals( Object block ) { - boolean results = false; - - if ( block != null && block instanceof BlockOld) { - results = getType() == ((BlockOld) block).getType(); - } - - return results; - } +// extends PrisonBlockStatusData +// implements Comparable +{ - @Override - public int compareTo( BlockOld block ) - { - int results = 0; - - if ( block == null ) { - results = 1; - } - else { - results = getBlockName().compareToIgnoreCase( block.getBlockName() ); - } - - return results; - } - - public ObsoleteBlockType getType() - { - return type; - } - public void setType( ObsoleteBlockType type ) - { - this.type = type; - } - - @Override - public boolean isAir() { - return compareTo( AIR ) == 0; - } - -// public double getChance() +// public static final BlockOld AIR = new BlockOld( ObsoleteBlockType.AIR ); +// public static final BlockOld IGNORE = new BlockOld( ObsoleteBlockType.IGNORE ); +// public static final BlockOld NULL_BLOCK = new BlockOld( ObsoleteBlockType.NULL_BLOCK ); +// +// /** +// * The {@link BlockType} represented by this {@link BlockOld} +// */ +// private ObsoleteBlockType type; // = BlockType.AIR; +// /** +// * The chance of this block appearing in it's associated mine +// */ +//// private double chance; // = 100.0d; +// +// +// protected BlockOld( ObsoleteBlockType block ) { +// this( block, 0.0d, 0L ); +// } +// +// /** +// * Assigns the type and chance +// */ +// public BlockOld(ObsoleteBlockType block, double chance, long blockCountTotal) { +// super( PrisonBlockType.minecraft, (block == null ? BlockOld.AIR.getBlockName() : block.name()), chance, blockCountTotal); +// +// this.type = block; +//// this.chance = chance; +// } +// +// public BlockOld(String blockType, double chance, long blockCountTotal) { +// super( PrisonBlockType.minecraft, blockType, chance, blockCountTotal); +// +//// this.chance = chance; +// +// ObsoleteBlockType block = ObsoleteBlockType.fromString( blockType ); +// this.type = block; +// // Update blockName since mapping to BlockType may result in a different name: +// setBlockName( block.name() ); +// +// } +// +// @Override +// public String toString() { +// return getType().name() + " " + Double.toString( getChance() ); +// } +// +// +// @Override +// public boolean equals( Object block ) { +// boolean results = false; +// +// if ( block != null && block instanceof BlockOld) { +// results = getType() == ((BlockOld) block).getType(); +// } +// +// return results; +// } +// +// @Override +// public int compareTo( BlockOld block ) +// { +// int results = 0; +// +// if ( block == null ) { +// results = 1; +// } +// else { +// results = getBlockName().compareToIgnoreCase( block.getBlockName() ); +// } +// +// return results; +// } +// +// public ObsoleteBlockType getType() // { -// return chance; +// return type; // } -// public void setChance( double chance ) +// public void setType( ObsoleteBlockType type ) // { -// this.chance = chance; +// this.type = type; +// } +// +// @Override +// public boolean isAir() { +// return compareTo( AIR ) == 0; // } +// +//// public double getChance() +//// { +//// return chance; +//// } +//// public void setChance( double chance ) +//// { +//// this.chance = chance; +//// } } diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/Mine.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/Mine.java index 995cebcf5..52d76f401 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/Mine.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/Mine.java @@ -41,7 +41,6 @@ import tech.mcprison.prison.store.Document; import tech.mcprison.prison.util.Bounds; import tech.mcprison.prison.util.Location; -import tech.mcprison.prison.util.ObsoleteBlockType; /** * @author Dylan M. Perks @@ -390,86 +389,88 @@ private void loadFromDocument( Document document ) Set validateBlockNames = new HashSet<>(); getBlocks().clear(); - List docBlocks = (List) document.get("blocks"); - for (String docBlock : docBlocks) { - - // If the file is manually edited and a comma is added to the end of the block list, - // then docBlock could be null. Skip processing if null. - if ( docBlock != null ) { - - String[] split = docBlock.split("-"); - String blockTypeName = split[0]; -// double chance = split.length > 1 ? Double.parseDouble(split[1]) : 0; -// long blockCount = split.length > 2 ? Long.parseLong(split[2]) : 0; -// int constraintMin = split.length > 3 ? Integer.parseInt(split[3]) : 0; -// int constraintMax = split.length > 4 ? Integer.parseInt(split[4]) : 0; - - if ( blockTypeName != null && !validateBlockNames.contains( blockTypeName )) { - // Use the BlockType.name() load the block type: - ObsoleteBlockType blockType = ObsoleteBlockType.getBlock(blockTypeName); - if ( blockType != null ) { - - /** - *

The following is code to correct the use of items being used as a - * block in a mine, which will cause a failure in trying to place an - * item as a block. - *

- * - *

This is intended for the old block model and is temp code to ensure - * that there are less errors the end user will experience. - *

- */ - String errorMessage = "Warning! An invalid block type of %s was " + - "detect when loading blocks for " + - "mine %s. %s is not a valid block type. Using " + - "%s instead. If this is incorrect please fix manually."; - - if ( blockType == ObsoleteBlockType.REDSTONE ) { - ObsoleteBlockType itemType = blockType; - blockType = ObsoleteBlockType.REDSTONE_ORE; - - Output.get().logError( - String.format( errorMessage, itemType.name(), getName(), - "Redstone dust", blockType.name()) ); - - dirty = true; - } - else if ( blockType == ObsoleteBlockType.NETHER_BRICK ) { - ObsoleteBlockType itemType = blockType; - blockType = ObsoleteBlockType.DOUBLE_NETHER_BRICK_SLAB; - - Output.get().logError( - String.format( errorMessage, itemType.name(), getName(), - "Individual nether brick", blockType.name()) ); - - dirty = true; - } - - BlockOld block = new BlockOld(blockType); - - block.parseFromSaveFileFormatStats( docBlock ); - - totalBlockCount += block.getBlockCountTotal(); - - getBlocks().add(block); - } - else { - String message = String.format( "Failure in loading block type from %s mine's " + - "save file. Block type %s has no mapping.", getName(), - blockTypeName ); - Output.get().logError( message ); - } - - validateBlockNames.add( blockTypeName ); - } - else if (validateBlockNames.contains( blockTypeName ) ) { - // Detected and fixed a duplication so mark as dirty so fixed block list is saved: - dirty = true; - inconsistancy = true; - } - } - - } + + // Obsolete block model: +// List docBlocks = (List) document.get("blocks"); +// for (String docBlock : docBlocks) { +// +// // If the file is manually edited and a comma is added to the end of the block list, +// // then docBlock could be null. Skip processing if null. +// if ( docBlock != null ) { +// +// String[] split = docBlock.split("-"); +// String blockTypeName = split[0]; +//// double chance = split.length > 1 ? Double.parseDouble(split[1]) : 0; +//// long blockCount = split.length > 2 ? Long.parseLong(split[2]) : 0; +//// int constraintMin = split.length > 3 ? Integer.parseInt(split[3]) : 0; +//// int constraintMax = split.length > 4 ? Integer.parseInt(split[4]) : 0; +// +// if ( blockTypeName != null && !validateBlockNames.contains( blockTypeName )) { +// // Use the BlockType.name() load the block type: +// ObsoleteBlockType blockType = ObsoleteBlockType.getBlock(blockTypeName); +// if ( blockType != null ) { +// +// /** +// *

The following is code to correct the use of items being used as a +// * block in a mine, which will cause a failure in trying to place an +// * item as a block. +// *

+// * +// *

This is intended for the old block model and is temp code to ensure +// * that there are less errors the end user will experience. +// *

+// */ +// String errorMessage = "Warning! An invalid block type of %s was " + +// "detect when loading blocks for " + +// "mine %s. %s is not a valid block type. Using " + +// "%s instead. If this is incorrect please fix manually."; +// +// if ( blockType == ObsoleteBlockType.REDSTONE ) { +// ObsoleteBlockType itemType = blockType; +// blockType = ObsoleteBlockType.REDSTONE_ORE; +// +// Output.get().logError( +// String.format( errorMessage, itemType.name(), getName(), +// "Redstone dust", blockType.name()) ); +// +// dirty = true; +// } +// else if ( blockType == ObsoleteBlockType.NETHER_BRICK ) { +// ObsoleteBlockType itemType = blockType; +// blockType = ObsoleteBlockType.DOUBLE_NETHER_BRICK_SLAB; +// +// Output.get().logError( +// String.format( errorMessage, itemType.name(), getName(), +// "Individual nether brick", blockType.name()) ); +// +// dirty = true; +// } +// +// BlockOld block = new BlockOld(blockType); +// +// block.parseFromSaveFileFormatStats( docBlock ); +// +// totalBlockCount += block.getBlockCountTotal(); +// +// getBlocks().add(block); +// } +// else { +// String message = String.format( "Failure in loading block type from %s mine's " + +// "save file. Block type %s has no mapping.", getName(), +// blockTypeName ); +// Output.get().logError( message ); +// } +// +// validateBlockNames.add( blockTypeName ); +// } +// else if (validateBlockNames.contains( blockTypeName ) ) { +// // Detected and fixed a duplication so mark as dirty so fixed block list is saved: +// dirty = true; +// inconsistancy = true; +// } +// } +// +// } // Reset validation checks: @@ -552,38 +553,38 @@ else if ( validateBlockNames.contains( prisonBlock.getBlockName() ) ) { // Using the Obsolete old block model for conversion to the new block model // NOTE: This is the ONLY place were we are allowed to use the old block model! ;) - if ( // isUseNewBlockModel() && - getPrisonBlocks().size() == 0 && getBlocks().size() > 0 ) { - // Need to perform the initial conversion: - - for ( BlockOld blockOld : getBlocks() ) { - PrisonBlock prisonBlock = Prison.get().getPlatform().getPrisonBlock( blockOld.getType().name() ); - - if ( prisonBlock == null ) { - for ( String altName : blockOld.getType().getXMaterialAltNames() ) { - - prisonBlock = Prison.get().getPlatform().getPrisonBlock( altName ); - if ( prisonBlock != null ) { - break; - } - } - } - - if ( prisonBlock != null ) { - - // This transfers all the stats over so none are lost. - prisonBlock.transferStats( blockOld ); - - addPrisonBlock( prisonBlock ); - - dirty = true; - } - - } - - Output.get().logInfo( "Notice: Mine: " + getName() + ": Existing prison block model has " + - "been converted to the new block model and will be saved." ); - } +// if ( // isUseNewBlockModel() && +// getPrisonBlocks().size() == 0 && getBlocks().size() > 0 ) { +// // Need to perform the initial conversion: +// +// for ( BlockOld blockOld : getBlocks() ) { +// PrisonBlock prisonBlock = Prison.get().getPlatform().getPrisonBlock( blockOld.getType().name() ); +// +// if ( prisonBlock == null ) { +// for ( String altName : blockOld.getType().getXMaterialAltNames() ) { +// +// prisonBlock = Prison.get().getPlatform().getPrisonBlock( altName ); +// if ( prisonBlock != null ) { +// break; +// } +// } +// } +// +// if ( prisonBlock != null ) { +// +// // This transfers all the stats over so none are lost. +// prisonBlock.transferStats( blockOld ); +// +// addPrisonBlock( prisonBlock ); +// +// dirty = true; +// } +// +// } +// +// Output.get().logInfo( "Notice: Mine: " + getName() + ": Existing prison block model has " + +// "been converted to the new block model and will be saved." ); +// } List commands = (List) document.get("commands"); @@ -712,20 +713,20 @@ public Document toDocument() { // This is the ONLY SECOND place where we can use the old block model! // We want to "preserve" the old blocks that may have been setup up in the mines // originally. In a future release, these may be purged. - List blockStrings = new ArrayList<>(); - for (BlockOld block : getBlocks()) { - if ( !validateBlockNames.contains( block.getType().name() )) { - - blockStrings.add( block.toSaveFileFormat() ); - - // // Use the BlockType.name() to save the block type to the file: - // blockStrings.add(block.getType().name() + "-" + block.getChance()); - // blockStrings.add(block.getType().getId() + "-" + block.getChance()); - validateBlockNames.add( block.getType().name() ); - } - } - - ret.put("blocks", blockStrings); +// List blockStrings = new ArrayList<>(); +// for (BlockOld block : getBlocks()) { +// if ( !validateBlockNames.contains( block.getType().name() )) { +// +// blockStrings.add( block.toSaveFileFormat() ); +// +// // // Use the BlockType.name() to save the block type to the file: +// // blockStrings.add(block.getType().name() + "-" + block.getChance()); +// // blockStrings.add(block.getType().getId() + "-" + block.getChance()); +// validateBlockNames.add( block.getType().name() ); +// } +// } + +// ret.put("blocks", blockStrings); // reset validation for next block list: validateBlockNames.clear(); diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineData.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineData.java index bde6b8f67..860ac92c2 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineData.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineData.java @@ -645,16 +645,16 @@ public void resetUnsavedBlockCounts() { public void resetResetBlockCounts() { - for ( PrisonBlockStatusData block : getBlocks() ) { - - // Reset the block count for the reset event since the mine will be regenerated: - block.setBlockPlacedCount( 0 ); - block.setRangeBlockCountLow( -1 ); - block.setRangeBlockCountHigh( -1 ); - block.setRangeBlockCountLowLimit( -1 ); - block.setRangeBlockCountHighLimit( -1 ); - // block.setIncludeInLayerCalculations( true ); - } +// for ( PrisonBlockStatusData block : getBlocks() ) { +// +// // Reset the block count for the reset event since the mine will be regenerated: +// block.setBlockPlacedCount( 0 ); +// block.setRangeBlockCountLow( -1 ); +// block.setRangeBlockCountHigh( -1 ); +// block.setRangeBlockCountLowLimit( -1 ); +// block.setRangeBlockCountHighLimit( -1 ); +// // block.setIncludeInLayerCalculations( true ); +// } for ( PrisonBlockStatusData block : getPrisonBlocks() ) { From 8abb63a6482383ef031133638ba5d029fff2e876 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 6 Mar 2026 12:51:32 -0500 Subject: [PATCH 306/323] Prison Cleanup: prison-core: Removed obsolete and unneeded comments and fix indentation where needed. First part. --- docs/changelog_v3.3.x.md | 3 + .../prison/ranks/data/PlayerRank.java | 111 -- .../tech/mcprison/prison/ranks/data/Rank.java | 251 +--- .../prison/ranks/data/RankLadder.java | 416 ++---- .../prison/ranks/data/RankPlayer.java | 914 +++--------- .../data/StatsRankPlayerBalanceData.java | 3 - .../prison/selection/SelectionListener.java | 1 - .../prison/selection/SelectionManager.java | 10 - .../prison/spatial/CoordinateKey.java | 116 +- .../mcprison/prison/spatial/SpatialIndex.java | 15 +- .../prison/spatial/SpatialIndexData.java | 12 +- .../mcprison/prison/store/Collection.java | 2 - .../prison/tasks/PrisonCommandTaskData.java | 53 - .../prison/tasks/PrisonTaskSubmitter.java | 28 +- .../util/BluesSemanticVersionComparator.java | 10 +- .../tech/mcprison/prison/util/Bounds.java | 97 +- .../tech/mcprison/prison/util/ChatColor.java | 102 +- .../mcprison/prison/util/CollectionUtil.java | 7 - .../mcprison/prison/util/ConversionUtil.java | 2 +- .../util/ExampleJavaDoubleVsBigDecimal.java | 1 - .../mcprison/prison/util/ItemManager.java | 56 +- .../tech/mcprison/prison/util/Location.java | 41 +- .../mcprison/prison/util/MaterialType.java | 13 +- .../mcprison/prison/util/MaterialVersion.java | 27 +- .../prison/util/ObsoleteBlockType.java | 1266 +---------------- .../prison/util/PrisonJarReporter.java | 10 - .../mcprison/prison/util/PrisonStatsUtil.java | 184 ++- .../prison/util/PrisonTPSSingleton.java | 95 +- .../java/tech/mcprison/prison/util/Text.java | 263 ++-- .../tech/mcprison/prison/util/Vector.java | 40 +- 30 files changed, 823 insertions(+), 3326 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 33e246b18..37b0da3d0 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.19j 2026-03-06 +* **Prison Cleanup: prison-core: Removed obsolete and unneeded comments and fix indentation where needed.** First part. + + * **Removed some uses of the old block model. Breaking change: This removal should not actually break anything, but if upgrading from a version using the old block models, upgrade to an earlier release first to take advantage of the automatic conversion.** * **Removed a few other unused source related to the old non-functional troubleshooting.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/ranks/data/PlayerRank.java b/prison-core/src/main/java/tech/mcprison/prison/ranks/data/PlayerRank.java index 96342b3ec..05129e7d3 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/ranks/data/PlayerRank.java +++ b/prison-core/src/main/java/tech/mcprison/prison/ranks/data/PlayerRank.java @@ -20,10 +20,6 @@ protected PlayerRank( Rank rank ) { this.rank = rank; -// double rankMultiplier = getLadderBasedRankMultiplier( rank ); -// -// setRankCost( rankMultiplier ); -//// this.rankCost = rank.getCost() * (1.0 + rankMultiplier); } protected PlayerRank( Rank rank, double rankMultiplier ) { @@ -32,7 +28,6 @@ protected PlayerRank( Rank rank, double rankMultiplier ) { this.rankMultiplier = rankMultiplier; setRankCost( rankMultiplier ); -// this.rankCost = rank.getCost() * (1.0 + rankMultiplier); } @Override @@ -46,7 +41,6 @@ public void applyMultiplier( double rankMultiplier ) { this.rankMultiplier = rankMultiplier; setRankCost( rankMultiplier ); -// this.rankCost = rank.getCost() * (1.0 + rankMultiplier); } protected void setRankCost( double rankMultiplier ) { @@ -80,105 +74,6 @@ public double getLadderBasedRankMultiplier( Rank rank ) { } -// public static double getRawRankCost( Rank rank ) { -// return rank.getCost(); -// } -// public static void setRawRankCost( Rank rank, double rawCost ) { -// rank.setCost( rawCost ); -// } - -// public static PlayerRank getTargetPlayerRankForPlayer( RankPlayer player, Rank targetRank ) { -// PlayerRank targetPlayerRank = null; -// -// if ( targetRank != null ) { -// -// double targetRankMultiplier = getLadderBaseRankdMultiplier( targetRank ); -// -// PlayerRank pRankForPLayer = player.getRank( targetRank.getLadder() ); -// double existingRankMultiplier = pRankForPLayer == null ? 0 : -// getLadderBaseRankdMultiplier( pRankForPLayer.getRank() ); -// -// // Get the player's total rankMultiplier from the default ladder -// // because they will always have a rank there: -// PlayerRank pRank = player.getRank( "default" ); -// double playerMultipler = pRank == null ? 0 : pRank.getRankMultiplier(); -// -// // So the actual rank multiplier that needs to be used, is based upon the -// // Player's current multiplier PLUS the multiplier for the target rank -// // AND MINUS the multiplier for the current rank the player has within the -// // target rank's ladder. -// double rankMultiplier = playerMultipler + targetRankMultiplier - existingRankMultiplier; -// -// targetPlayerRank = new PlayerRank( targetRank, rankMultiplier ); -// } -// -// return targetPlayerRank; -// } - - -// public PlayerRank getTargetPlayerRankForPlayer( RankPlayer player, Rank targetRank ) { -// return getTargetPlayerRankForPlayer( this, player, targetRank ); -// } - -// public PlayerRank getTargetPlayerRankForPlayer( PlayerRank playerRank, RankPlayer player, Rank targetRank ) -// { -// PlayerRank targetPlayerRank = null; -// -// if ( targetRank != null ) -// { -// -// double targetRankMultiplier = playerRank.getLadderBasedRankMultiplier( targetRank ); -// -// -// PlayerRank pRankForPLayer = player.getLadderRanks().get( targetRank.getLadder() ); -// -// // PlayerRank pRankForPLayer = getRank( player, targetRank.getLadder() ); -// double existingRankMultiplier = pRankForPLayer == null ? 0 -// : playerRank.getLadderBasedRankMultiplier( pRankForPLayer.getRank() ); -// -// // Get the player's total rankMultiplier from the default ladder -// // because they will always have a rank there: -// RankLadder defaultLadder = getDefaultLadder( player ); -// -// PlayerRank pRank = player.getLadderRanks().get( defaultLadder ); -//// PlayerRank pRank = getRank( player, "default" ); -// double playerMultipler = pRank == null ? 0 : pRank.getRankMultiplier(); -// -// // So the actual rank multiplier that needs to be used, is based upon -// // the -// // Player's current multiplier PLUS the multiplier for the target rank -// // AND MINUS the multiplier for the current rank the player has within -// // the -// // target rank's ladder. -// double rankMultiplier = playerMultipler + targetRankMultiplier - existingRankMultiplier; -// -// targetPlayerRank = createPlayerRank( targetRank, rankMultiplier ); -// } -// -// return targetPlayerRank; -// } - - -// private RankLadder getDefaultLadder( RankPlayer player ) -// { -// return player.getPlayerRankDefault().getRank().getLadder(); -//// RankLadder defaultLadder = null; -//// -//// for ( RankLadder ladder : player.getLadderRanks().keySet() ) -//// { -//// if ( ladder.getName().equalsIgnoreCase( "default" ) ) { -//// defaultLadder = ladder; -//// } -//// } -//// -//// return defaultLadder; -// } - -// private PlayerRank createPlayerRank( Rank rank, double rankMultiplier ) { -// PlayerRank results = new PlayerRank( rank, rankMultiplier ); -// -// return results; -// } public Rank getRank() { return rank; @@ -194,16 +89,10 @@ public String getCurrency() { public Double getRankMultiplier() { return rankMultiplier; } -// public void setRankMultiplier( Double rankMultiplier ) { -// this.rankMultiplier = rankMultiplier; -// } public Double getRankCost() { return rankCost; } -// public void setRankCost( Double rankCost ) { -// this.rankCost = rankCost; -// } @Override public int compareTo( PlayerRank pr ) 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 2f05c3a23..61d072d58 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 @@ -35,7 +35,7 @@ public class Rank ModuleElement, Comparable { -// // This is to help eliminate RankLadder.PositionRank object: + // This is to help eliminate RankLadder.PositionRank object: private transient int position = -1; // The unique identifier used to distinguish this rank from others - this never changes. @@ -63,11 +63,6 @@ public class Rank private List rankUpCommands; - // permissions in ranks is obsolete and is being removed. It can never work with vault. - // And Access by Ranks replaces this. -// private List permissions; -// private List permissionGroups; - private transient Rank rankPrior; private transient Rank rankNext; @@ -87,31 +82,27 @@ public class Rank public Rank() { - super(); - - this.rankUpCommands = new ArrayList<>(); - - this.mines = new ArrayList<>(); - this.mineStrings = new ArrayList<>(); - -// this.permissions = new ArrayList<>(); -// this.permissionGroups = new ArrayList<>(); - - this.players = new ArrayList<>(); - - this.statsPlayerBlance = new StatsRankPlayerBalance( this ); + super(); + + this.rankUpCommands = new ArrayList<>(); + + this.mines = new ArrayList<>(); + this.mineStrings = new ArrayList<>(); + + this.players = new ArrayList<>(); + + this.statsPlayerBlance = new StatsRankPlayerBalance( this ); } public Rank( int id, String name, String tag, double cost ) { - this(); - -// this.position = position; - - this.id = id; - this.name = name; - this.tag = tag; - this.cost = cost; + this(); + + + this.id = id; + this.name = name; + this.tag = tag; + this.cost = cost; } /** @@ -123,161 +114,12 @@ public Rank( int id, String name, String tag, double cost ) { * @param name */ protected Rank( String name ) { - this(); - -// this.position = 0; - this.id = 0; - this.name = name; + this(); + + this.id = 0; + this.name = name; } -// @SuppressWarnings( "unchecked" ) -// public Rank(Document document) { -// this(); -// -// try -// { -//// Object pos = document.get("position"); -//// this.position = RankUtil.doubleToInt( pos == null ? 0.0d : pos ); -// -// this.id = RankUtil.doubleToInt(document.get("id")); -// this.name = (String) document.get("name"); -// this.tag = (String) document.get("tag"); -// this.cost = (double) document.get("cost"); -// -// String currency = (String) document.get("currency"); -// this.currency = (currency == null || -// "null".equalsIgnoreCase( currency ) ? null : currency); -// -// getRankUpCommands().clear(); -// Object cmds = document.get("commands"); -// if ( cmds != null ) { -// -// List commands = (List) cmds; -// for ( String cmd : commands ) { -// if ( cmd != null ) { -// getRankUpCommands().add( cmd ); -// } -// } -// -// // This was allowing nulls to be added to the live commands... -//// this.rankUpCommands = (List) cmds; -// } -// -// getMines().clear(); -// getMineStrings().clear(); -// Object minesObj = document.get("mines"); -// if ( minesObj != null ) { -// List mineStrings = (List) minesObj; -// setMineStrings( mineStrings ); -// } -// -// -//// getPermissions().clear(); -//// Object perms = document.get( "permissions" ); -//// if ( perms != null ) { -//// List permissions = (List) perms; -//// for ( String permission : permissions ) { -//// getPermissions().add( permission ); -//// } -//// } -//// -//// -//// getPermissionGroups().clear(); -//// Object permsGroups = document.get( "permissionGroups" ); -//// if ( perms != null ) { -//// List permissionGroups = (List) permsGroups; -//// for ( String permissionGroup : permissionGroups ) { -//// getPermissionGroups().add( permissionGroup ); -//// } -//// } -// -// } -// catch ( Exception e ) -// { -// String message = rankFailureLoadingRanksMsg( Integer.toString( this.id ), -// (this.name == null ? "null" : this.name ), -// e.getMessage() ); -// -// Output.get().logError( message ); -// } -// } - -// public Document toDocument() { -// Document ret = new Document(); -//// ret.put("position", this.position ); -// ret.put("id", this.id); -// ret.put("name", this.name); -// ret.put("tag", this.tag); -// ret.put("cost", this.cost); -// ret.put("currency", this.currency); -// -// List cmds = new ArrayList<>(); -// for ( String cmd : getRankUpCommands() ) { -// // Filters out possible nulls: -// if ( cmd != null ) { -// cmds.add( cmd ); -// } -// } -// ret.put("commands", cmds); -// -// List mineStrings = new ArrayList<>(); -// if ( getMines() != null ) { -// for ( ModuleElement mine : getMines() ) { -// String mineString = mine.getModuleElementType() + "," + mine.getName() + "," + -// mine.getId() + "," + mine.getTag(); -// mineStrings.add( mineString ); -// } -// } -// ret.put("mines", mineStrings); -// -//// ret.put( "permissions", getPermissions() ); -//// ret.put( "permissionGroups", getPermissionGroups() ); -// -// return ret; -// } -// - - -// /** -// *

Identifies of the Ladder contains a permission. -// *

-// * -// * @param permission -// * @return -// */ -// public boolean hasPermission( String permission ) { -// boolean results = false; -// -// for ( String perm : getPermissions() ) { -// if ( perm.equalsIgnoreCase( permission ) ) { -// results = true; -// break; -// } -// } -// -// return results; -// } - -// /** -// *

Identifies if the Ladder contains a permission group. -// *

-// * -// * @param permissionGroup -// * @return -// */ -// public boolean hasPermissionGroup( String permissionGroup ) { -// boolean results = false; -// -// for ( String perm : getPermissionGroups() ) { -// if ( perm.equalsIgnoreCase( permissionGroup ) ) { -// results = true; -// break; -// } -// } -// -// return results; -// } - public StatsRankPlayerBalance getStatsPlayerBlance() { return statsPlayerBlance; @@ -313,28 +155,23 @@ public void removePlayer( RankPlayer player ) { @Override public String toString() { - return "Rank: " + id + " " + name; + return "Rank: " + id + " " + name; } public String filenameNew() { - return "rank_" + getName(); + return "rank_" + getName(); } public String filenameOld() { - return getId() == -1 ? null : "rank_" + getId(); + return getId() == -1 ? null : "rank_" + getId(); } public RankLadder getLadder() { -// if ( ladder == null ) { -// -// ladder = PrisonRanks.getInstance().getLadderManager().getLadder( this ); -// } - - return ladder; + return ladder; } public void setLadder( RankLadder ladder ) { - this.ladder = ladder; + this.ladder = ladder; } @@ -360,23 +197,6 @@ public boolean equals(Object o) { // Rank.id is unique and there should never be two with the same rank. return id == rank.id; -// if (id != rank.id) { -// return false; -// } -// if (Double.compare(rank.cost, cost) != 0) { -// return false; -// } -// -// if ( currency != null && rank.currency == null || -// currency != null && rank.currency != null && -// !currency.equals( rank.currency ) ) { -// return false; -// } -// -// if (!name.equals(rank.name)) { -// return false; -// } -// return tag != null ? tag.equals(rank.tag) : rank.tag == null; } @Override @@ -444,9 +264,6 @@ public void resetPosition() { position = -1; } -// public void setPosition( int position ) { -// this.position = position; -// } public int getId() { return id; @@ -508,20 +325,6 @@ public void setRankUpCommands( List rankUpCommands ) { this.rankUpCommands = rankUpCommands; } -// public List getPermissions() { -// return permissions; -// } -// public void setPermissions( List permissions ) { -// this.permissions = permissions; -// } -// -// public List getPermissionGroups() { -// return permissionGroups; -// } -// public void setPermissionGroups( List permissionGroups ) { -// this.permissionGroups = permissionGroups; -// } - public Rank getRankPrior() { return rankPrior; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/ranks/data/RankLadder.java b/prison-core/src/main/java/tech/mcprison/prison/ranks/data/RankLadder.java index 27408f455..f34d64645 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/ranks/data/RankLadder.java +++ b/prison-core/src/main/java/tech/mcprison/prison/ranks/data/RankLadder.java @@ -45,9 +45,6 @@ public class RankLadder -// private int maxPrestige; - - // The commands that are run when this rank is attained. private List rankUpCommands; @@ -59,20 +56,20 @@ public class RankLadder public RankLadder() { - super(); - - this.rankUpCommands = new ArrayList<>(); - - this.ranks = new ArrayList<>(); - - this.applyRankCostMultiplierToLadder = true; + super(); + + this.rankUpCommands = new ArrayList<>(); + + this.ranks = new ArrayList<>(); + + this.applyRankCostMultiplierToLadder = true; } public RankLadder( int id, String name ) { - this(); - - this.id = id; - this.name = name; + this(); + + this.id = id; + this.name = name; } @@ -85,143 +82,18 @@ public boolean isPrestiges() { } -// @SuppressWarnings( "unchecked" ) -// public RankLadder(Document document, PrisonRanks prisonRanks) { -// this(); -// -// boolean isDirty = false; -// -// this.id = ConversionUtil.doubleToInt(document.get("id")); -// this.name = (String) document.get("name"); -// -// RankManager rankManager = prisonRanks.getRankManager(); -// -// if ( rankManager == null ) { -// -// RankMessages rMessages = new RankMessages(); -// rMessages.rankFailureLoadingRankManagerMsg( getName(), getId() ); -// -// return; -// } -// -// List> ranksLocal = -// (List>) document.get("ranks"); -// -// getRankUpCommands().clear(); -// Object cmds = document.get("commands"); -// if ( cmds != null ) { -// -// List commands = (List) cmds; -// for ( String cmd : commands ) { -// if ( cmd != null ) { -// getRankUpCommands().add( cmd ); -// } -// } -// -// // This was allowing nulls to be added to the live commands... -//// this.rankUpCommands = (List) cmds; -// } -// -// -// this.ranks = new ArrayList<>(); -// for (LinkedTreeMap rank : ranksLocal) { -// -// -// // The only real field that is important here is rankId to tie the -// // rank back to this ladder. Name helps clarify the contents of the -// // Ladder file. -// int rRankId = ConversionUtil.doubleToInt((rank.get("rankId"))); -// String rRankName = (String) rank.get( "rankName" ); -// -// Rank rankPrison = rankManager.getRank( rRankId ); -// -// if ( rankPrison != null && rankPrison.getLadder() != null ) { -// -// RankMessages rMessages = new RankMessages(); -// rMessages.rankFailureLoadingDuplicateRankMsg( -// rankPrison.getName(), rankPrison.getLadder().getName(), -// getName() ); -// -// isDirty = true; -// } -// else if ( rankPrison != null) { -// -// addRank( rankPrison ); -// -//// Output.get().logInfo( "RankLadder load : " + getName() + -//// " rank= " + rankPrison.getName() + " " + rankPrison.getId() + -//// ); -// -//// // if null look it up from loaded ranks: -//// if ( rRankName == null ) { -//// rRankName = rankPrison.getName(); -//// dirty = true; -//// } -// } -// else { -// // Rank not found. Try to create it? The name maybe wrong. -// String rankName = rRankName != null && !rRankName.trim().isEmpty() ? -// rRankName : "Rank " + rRankId; -// -// // NOTE: The following is valid use of getCost(): -// double cost = getRanks().size() == 0 ? 0 : -// getRanks().get( getRanks().size() - 1 ).getCost() * 3; -// Rank newRank = new Rank( rRankId, rankName, null, cost ); -// -// addRank( newRank ); -// -//// String message = String.format( -//// "Loading RankLadder Error: A rank for %s was not found so it was " + -//// "fabricated: %s id=%d tag=%s cost=%d", getName(), newRank.getName(), newRank.getId(), -//// newRank.getTag(), newRank.getCost() ); -//// Output.get().logError( message ); -// } -// -// } -// -//// this.maxPrestige = RankUtil.doubleToInt(document.get("maxPrestige")); -// -// -// Double rankCostMultiplier = (Double) document.get( "rankCostMultiplierPerRank" ); -// setRankCostMultiplierPerRank( rankCostMultiplier == null ? 0 : rankCostMultiplier ); -// -// -//// getPermissions().clear(); -//// Object perms = document.get( "permissions" ); -//// if ( perms != null ) { -//// List permissions = (List) perms; -//// for ( String permission : permissions ) { -//// getPermissions().add( permission ); -//// } -//// } -//// -//// -//// getPermissionGroups().clear(); -//// Object permsGroups = document.get( "permissionGroups" ); -//// if ( perms != null ) { -//// List permissionGroups = (List) permsGroups; -//// for ( String permissionGroup : permissionGroups ) { -//// getPermissionGroups().add( permissionGroup ); -//// } -//// } -// -// if ( isDirty ) { -// PrisonRanks.getInstance().getLadderManager().save( this ); -// } -// -// } public Document toDocument() { Document ret = new Document(); if ( this.id != -1 ) { - ret.put("id", this.id); + ret.put("id", this.id); } ret.put("name", this.name); List cmds = new ArrayList<>(); for ( String cmd : getRankUpCommands() ) { - // Filters out possible nulls: + // Filters out possible nulls: if ( cmd != null ) { cmds.add( cmd ); } @@ -232,51 +104,39 @@ public Document toDocument() { List> ranksLocal = new ArrayList>(); for ( Rank rank : getRanks() ) { - LinkedTreeMap rnk = new LinkedTreeMap(); - -// rnk.put( "position", rank.getPosition() ); - - // Do not save the rank ID in the ladder file: -// if ( rank.getId() != -1 ) { -// rnk.put( "rankId", rank.getId() ); -// } - - rnk.put( "rankName", rank.getName()); - - ranksLocal.add( rnk ); + LinkedTreeMap rnk = new LinkedTreeMap(); + + + rnk.put( "rankName", rank.getName()); + + ranksLocal.add( rnk ); } ret.put("ranks", ranksLocal); -// ret.put("ranks", this.ranks); ret.put( "rankCostMultiplierPerRank", getRankCostMultiplierPerRank() ); ret.put( "applyRankCostMultiplierToLadder", isApplyRankCostMultiplierToLadder() ); -// ret.put("maxPrestige", this.maxPrestige); - -// ret.put( "permissions", getPermissions() ); -// ret.put( "permissionGroups", getPermissionGroups() ); - return ret; } @Override public String toString() { - return "Ladder: " + name + " ranks: " + (ranks == null ? 0 : ranks.size()); + return "Ladder: " + name + " ranks: " + (ranks == null ? 0 : ranks.size()); } public List getRanks() { - return ranks; + return ranks; } @Override public int compareTo( RankLadder rl ) { - int results = -1; - if ( rl != null ) { - results = getName().compareTo( rl.getName() ); - } + int results = -1; + if ( rl != null ) { + results = getName().compareTo( rl.getName() ); + } return results; } @@ -289,16 +149,16 @@ public int compareTo( RankLadder rl ) * @return */ public Rank getRank( String rank ) { - Rank results = null; - - for ( Rank r : ranks ) { + Rank results = null; + + for ( Rank r : ranks ) { if ( r.getName().equalsIgnoreCase( rank ) ) { results = r; break; } } - return results; + return results; } @@ -311,19 +171,19 @@ public Rank getRank( String rank ) { * @return */ public Rank getRank( int rankId ) { - Rank results = null; - - if ( rankId != -1 ) { - - for ( Rank r : ranks ) { - if ( r.getId() != -1 && r.getId() == rankId ) { - results = r; - break; - } - } - } - - return results; + Rank results = null; + + if ( rankId != -1 ) { + + for ( Rank r : ranks ) { + if ( r.getId() != -1 && r.getId() == rankId ) { + results = r; + break; + } + } + } + + return results; } /** @@ -335,17 +195,17 @@ public Rank getRank( int rankId ) { */ public void addRank(int position, Rank rank) { - if ( position < 0 ) { - position = 0; - } - else if ( position > getRanks().size() ) { - getRanks().add( rank ); - } - else { - getRanks().add( position, rank ); - } - - rank.setLadder( this ); + if ( position < 0 ) { + position = 0; + } + else if ( position > getRanks().size() ) { + getRanks().add( rank ); + } + else { + getRanks().add( position, rank ); + } + + rank.setLadder( this ); // Update the rank positions along with next and prior: connectRanks(); @@ -362,33 +222,27 @@ else if ( position > getRanks().size() ) { * @param rank The {@link Rank} to add. */ public void addRank(Rank rank) { -// int position = getRanks().size(); -// rank.setPosition( position ); - rank.setLadder( this ); - - getRanks().add( rank ); - - // Update the rank positions along with next and prior: - connectRanks(); - -// ranks.add(new PositionRank(getNextAvailablePosition(), rank.getId(), rank.getName(), rank)); - -// // Reset the rank relationships: -// PrisonRanks.getInstance().getRankManager().connectRanks(); + rank.setLadder( this ); + + getRanks().add( rank ); + + // Update the rank positions along with next and prior: + connectRanks(); + } public void removeRank( Rank rank ) { - boolean success = getRanks().remove( rank ); - - if ( success ) { - rank.setLadder( null ); - - // Update the rank positions along with next and prior: - connectRanks(); - } + boolean success = getRanks().remove( rank ); + + if ( success ) { + rank.setLadder( null ); + + // Update the rank positions along with next and prior: + connectRanks(); + } } /** @@ -405,52 +259,29 @@ public void removeRank( Rank rank ) { */ private void connectRanks() { - Rank rankLast = null; - - // The inserted rank may not be at the end of ranks, so go through all ranks and - // update their position value: - for ( int i = 0; i < getRanks().size(); i++ ) { - Rank rank = getRanks().get( i ); - - rank.resetPosition(); - -// if ( rank.getPosition() != i ) { -// rank.setPosition( i ); -// } - - // reset the rankPrior and rankNext in case there are no hookups: - // Important if ranks are removed, or inserted, or moved: - rank.setRankPrior( null ); - rank.setRankNext( null ); - - if ( rankLast != null ) { - rank.setRankPrior( rankLast ); - rankLast.setRankNext( rank ); - } - rankLast = rank; - -// String message = "Ladder " + getName() + " " + rank.getName() + -// " position=" + rank.getPosition(); -// Output.get().logInfo( message ); - } + Rank rankLast = null; + + // The inserted rank may not be at the end of ranks, so go through all ranks and + // update their position value: + for ( int i = 0; i < getRanks().size(); i++ ) { + Rank rank = getRanks().get( i ); + + rank.resetPosition(); + + // reset the rankPrior and rankNext in case there are no hookups: + // Important if ranks are removed, or inserted, or moved: + rank.setRankPrior( null ); + rank.setRankNext( null ); + + if ( rankLast != null ) { + rank.setRankPrior( rankLast ); + rankLast.setRankNext( rank ); + } + rankLast = rank; + + } } -// /** -// * Orders the ranks in the rank list of this ladder by their position, in ascending order. -// */ -// public void orderRanksByPosition() { -// -// // Do not sort here: -// //The ranks within a ladder will be sorted within the function connectRanks(): -// //ranks.sort(Comparator.comparingInt(PositionRank::getPosition)); -// -// // Reset the rank relationships: -// PrisonRanks.getInstance().getRankManager().connectRanks(); -// } - - /* - * Getters & Setters - */ /** * Returns true if this ladder contains the Rank. @@ -459,7 +290,7 @@ private void connectRanks() { * @return True if the rank was found, false otherwise. */ public boolean containsRank( Rank rank ) { - return ranks.contains( rank ); + return ranks.contains( rank ); } // This next method is sort of precautionary. Sure, positions start at 0, but if the user decides @@ -473,19 +304,13 @@ public boolean containsRank( Rank rank ) { * @return The rank option, or an empty optional if there are no ranks in this ladder. */ public Optional getLowestRank() { - Rank results = null; - - if ( getRanks().size() > 0 ) { - results = getRanks().get( 0 ); - } - -// for ( Rank r : getRanks() ) { -// if ( results == null || r.getPosition() < results.getPosition() ) { -// results = r; -// } -// } - - return results == null ? Optional.empty() : Optional.of( results ); + Rank results = null; + + if ( getRanks().size() > 0 ) { + results = getRanks().get( 0 ); + } + + return results == null ? Optional.empty() : Optional.of( results ); } @@ -510,47 +335,6 @@ public int hashCode() { return result; } - - -// /** -// *

Identifies of the Ladder contains a permission. -// *

-// * -// * @param permission -// * @return -// */ -// public boolean hasPermission( String permission ) { -// boolean results = false; -// -// for ( String perm : getPermissions() ) { -// if ( perm.equalsIgnoreCase( permission ) ) { -// results = true; -// break; -// } -// } -// -// return results; -// } - -// /** -// *

Identifies if the Ladder contains a permission group. -// *

-// * -// * @param permissionGroup -// * @return -// */ -// public boolean hasPermissionGroup( String permissionGroup ) { -// boolean results = false; -// -// for ( String perm : getPermissionGroups() ) { -// if ( perm.equalsIgnoreCase( permissionGroup ) ) { -// results = true; -// break; -// } -// } -// -// return results; -// } public int getId() { return id; @@ -566,12 +350,6 @@ public void setName( String name ) { this.name = name; } -// public int getMaxPrestige() { -// return maxPrestige; -// } -// public void setMaxPrestige( int maxPrestige ) { -// this.maxPrestige = maxPrestige; -// } public List getRankUpCommands() { if ( rankUpCommands == null ) { 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 28157e75e..bf1b80b75 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 @@ -57,18 +57,9 @@ public class RankPlayer public static final long DELAY_THREE_SECONDS = 20 * 3; // 3 seconds in ticks - // The cooldown time for when the rank score will be recalculated -// public static final long RANK_SCORE_COOLDOWN_MS = 1000 * 60 * 5; // 5 minutes -// public static final double RANK_SCORE_BALANCE_THRESHOLD_PERCENT = 0.05d; // 5% - - - /* - * Fields & Constants - */ private UUID uid; - private Player platformPlayer; private long platformPlayerTimestamp = -1L; @@ -99,13 +90,9 @@ public class RankPlayer // ranks is the storage structure used to save the player's ladder & ranks: private HashMap ranksRefs; // - // This prestige is not used. Current prestige is just another ladder. - //private HashMap prestige; // private List names; -// // Block name, count -// private HashMap blocksMined; // For tops processing. Need current balance. @@ -118,7 +105,6 @@ public class RankPlayer private Object unsavedBalanceLock = new Object(); private int ubTaskId = 0; -// private HashMap economyCustom = new HashMap<>();; @@ -134,9 +120,6 @@ public class RankPlayer private double rankScoreBalance = 0; private String rankScoreCurrency = null; -// private double rankScoreBalanceThreshold = 0; -// private long rankScoreCooldown = 0L; - private long economyCacheUpdateDelayTicks = -1; @@ -154,14 +137,11 @@ public class RankPlayer public RankPlayer() { - super(); - - this.ladderRanks = new TreeMap<>(); + super(); + + this.ladderRanks = new TreeMap<>(); this.ranksRefs = new HashMap<>(); - //this.prestige = new HashMap<>(); - -// this.blocksMined = new HashMap<>(); this.playerBalances = new TreeMap<>(); @@ -177,116 +157,41 @@ public RankPlayer() { } public RankPlayer( UUID uid ) { - this(); - - this.uid = uid; + this(); + + this.uid = uid; } public RankPlayer( UUID uid, String playerName ) { - this( uid ); - - checkName( playerName ); + this( uid ); + + checkName( playerName ); } -// public RankPlayer clone() { -// RankPlayer clone = new RankPlayer( getUUID() ); -// -// clone.setBalance( getBalance() ); -// -// Set keys = getLadderRanks().keySet(); -// for (RankLadder key : keys) { -// -// clone.ladderRanks.put( key, getLadderRanks().get( key ) ); -// } -// -// return clone; -// } - -// @SuppressWarnings( "unchecked" ) -// public RankPlayer(Document document) { -// this(); -// -// this.uid = UUID.fromString((String) document.get("uid")); -// LinkedTreeMap ranksLocal = -// (LinkedTreeMap) document.get("ranks"); -//// LinkedTreeMap prestigeLocal = -//// (LinkedTreeMap) document.get("prestige"); -// -// LinkedTreeMap blocksMinedLocal = -// (LinkedTreeMap) document.get("blocksMined"); -// -// Object namesListObject = document.get( "names" ); -// -// -// for (String key : ranksLocal.keySet()) { -// ranksRefs.put(key, ConversionUtil.doubleToInt(ranksLocal.get(key))); -// } -// -//// for (String key : prestigeLocal.keySet()) { -//// prestige.put(key, RankUtil.doubleToInt(prestigeLocal.get(key))); -//// } -// -// this.blocksMined = new HashMap<>(); -// if ( blocksMinedLocal != null ) { -// for (String key : blocksMinedLocal.keySet()) { -// blocksMined.put(key, ConversionUtil.doubleToInt(blocksMinedLocal.get(key))); -// } -// } -// -// if ( namesListObject != null ) { -// -// for ( Object rankPlayerNameMap : (ArrayList) namesListObject ) { -// LinkedTreeMap rpnMap = (LinkedTreeMap) rankPlayerNameMap; -// -// if ( rpnMap.size() > 0 ) { -// String name = (String) rpnMap.get( "name" ); -// long date = ConversionUtil.doubleToLong( rpnMap.get( "date" ) ); -// -// RankPlayerName rankPlayerName = new RankPlayerName( name, date ); -// getNames().add( rankPlayerName ); -//// Output.get().logInfo( "RankPlayer: uuid: " + uid + " RankPlayerName: " + rankPlayerName.toString() ); -// } -// -// } -// } -// -// } -// -// public Document toDocument() { -// Document ret = new Document(); -// ret.put("uid", this.uid); -// ret.put("ranks", this.ranksRefs); -//// ret.put("prestige", this.prestige); -// -// ret.put("names", this.names); -// -// ret.put("blocksMined", this.blocksMined); -// return ret; -// } -// + @Override public String toString() { - return getName() + " " + getRanks(); + return getName() + " " + getRanks(); } public String getRanks() { - StringBuilder sb = new StringBuilder(); - - for ( PlayerRank rank : getLadderRanks().values() ) { - + StringBuilder sb = new StringBuilder(); + + for ( PlayerRank rank : getLadderRanks().values() ) { + sb.append( rank.getRank().getLadder() == null ? "--" : rank.getRank().getLadder().getName() ) .append( ":" ).append( rank.getRank().getName() ).append( " " ); } - - return sb.toString(); + + return sb.toString(); } public UUID getUUID() { - return uid; + return uid; } /** @@ -419,15 +324,15 @@ public void setDirty(boolean dirty) { * a null. */ public String getDisplayName() { - return getLastName(); + return getLastName(); } public void setDisplayName(String newDisplayName) { - checkName( newDisplayName ); + checkName( newDisplayName ); } public boolean isOnline() { - return false; + return false; } /** @@ -441,55 +346,49 @@ public boolean isOnline() { * @return */ public boolean checkName( String playerName ) { - boolean added = false; - - // If the playerName is not valid, don't try to add it: - if ( playerName != null && playerName.trim().length() > 0 && - !"CONSOLE".equalsIgnoreCase( playerName ) ) { - - String name = getLastName(); - - // Check if the last name in the list is not the same as the name passed: - if ( name == null || - name != null && !name.equalsIgnoreCase( playerName ) ) { - - RankPlayerName rpn = new RankPlayerName( playerName, System.currentTimeMillis() ); - getNames().add( rpn ); - - dirty = true; - - added = true; - } - } - - return added; + boolean added = false; + + // If the playerName is not valid, don't try to add it: + if ( playerName != null && playerName.trim().length() > 0 && + !"CONSOLE".equalsIgnoreCase( playerName ) ) { + + String name = getLastName(); + + // Check if the last name in the list is not the same as the name passed: + if ( name == null || + name != null && !name.equalsIgnoreCase( playerName ) ) { + + RankPlayerName rpn = new RankPlayerName( playerName, System.currentTimeMillis() ); + getNames().add( rpn ); + + dirty = true; + + added = true; + } + } + + return added; } private String getLastName() { - String name = getNames().size() == 0 ? - null : - getNames().get( getNames().size() - 1 ).getName(); - - return name; + String name = getNames().size() == 0 ? + null : + getNames().get( getNames().size() - 1 ).getName(); + + return name; } public List getNames() { - if ( names == null ) { - names = new ArrayList<>(); - } + if ( names == null ) { + names = new ArrayList<>(); + } return names; } public void setNames( List names ) { this.names = names; } -// public HashMap getBlocksMined() { -// return blocksMined; -// } -// public void setBlocksMined( HashMap blocksMined ) { -// this.blocksMined = blocksMined; -// } /** @@ -509,7 +408,7 @@ public void setNames( List names ) { */ public String getPlayerFileName() { - return filenamePlayer(); + return filenamePlayer(); } @@ -542,56 +441,15 @@ public void setFileCache(File fileCache) { */ public String filenamePlayer() { - return getFilePlayer().getName(); -// return JsonFileIO.filenamePlayer( this ); + return getFilePlayer().getName(); } public String filenameCache() { - return getFileCache().getName(); -// return JsonFileIO.filenameCache( this ); + return getFileCache().getName(); } -// /** -// *

This function will check to see if the player is on the default rank on -// * the default ladder. If not, then it will add them. -// *

-// * -// *

This is safe to run on anyone, even if they already are on the default ladder. -// *

-// * -// *

Note, this will not save the player's new rank. The save function must be -// * managed and called outside of this. -// *

-// */ -// public void firstJoin() { -// -// RankLadder defaultLadder = PrisonRanks.getInstance().getDefaultLadder(); -// -// if ( !getLadderRanks().containsKey( defaultLadder ) ) { -// -// Optional firstRank = defaultLadder.getLowestRank(); -// -// if ( firstRank.isPresent() ) { -// Rank rank = firstRank.get(); -// -// addRank( rank ); -// -// Prison.get().getEventBus().post(new FirstJoinEvent( this )); -// -// FirstJoinHandlerMessages messages = new FirstJoinHandlerMessages(); -// Output.get().logWarn( messages.firstJoinSuccess( getName() ) ); -// -// } else { -// -// FirstJoinHandlerMessages messages = new FirstJoinHandlerMessages(); -// Output.get().logWarn( messages.firstJoinWarningNoRanksOnServer() ); -// } -// } -// -// } - /** * Add a rank to this player. * If a rank on this ladder is already attached, it will automatically be removed and replaced with this new one. @@ -601,7 +459,7 @@ public String filenameCache() */ public void addRank( Rank rank) { if ( rank.getLadder() == null ) { - throw new IllegalArgumentException("Rank must be on ladder."); + throw new IllegalArgumentException("Rank must be on ladder."); } String ladderName = rank.getLadder().getName(); @@ -613,11 +471,11 @@ public void addRank( Rank rank) { if ( ladderRanks.containsKey( rank.getLadder() ) ) { - // Remove the player from the old rank: - PlayerRank oldRank = ladderRanks.get( rank.getLadder() ); - oldRank.getRank().getPlayers().remove( this ); - - ladderRanks.remove( rank.getLadder() ); + // Remove the player from the old rank: + PlayerRank oldRank = ladderRanks.get( rank.getLadder() ); + oldRank.getRank().getPlayers().remove( this ); + + ladderRanks.remove( rank.getLadder() ); } ranksRefs.put(ladderName, rank.getId()); @@ -643,9 +501,9 @@ public void addRank( Rank rank) { * @return */ public PlayerRank createPlayerRank( Rank rank ) { - PlayerRank pRank = new PlayerRank( rank, 1.0 ); - - return pRank; + PlayerRank pRank = new PlayerRank( rank, 1.0 ); + + return pRank; } /** @@ -657,7 +515,7 @@ public PlayerRank createPlayerRank( Rank rank ) { */ public void recalculateRankMultipliers() { - recalculateRankMultipliers( getLadderRanks() ); + recalculateRankMultipliers( getLadderRanks() ); } @@ -675,25 +533,24 @@ public void recalculateRankMultipliers() { */ public void recalculateRankMultipliers( TreeMap targetLadderRanks ) { - double multiplier = 0; - - // First gather and calculate the multipliers: - Set keys = targetLadderRanks.keySet(); - for ( RankLadder rankLadder : keys ) - { - PlayerRank pRank = targetLadderRanks.get( rankLadder ); - - double rankMultiplier = pRank.getLadderBasedRankMultiplier(); - multiplier += rankMultiplier; + double multiplier = 0; + + // First gather and calculate the multipliers: + Set keys = targetLadderRanks.keySet(); + for ( RankLadder rankLadder : keys ) + { + PlayerRank pRank = targetLadderRanks.get( rankLadder ); + + double rankMultiplier = pRank.getLadderBasedRankMultiplier(); + multiplier += rankMultiplier; } - - // We now have the multipliers, so apply them to all ranks: - for ( RankLadder rankLadder : keys ) - { - PlayerRank pRank = targetLadderRanks.get( rankLadder ); - - pRank.applyMultiplier( multiplier ); -// pRank.setRankCost( pRank.getRank().getCost() * (1.0 + multiplier) ); + + // We now have the multipliers, so apply them to all ranks: + for ( RankLadder rankLadder : keys ) + { + PlayerRank pRank = targetLadderRanks.get( rankLadder ); + + pRank.applyMultiplier( multiplier ); } } @@ -711,43 +568,43 @@ public void recalculateRankMultipliers( * @return */ public PlayerRank calculateTargetPlayerRank( Rank targetRank ) { - PlayerRank targetPlayerRank = null; - - // Can only process if the target rank is not null and it has a ladder: - if ( targetRank != null && targetRank.getLadder() != null ) { - - // Need to get the targetRank's ladder. Not all ranks have ladders. - RankLadder targetLadder = targetRank.getLadder(); - - // Create a new PlayerRank object for this target rank. - // Ignore rank cost multipliers since that will be applied later. - targetPlayerRank = new PlayerRank( targetRank ); - - // Create a new temp targetLadderRanks TreeMap: - TreeMap targetLadderRanks = new TreeMap<>(); - - // Copy the player's actual ladderRanks to the targetLadderRanks: - Set keys = getLadderRanks().keySet(); - for (RankLadder key : keys) { - PlayerRank pRank = getLadderRanks().get( key ); - - targetLadderRanks.put( key, pRank ); - } - - // Now add our targetPlayerRank to the targetLadderRanks: - targetLadderRanks.put( targetLadder, targetPlayerRank ); - - - // Now recalculate all multipliers and the rank costs for the targetPlayerRank: - recalculateRankMultipliers( targetLadderRanks ); - - } - - // The targetPlayerRank now has the correct total multiplier from all - // ladders, and it's Rank Cost is based upon those multipliers and if - // the ladder should apply the multipliers or not: - - return targetPlayerRank; + PlayerRank targetPlayerRank = null; + + // Can only process if the target rank is not null and it has a ladder: + if ( targetRank != null && targetRank.getLadder() != null ) { + + // Need to get the targetRank's ladder. Not all ranks have ladders. + RankLadder targetLadder = targetRank.getLadder(); + + // Create a new PlayerRank object for this target rank. + // Ignore rank cost multipliers since that will be applied later. + targetPlayerRank = new PlayerRank( targetRank ); + + // Create a new temp targetLadderRanks TreeMap: + TreeMap targetLadderRanks = new TreeMap<>(); + + // Copy the player's actual ladderRanks to the targetLadderRanks: + Set keys = getLadderRanks().keySet(); + for (RankLadder key : keys) { + PlayerRank pRank = getLadderRanks().get( key ); + + targetLadderRanks.put( key, pRank ); + } + + // Now add our targetPlayerRank to the targetLadderRanks: + targetLadderRanks.put( targetLadder, targetPlayerRank ); + + + // Now recalculate all multipliers and the rank costs for the targetPlayerRank: + recalculateRankMultipliers( targetLadderRanks ); + + } + + // The targetPlayerRank now has the correct total multiplier from all + // ladders, and it's Rank Cost is based upon those multipliers and if + // the ladder should apply the multipliers or not: + + return targetPlayerRank; } /** @@ -757,168 +614,41 @@ public PlayerRank calculateTargetPlayerRank( Rank targetRank ) { * @param rank The The {@link Rank} to remove. */ public void removeRank(Rank rank) { - - if ( rank != null && rank.getLadder() != null ) { - - ladderRanks.remove( rank.getLadder() ); - - ranksRefs.remove( rank.getLadder().getName() ); - } + + if ( rank != null && rank.getLadder() != null ) { + + ladderRanks.remove( rank.getLadder() ); + + ranksRefs.remove( rank.getLadder().getName() ); + } -// // When we loop through, we have to store our ladder name outside the loop to -// // avoid a concurrent modification exception. So, we'll retrieve the data we need... -// String ladderName = null; -// for (Map.Entry rankEntry : ranksRefs.entrySet()) { -// if (rankEntry.getValue() == rank.getId()) { // This is our rank! -// ladderName = rankEntry.getKey(); -// } -// } -// -// // ... and then remove it! -// ranksRefs.remove(ladderName); -// -// ladderRanks.remove( rank.getLadder() ); } public boolean hasLadder( String ladderName ) { - boolean results = false; - - Set ladders = getLadderRanks().keySet(); - - for (RankLadder ladder : ladders) { - if ( ladderName != null && ladder.getName().equalsIgnoreCase(ladderName) ) { - results = true; - break; + boolean results = false; + + Set ladders = getLadderRanks().keySet(); + + for (RankLadder ladder : ladders) { + if ( ladderName != null && ladder.getName().equalsIgnoreCase(ladderName) ) { + results = true; + break; + } } - } - - return results; -// return ranksRefs.containsKey( ladderName ); + + return results; } -// /** -// * Removes a ladder from this player, including whichever rank this player had in it. -// * Cannot remove the default ladder. -// * -// * @param ladderName The ladder's name. -// */ -// public boolean removeLadder(String ladderName) { -// boolean results = false; -// if ( !ladderName.equalsIgnoreCase("default") ) { -// Integer id = ranksRefs.remove(ladderName); -// results = (id != null); -// -// RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder( ladderName ); -// if ( ladder != null && !ladder.getName().equalsIgnoreCase( "default" ) ) { -// ladderRanks.remove( ladder ); -// } -// } -// -// return results; -// } - -// /** -// * Retrieves the rank that this player has in a certain ladder, if any. -// * -// * @param ladder The ladder to check. -// * @return An optional containing the {@link Rank} if found, or empty if there isn't a rank by that ladder for this player. -// */ -// public PlayerRank getRank(RankLadder ladder) { -// PlayerRank results = null; -// -// if ( ladder != null ) { -// -// Set keys = ladderRanks.keySet(); -// for ( RankLadder key : keys ) -// { -// if ( key != null && key.getName().equalsIgnoreCase( ladder.getName() ) ) { -// results = ladderRanks.get( key ); -// } -// } -// } -// -// return results; -// -//// if (!ranksRefs.containsKey(ladder.getName())) { -//// return null; -//// } -//// int id = ranksRefs.get(ladder.getName()); -//// return PrisonRanks.getInstance().getRankManager().getRank(id); -// } -// -// /** -// * Retrieves the rank that this player has the specified ladder. -// * -// * @param ladder The ladder name to check. -// * @return The {@link Rank} if found, otherwise null; -// */ -// public PlayerRank getRank( String ladderName ) { -// -// RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder( ladderName ); -// return getRank( ladder ); -// -//// Rank results = null; -//// if (ladder != null && ranksRefs.containsKey(ladder)) { -//// int id = ranksRefs.get(ladder); -//// results = PrisonRanks.getInstance().getRankManager().getRank(id); -//// } -//// return results; -// } - - -// public HashMap getPrestige() { -// return prestige; -// } -// public void setPrestige( HashMap prestige ) { -// this.prestige = prestige; -// } public void setRanks( HashMap ranks ) { this.ranksRefs = ranks; } -// /** -// * Returns all ladders this player is a part of, along with each rank the player has in that ladder. -// * -// * @return The map containing this data. -// */ -// public Map getLadderRanks( RankPlayer rankPlay) { -// -// if ( ladderRanks.isEmpty() && !ranksRefs.isEmpty() ) { -// -// //Map ret = new HashMap<>(); -// -// for (Map.Entry entry : rankPlay.getRanksRefs().entrySet()) { -// RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder(entry.getKey()); -// -// if ( ladder == null ) { -// continue; // Skip it -// } -// -// Rank rank = PrisonRanks.getInstance().getRankManager().getRank(entry.getValue()); -// if ( rank == null ) { -// continue; // Skip it -// } -// -// PlayerRank pRank = new PlayerRank( rank ); -// -// ladderRanks.put(ladder, pRank); -// } -// -// // Need to recalculate all rank multipliers: -// recalculateRankMultipliers(); -// } -// -// return ladderRanks; -// } public TreeMap getLadderRanks() { return ladderRanks; } -// public void setLadderRanks( TreeMap ladderRanks ) { -// this.ladderRanks = ladderRanks; -// } private RankLadder getRankLadder( String ladderName ) { RankLadder results = null; @@ -1022,45 +752,41 @@ public void setRanksRefs( HashMap ranksRefs ) { * @return */ public boolean hasAccessToRank( Rank targetRank ) { - boolean hasAccess = false; - - if ( targetRank != null && targetRank.getLadder() != null ) { - - PlayerRank pRank = getLadderRanks().get( targetRank.getLadder() ); - -// PlayerRank pRank = getRank( targetRank.getLadder() ); - if ( pRank != null ) { - - Rank rank = pRank.getRank(); - if ( rank != null && - rank.getLadder().equals( targetRank.getLadder() ) ) { - - hasAccess = rank.equals( targetRank ); - - // If access-to-prior-mines is enabled (defaults to true if does not exist), - // then search prior ranks on this ladder until a match with target is found. - if ( Prison.get().getPlatform() - .getConfigBooleanTrue( "prison-mines.access-to-prior-mines" ) ) { - - Rank priorRank = rank.getRankPrior(); - - while ( !hasAccess && priorRank != null ) { - - hasAccess = priorRank.equals( targetRank ); - priorRank = priorRank.getRankPrior(); - } - } - - } - } - } - return hasAccess; + boolean hasAccess = false; + + if ( targetRank != null && targetRank.getLadder() != null ) { + + PlayerRank pRank = getLadderRanks().get( targetRank.getLadder() ); + + if ( pRank != null ) { + + Rank rank = pRank.getRank(); + if ( rank != null && + rank.getLadder().equals( targetRank.getLadder() ) ) { + + hasAccess = rank.equals( targetRank ); + + // If access-to-prior-mines is enabled (defaults to true if does not exist), + // then search prior ranks on this ladder until a match with target is found. + if ( Prison.get().getPlatform() + .getConfigBooleanTrue( "prison-mines.access-to-prior-mines" ) ) { + + Rank priorRank = rank.getRankPrior(); + + while ( !hasAccess && priorRank != null ) { + + hasAccess = priorRank.equals( targetRank ); + priorRank = priorRank.getRankPrior(); + } + } + + } + } + } + return hasAccess; } - /* - * equals() and hashCode() - */ @Override public boolean equals(Object o) { @@ -1195,8 +921,8 @@ public boolean isOp() { */ @Override public boolean isPlayer() { - Player player = getPlatformPlayer(); - return (player != null ? player.isPlayer() : false ); + Player player = getPlatformPlayer(); + return (player != null ? player.isPlayer() : false ); } @@ -1222,10 +948,6 @@ public Inventory getInventory() { return results; } -// @Override -// public void printDebugInventoryInformationToConsole() { -// -// } /** @@ -1255,19 +977,6 @@ public Player getPlatformPlayer() { platformPlayerTimestamp = now; } -// Optional oPlayer = Prison.get().getPlatform().getPlayer( uid ); -// -// if ( oPlayer.isPresent() ) { -// player = oPlayer.get(); -// } -// else { -// oPlayer = Prison.get().getPlatform().getOfflinePlayer( uid ); -// -// if ( oPlayer.isPresent() ) { -// player = oPlayer.get(); -// } -// } - return platformPlayer; } @@ -1287,22 +996,22 @@ public void recalculatePermissions() { @Override public List getPermissions() { - Player player = getPlatformPlayer(); - return (player == null ? new ArrayList<>() : player.getPermissions() ); + Player player = getPlatformPlayer(); + return (player == null ? new ArrayList<>() : player.getPermissions() ); } @Override public List getPermissions( String prefix ) { - return getPermissions( prefix, getPermissions() ); + return getPermissions( prefix, getPermissions() ); } @Override public List getPermissions( String prefix, List perms ) { - Player player = getPlatformPlayer(); - return (player == null ? new ArrayList<>() : - player.getPermissions( prefix, perms ) ); - + Player player = getPlatformPlayer(); + return (player == null ? new ArrayList<>() : + player.getPermissions( prefix, perms ) ); + } /** @@ -1327,42 +1036,36 @@ public List getPermissions( String prefix, List perms ) { */ @Override public double getSellAllMultiplier() { - double results = 1.0; - - Player player = getPlatformPlayer(); - if ( player != null ) { - results = player.getSellAllMultiplier(); - - if ( results != getSellallMultiplierValue() ) { - - setSellallMultiplierValue( results ); - setDirty( true ); - } - } - else { - results = getSellallMultiplierValue(); - } -// -// Optional player = Prison.get().getPlatform().getPlayer( uid ); -// -// if ( player.isPresent() ) { -// results = player.get().getSellAllMultiplier(); -// } - - return results; + double results = 1.0; + + Player player = getPlatformPlayer(); + if ( player != null ) { + results = player.getSellAllMultiplier(); + + if ( results != getSellallMultiplierValue() ) { + + setSellallMultiplierValue( results ); + setDirty( true ); + } + } + else { + results = getSellallMultiplierValue(); + } + + return results; } @Override public double getSellAllMultiplierDebug() { - double results = 1.0; - - Player player = getPlatformPlayer(); - if ( player != null ) { - results = player.getSellAllMultiplierDebug(); - - } - - return results; + double results = 1.0; + + Player player = getPlatformPlayer(); + if ( player != null ) { + results = player.getSellAllMultiplierDebug(); + + } + + return results; } @@ -1377,22 +1080,22 @@ public void setPlayerBalances( TreeMap playerBalances private void addCachedRankPlayerBalance( String currency, double amount ) { - // Since the cache will be updated, do not allow it fetch the player's balance: - RankPlayerBalance balance = getCachedRankPlayerBalance( currency, false ); - - balance.addBalance( amount ); + // Since the cache will be updated, do not allow it fetch the player's balance: + RankPlayerBalance balance = getCachedRankPlayerBalance( currency, false ); + + balance.addBalance( amount ); } private void setCachedRankPlayerBalance( String currency, double amount ) { - // Since the cache will be updated, do not allow it fetch the player's balance: - RankPlayerBalance balance = getCachedRankPlayerBalance( currency, false ); - - balance.setBalance( amount ); + // Since the cache will be updated, do not allow it fetch the player's balance: + RankPlayerBalance balance = getCachedRankPlayerBalance( currency, false ); + + balance.setBalance( amount ); } public RankPlayerBalance getCachedRankPlayerBalance( String currency ) { - return getCachedRankPlayerBalance( currency, true ); + return getCachedRankPlayerBalance( currency, true ); } /** @@ -1527,12 +1230,6 @@ public void removeBalance( double amount ) { addBalance( targetAmount ); addCachedRankPlayerBalance( null, targetAmount ); -// EconomyIntegration economy = getEconomy(); -// -// if ( economy != null ) { -// economy.removeBalance( this, amount ); -// addCachedRankPlayerBalance( null, -1 * amount ); -// } } public void setBalance( double amount ) { @@ -1546,12 +1243,6 @@ public void setBalance( double amount ) { addBalance( targetAmount ); addCachedRankPlayerBalance( null, targetAmount ); -// EconomyIntegration economy = getEconomy(); -// -// if ( economy != null ) { -// economy.setBalance( this, amount ); -// setCachedRankPlayerBalance( null, amount ); -// } } @@ -1821,7 +1512,6 @@ public PlayerRank getNextPlayerRank() { // If the player does not have a presetige rank, the getRankLadder will return null. -// RankLadder rLadder = getRankLadder( RankLadder.PRESTIGES ); nRank = rLadder == null ? null : rLadder.getLowestRank().orElse(null); } @@ -1833,7 +1523,6 @@ public PlayerRank getNextPlayerRank() { } PlayerRank pRankNext = calculateTargetPlayerRank( nRank ); -// PlayerRank pRankNext = rankCurrent.getTargetPlayerRankForPlayer( this, nRank ); return pRankNext; } @@ -1854,68 +1543,7 @@ public void calculateRankScore() { double balance = getBalance( rankNextCurrency ); -// RankPlayerBalance cachedBalance = getCachedRankPlayerBalance( rankNextCurrency, true ); -// -// double balance = cachedBalance.getBalance(); - calculateRankScore( rankNextCurrency, cost, balance ); - - -// PlayerRank rankCurrent = getPlayerRankDefault(); - -// Rank nRank = rankCurrent.getRank().getRankNext(); -// -// // If player does not have a next rank, then try to use the next prestige rank: -// if ( nRank == null ) { -// PlayerRank prestigeRankCurrent = getPlayerRankPrestiges(); -// -// // if they don't have a current prestige rank, then use the lowest rank: -// if ( prestigeRankCurrent == null ) { -// RankLadder rLadder = getRankLadder( RankLadder.PRESTIGES ); -// nRank = rLadder == null ? null : rLadder.getLowestRank().orElse(null); -// } -// -// if ( prestigeRankCurrent != null ) { -// nRank = prestigeRankCurrent.getRank() == null ? -// null : prestigeRankCurrent.getRank().getRankNext(); -// } -// -// } -// -// -// PlayerRank pRankNext = rankCurrent.getTargetPlayerRankForPlayer( this, nRank ); - -// String rankNextCurrency = nRank == null ? "" : nRank.getCurrency(); -// double balance = getBalance( rankNextCurrency ); - - -// double balance = getBalance( rankNextCurrency ); -// double score = balance; -// double penalty = 0d; -// -// // Do not apply the penalty if cost is zero: -// if ( cost > 0 && isHesitancyDelayPenaltyEnabled() ) { -// score = balance > cost ? cost : score; -// -// double excess = balance > cost ? balance - cost : 0d; -// penalty = excess * 0.2d; -// } -// -// score = (score - penalty); -// -// if ( cost > 0 ) { -// score /= cost * 100.0d; -// } -// -//// double balanceThreshold = cost * RANK_SCORE_BALANCE_THRESHOLD_PERCENT; -// -//// setRankScoreBalance( balance ); -//// setRankScoreCurrency( rankNextCurrency ); -//// setRankScoreBalanceThreshold( balanceThreshold ); -// setRankScore( score ); -// setRankScorePenalty( penalty ); -// -//// setRankScoreCooldown( System.currentTimeMillis() + RANK_SCORE_COOLDOWN_MS ); } private void calculateRankScore( String currency, double cost, double playerBalance ) { @@ -1944,56 +1572,12 @@ private void calculateRankScore( String currency, double cost, double playerBala setRankScoreCurrency( currency ); } -// private void checkRecalculateRankScore() { -// -// calculateRankScore(); -// -//// if ( getRankScoreCooldown() == 0L || -//// System.currentTimeMillis() > getRankScoreCooldown() -//// ) { -//// -//// double currentBalance = getBalance( getRankScoreCurrency() ); -//// -//// if ( getRankScoreBalance() != 0 && ( -//// currentBalance == getRankScoreBalance() || -//// currentBalance >= (getRankScoreBalance() - getRankScoreBalanceThreshold()) || -//// currentBalance <= (getRankScoreBalance() + getRankScoreBalanceThreshold() ) )) { -//// -//// // increment the cooldown since the balance is either the same, or still -//// // within the threshold range: -//// setRankScoreCooldown( System.currentTimeMillis() + RANK_SCORE_COOLDOWN_MS ); -//// } -//// else { -//// calculateRankScore( currentBalance ); -//// } -//// } -// } - -// /** -// *

By setting rankScoreCooldown to zero, it will force that player to have it's -// * rank score to be recalculated. The most expensive part is getting the player's -// * balance from Vault. -// *

-// * -// */ -// public void forcePlayerToRecalculateRankScore() { -// rankScoreCooldown = 0L; -// } + public static String printRankScoreLine1Header() { String header = coreTopNLine1HeaderMsg(); -// String header = String.format( -// "Rank %-16s %-9s %-6s %-9s %-9s %-9s", -// "Player", -// "Prestiges", -// "Rank", -// "Balance", -// "Rank-Score", -// "Penalty" -// -// ); return header; } @@ -2040,16 +1624,6 @@ public String printRankScoreLine1( int rankPostion ) { balanceMetricStr ); -// String message = String.format( -// " %-3s %-18s %-7s %-7s %9s %9s %9s", -// rankScoreStr, -// getName(), -// prestRankTagNc, -// defRankTagNc, -// balanceKmbtStr, -// dFmt.format( getRankScore() ), -// sPenaltyStr -// ); message = message .replace(prestRankTagNc, prestRankTag + "&r") @@ -2061,14 +1635,6 @@ public String printRankScoreLine1( int rankPostion ) { public static String printRankScoreLine2Header() { String header = coreTopNLine2HeaderMsg(); -// String header = String.format( -// "Rank %s %s %-15s %9s", -// "Ranks", -// "Rank-Score", -// "Player", -// "Balance" -// -// ); return header; } @@ -2098,21 +1664,6 @@ public String printRankScoreLine2( int rankPostion ) { String playerName = getName(); -// DecimalFormat dFmt = Prison.get().getDecimalFormat("#,##0.00"); -// -// PlayerRank prestRank = getPlayerRankPrestiges(); -// PlayerRank defRank = getPlayerRankDefault(); -// -// String prestRankTag = prestRank == null ? "---" : prestRank.getRank().getTag(); -// String defRankTag = defRank == null ? "---" : defRank.getRank().getTag(); -// -// String prestRankTagNc = Text.stripColor(prestRankTag); -// String defRankTagNc = Text.stripColor(defRankTag); -// -// String balanceKmbtStr = PlaceholdersUtil.formattedKmbtSISize( getRankScoreBalance(), dFmt, " " ); -//// String sPenaltyStr = PlaceholdersUtil.formattedKmbtSISize( getRankScorePenalty(), dFmt, " " ); -// -// String ranks = prestRankTagNc + defRankTagNc; String message = coreTopNLine2DetailMsg( playerName, @@ -2123,19 +1674,6 @@ public String printRankScoreLine2( int rankPostion ) { prestRankTagNc, defRankTagNc, balanceFmtStr, balanceKmbtStr, balanceMetricStr ); -// String message = String.format( -// " %-3s %-9s %6s %-17s %9s", -// (rankPostion > 0 ? Integer.toString(rankPostion) : ""), -// ranks, -// dFmt.format( getRankScore() ), -// getName(), -// balanceKmbtStr -// ); -// -// message = message -// .replace(prestRankTagNc, prestRankTag + "&r") -// .replace(defRankTagNc, defRankTag + "&r"); - return message; } @@ -2158,18 +1696,9 @@ public void setRankScoreCurrency( String rankScoreCurrency ) { this.rankScoreCurrency = rankScoreCurrency; } -// public double getRankScoreBalanceThreshold() { -// return rankScoreBalanceThreshold; -// } -// public void setRankScoreBalanceThreshold( double rankScoreBalanceThreshold ) { -// this.rankScoreBalanceThreshold = rankScoreBalanceThreshold; -// } public double getRankScore() { - // check if the rankScore needs to be reset: -// checkRecalculateRankScore(); - return rankScore; } public void setRankScore( double rankScore ) { @@ -2197,12 +1726,12 @@ public List getSellAllMultiplierListings() { Player player = Prison.get().getPlatform().getPlayer(getUUID()).orElse(null); return player == null ? + + // NOTE: player is offline, so use the saved sellall multiplier list: + getSellallMultipliers() : - // NOTE: player is offline, so use the saved sellall multiplier list: - getSellallMultipliers() : - - // Online player: The actual live multiplier listings: - player.getSellAllMultiplierListings(); + // Online player: The actual live multiplier listings: + player.getSellAllMultiplierListings(); } @@ -2414,11 +1943,4 @@ public String getMiscText() { public void setMiscText( String text ) { miscText = text; } - -// public long getRankScoreCooldown() { -// return rankScoreCooldown; -// } -// public void setRankScoreCooldown( long rankScoreCooldown ) { -// this.rankScoreCooldown = rankScoreCooldown; -// } } diff --git a/prison-core/src/main/java/tech/mcprison/prison/ranks/data/StatsRankPlayerBalanceData.java b/prison-core/src/main/java/tech/mcprison/prison/ranks/data/StatsRankPlayerBalanceData.java index 94cf3440e..f2195849d 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/ranks/data/StatsRankPlayerBalanceData.java +++ b/prison-core/src/main/java/tech/mcprison/prison/ranks/data/StatsRankPlayerBalanceData.java @@ -45,12 +45,9 @@ public void recalc( boolean isPenaltyEnabled ) { // This calculates the target rank, and takes in to consideration the player's existing rank: PlayerRank pRankNext = player.calculateTargetPlayerRank( rank.getRankNext() ); -// PlayerRank pRankNext = pRank.getTargetPlayerRankForPlayer( player, rank.getRankNext() ); - //PlayerRank pRankNext = new PlayerRank( rank.getRankNext(), pRank.getRankMultiplier() ); cost = pRankNext.getRankCost(); } -// double cost = rank.getRankNext() == null ? rank.getCost() : rank.getRankNext().getCost(); double penalty = 0d; // Do not apply the penalty if cost is zero: diff --git a/prison-core/src/main/java/tech/mcprison/prison/selection/SelectionListener.java b/prison-core/src/main/java/tech/mcprison/prison/selection/SelectionListener.java index bf4e41d05..08b59a56a 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/selection/SelectionListener.java +++ b/prison-core/src/main/java/tech/mcprison/prison/selection/SelectionListener.java @@ -38,7 +38,6 @@ public void init() { public void onPlayerInteract(PrisonPlayerInteractEvent e) { ItemStack ourItem = e.getItemInHand(); ItemStack toolItem = ItemStack.SELECTION_WAND; -// ItemStack toolItem = SelectionManager.SELECTION_TOOL; if ( ourItem == null || !ourItem.equals(toolItem)) { return; diff --git a/prison-core/src/main/java/tech/mcprison/prison/selection/SelectionManager.java b/prison-core/src/main/java/tech/mcprison/prison/selection/SelectionManager.java index c0df99b6d..4d8ba5f7f 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/selection/SelectionManager.java +++ b/prison-core/src/main/java/tech/mcprison/prison/selection/SelectionManager.java @@ -31,13 +31,6 @@ */ public class SelectionManager { -// public static final ItemStack SELECTION_TOOL = -// new ItemStack( 1, PrisonBlock.SELECTION_WAND, -// "&7Corner 1 - Left click", -// "&7Corner 2 - Right click"); - -// new ItemStack("&6Selection Wand", 1, PrisonBlock.BLAZE_ROD, "&7Corner 1 - Left click", -// "&7Corner 2 - Right click"); private Map selectionMap; public SelectionManager() { @@ -70,9 +63,6 @@ private int selectionWandCount( Player player) { for (ItemStack is : inv.getItems()) { if ( is != null && is.getMaterial().compareTo( ItemStack.SELECTION_WAND.getMaterial() ) == 0 - // is.getName().toLowerCase().contains( "selection wand" ) && - // is.getDisplayName().toLowerCase().contains( "selection wand" ) && -// is.getMaterial().compareTo( PrisonBlock.BLAZE_ROD ) == 0 ) { count += is.getAmount(); } diff --git a/prison-core/src/main/java/tech/mcprison/prison/spatial/CoordinateKey.java b/prison-core/src/main/java/tech/mcprison/prison/spatial/CoordinateKey.java index 2a0f9e6fe..15fa80119 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/spatial/CoordinateKey.java +++ b/prison-core/src/main/java/tech/mcprison/prison/spatial/CoordinateKey.java @@ -1,62 +1,68 @@ package tech.mcprison.prison.spatial; +/** + * @deprecated Not used + */ public class CoordinateKey - implements Comparable { +// implements Comparable +{ - private int x; - private int y; - private int z; + // NOTE This class is not used, so it has been commented out before removal. - public CoordinateKey( int x, int y, int z ) { - super(); - - this.x = x; - this.y = y; - this.z = z; - } - - @Override - public int compareTo( CoordinateKey skey ) - { - int results = 0; - - if ( skey == null ) { - results = -1; - } - else { - results = Integer.compare( x, skey.getX() ); - - if ( results == 0 ) { - results = Integer.compare( z, skey.getZ() ); - - if ( results == 0 ) { - results = Integer.compare( y, skey.getY() ); - } - } - } - - return results; - } - - public int getX() { - return x; - } - public void setX( int x ) { - this.x = x; - } - - public int getY() { - return y; - } - public void setY( int y ) { - this.y = y; - } - - public int getZ() { - return z; - } - public void setZ( int z ) { - this.z = z; - } +// private int x; +// private int y; +// private int z; +// +// public CoordinateKey( int x, int y, int z ) { +// super(); +// +// this.x = x; +// this.y = y; +// this.z = z; +// } +// +// @Override +// public int compareTo( CoordinateKey skey ) +// { +// int results = 0; +// +// if ( skey == null ) { +// results = -1; +// } +// else { +// results = Integer.compare( x, skey.getX() ); +// +// if ( results == 0 ) { +// results = Integer.compare( z, skey.getZ() ); +// +// if ( results == 0 ) { +// results = Integer.compare( y, skey.getY() ); +// } +// } +// } +// +// return results; +// } +// +// public int getX() { +// return x; +// } +// public void setX( int x ) { +// this.x = x; +// } +// +// public int getY() { +// return y; +// } +// public void setY( int y ) { +// this.y = y; +// } +// +// public int getZ() { +// return z; +// } +// public void setZ( int z ) { +// this.z = z; +// } } diff --git a/prison-core/src/main/java/tech/mcprison/prison/spatial/SpatialIndex.java b/prison-core/src/main/java/tech/mcprison/prison/spatial/SpatialIndex.java index 4d3749df6..c87cc4f28 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/spatial/SpatialIndex.java +++ b/prison-core/src/main/java/tech/mcprison/prison/spatial/SpatialIndex.java @@ -1,13 +1,16 @@ package tech.mcprison.prison.spatial; -import java.util.NavigableMap; - +/** + * @deprecated + */ public class SpatialIndex { - public static final int SPATIAL_INDEX_GRANULARIT = 25; + // NOTE: This class is not used. Contents has been commented out before removal. - private NavigableMap idxX; - private NavigableMap idxY; - private NavigableMap idxZ; +// public static final int SPATIAL_INDEX_GRANULARIT = 25; +// +// private NavigableMap idxX; +// private NavigableMap idxY; +// private NavigableMap idxZ; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/spatial/SpatialIndexData.java b/prison-core/src/main/java/tech/mcprison/prison/spatial/SpatialIndexData.java index dcfb9f601..ade59eda4 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/spatial/SpatialIndexData.java +++ b/prison-core/src/main/java/tech/mcprison/prison/spatial/SpatialIndexData.java @@ -1,11 +1,17 @@ package tech.mcprison.prison.spatial; + +/** + * @deprecated + */ public class SpatialIndexData { - private int x; - private int y; - private int z; + // NOTE: class is not used and has been commented out before removal. + +// private int x; +// private int y; +// private int z; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/store/Collection.java b/prison-core/src/main/java/tech/mcprison/prison/store/Collection.java index e2fa7e62c..192919312 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/store/Collection.java +++ b/prison-core/src/main/java/tech/mcprison/prison/store/Collection.java @@ -32,8 +32,6 @@ public interface Collection { public Optional get(String key); -// public void save(Document document); -// public void save(String filename, Document document); public void save(String filename, Document document, String oldFilename, String fileType); diff --git a/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonCommandTaskData.java b/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonCommandTaskData.java index 40c324c1e..d2fb697bb 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonCommandTaskData.java +++ b/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonCommandTaskData.java @@ -14,8 +14,6 @@ public class PrisonCommandTaskData { - private boolean fail = false; - private RankLadder ladder; private PlayerRank rankTarget; private PlayerRank rankOriginal; @@ -437,26 +435,6 @@ public void runCommandTask() { public void runCommandTask( Player player ) { -// if ( command.contains( "{inline}" ) ) { -// taskMode = TaskMode.inline; -// command = command.replace( "{inline}", "" ); -// } -// -// if ( command.contains( "{inlinePlayer}" ) ) { -// taskMode = TaskMode.inlinePlayer; -// command = command.replace( "{inlinePlayer}", "" ); -// } -// -// if ( command.contains( "{sync}" ) ) { -// taskMode = TaskMode.sync; -// command = command.replace( "{sync}", "" ); -// } -// -// if ( command.contains( "{syncPlayer}" ) ) { -// taskMode = TaskMode.syncPlayer; -// command = command.replace( "{syncPlayer}", "" ); -// } -// String commandTranslated = translateCommand( player, getCmd() ); // Split multiple commands in to a List of individual tasks: @@ -473,37 +451,6 @@ public void runCommandTask( Player player ) { runTask( player ); -// PrisonDispatchCommandTask task = -// new PrisonDispatchCommandTask( tasks, errorMessage, -// player, taskMode.isPlayerTask() ); - - - // Ignore taskMode since it's already running in a new sync task: -// task.run(); - - - // NOTE: taskMode is no longer used, since all tasks are being ran - // within a sync task that has already been submitted. -// switch ( taskMode ) -// { -// case inline: -// case inlinePlayer: -// // Don't submit, but run it here within this thread: -// task.run(); -// break; -// -// case sync: -// case syncPlayer: -// //case "async": // async will cause failures so run as sync: -// -// // submit task: -// setTaskId( PrisonTaskSubmitter.runTaskLater(task, 0) ); -// break; -// -// default: -// break; -// } - } } diff --git a/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonTaskSubmitter.java b/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonTaskSubmitter.java index cc22ab101..72370f7f9 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonTaskSubmitter.java +++ b/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonTaskSubmitter.java @@ -27,9 +27,9 @@ public static int runTaskLater( PrisonRunnable task, long delayInTicks ) { * @return The task ID. */ public static int runTaskLaterAsync(Runnable task, long delayInTicks) { - int taskId = Prison.get().getPlatform().getScheduler().runTaskLaterAsync(task, delayInTicks); - - return taskId; + int taskId = Prison.get().getPlatform().getScheduler().runTaskLaterAsync(task, delayInTicks); + + return taskId; } /** @@ -41,10 +41,10 @@ public static int runTaskLaterAsync(Runnable task, long delayInTicks) { * @return The task ID. */ public static int runTaskTimer(Runnable task, long delayInTicks, long intervalInTicks){ - int taskId = Prison.get().getPlatform().getScheduler().runTaskTimer(task, delayInTicks, - intervalInTicks); - - return taskId; + int taskId = Prison.get().getPlatform().getScheduler().runTaskTimer(task, delayInTicks, + intervalInTicks); + + return taskId; } /** @@ -56,10 +56,10 @@ public static int runTaskTimer(Runnable task, long delayInTicks, long intervalIn * @return The task ID. */ public static int runTaskTimerAsync(Runnable task, long delayInTicks, long intervalInTicks){ - int taskId = Prison.get().getPlatform().getScheduler().runTaskTimerAsync(task, delayInTicks, - intervalInTicks); - - return taskId; + int taskId = Prison.get().getPlatform().getScheduler().runTaskTimerAsync(task, delayInTicks, + intervalInTicks); + + return taskId; } /** @@ -68,14 +68,14 @@ public static int runTaskTimerAsync(Runnable task, long delayInTicks, long inter * @param taskId The task's ID. */ public static void cancelTask(int taskId) { - Prison.get().getPlatform().getScheduler().cancelTask( taskId ); + Prison.get().getPlatform().getScheduler().cancelTask( taskId ); } /** * Cancels all tasks registered through this scheduler. */ public static void cancelAll(){ - Prison.get().getPlatform().getScheduler().cancelAll(); + Prison.get().getPlatform().getScheduler().cancelAll(); } /** @@ -85,7 +85,7 @@ public static void cancelAll(){ * @return */ public static boolean isPrimaryThread() { - return Prison.get().getPlatform().getScheduler().isPrimaryThread(); + return Prison.get().getPlatform().getScheduler().isPrimaryThread(); } } diff --git a/prison-core/src/main/java/tech/mcprison/prison/util/BluesSemanticVersionComparator.java b/prison-core/src/main/java/tech/mcprison/prison/util/BluesSemanticVersionComparator.java index 05f74aa5b..f28c54565 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/util/BluesSemanticVersionComparator.java +++ b/prison-core/src/main/java/tech/mcprison/prison/util/BluesSemanticVersionComparator.java @@ -2,9 +2,6 @@ import tech.mcprison.prison.Prison; -//import org.bukkit.Bukkit; -//import org.inventivetalent.update.spiget.comparator.VersionComparator; - /** *

This class provides a real comparator for semantic versioning * for spiget. This addresses issues seen with incorrect notifications. @@ -39,7 +36,7 @@ */ public class BluesSemanticVersionComparator // extends VersionComparator - { +{ public boolean isNewer(String currentVersion, String checkVersion) { return performComparisons( currentVersion, checkVersion); @@ -143,7 +140,6 @@ public String getBukkitVersion() { private String getBukkitVersionRaw() { return Prison.get().getMinecraftVersion(); -// return Bukkit.getVersion(); } public String getBukkitVersion( String currentVersion ) { @@ -158,10 +154,6 @@ public String getBukkitVersion( String currentVersion ) { } } -// if ( results != null && "1.17".equals( results ) ) { -// results = "1.17.0"; -// } - return results; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/util/Bounds.java b/prison-core/src/main/java/tech/mcprison/prison/util/Bounds.java index 27ecf35bc..91a4af970 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/util/Bounds.java +++ b/prison-core/src/main/java/tech/mcprison/prison/util/Bounds.java @@ -390,11 +390,11 @@ public double getArea() { } public boolean within(Location location) { - return within( location, false, false ); + return within( location, false, false ); } public boolean withinIncludeTopBottomOfMine(Location location) { - return within( location, true, true ); + return within( location, true, true ); } /** @@ -409,27 +409,27 @@ public boolean withinIncludeTopBottomOfMine(Location location) { * @return true if the location is within the bounds, false otherwise. */ private boolean within(Location location, boolean includeTopOfMine, boolean includeOneBelowMine ) { - boolean results = false; - - if ( withinSameWorld( location )) { - - double ourX = Math.floor(location.getX()); - double ourY = Math.floor(location.getY()); - double ourZ = Math.floor(location.getZ()); - - results = ourX >= getxMin() && ourX <= getxMax() // Within X - && ourY >= (getyMin() - (includeOneBelowMine ? 1 : 0)) && - ourY <= (getyMax() + (includeTopOfMine ? 1 : 0)) // Within Y - && ourZ >= getzMin() && ourZ <= getzMax(); // Within Z - } + boolean results = false; + + if ( withinSameWorld( location )) { + + double ourX = Math.floor(location.getX()); + double ourY = Math.floor(location.getY()); + double ourZ = Math.floor(location.getZ()); + + results = ourX >= getxMin() && ourX <= getxMax() // Within X + && ourY >= (getyMin() - (includeOneBelowMine ? 1 : 0)) && + ourY <= (getyMax() + (includeTopOfMine ? 1 : 0)) // Within Y + && ourZ >= getzMin() && ourZ <= getzMax(); // Within Z + } return results; } public boolean withinSameWorld(Location location) { - return getCenter().getWorld() != null && location.getWorld() != null && - getCenter().getWorld().getName().equalsIgnoreCase( - location.getWorld().getName() ); + return getCenter().getWorld() != null && location.getWorld() != null && + getCenter().getWorld().getName().equalsIgnoreCase( + location.getWorld().getName() ); } /** @@ -448,17 +448,17 @@ public boolean withinSameWorld(Location location) { * @return */ public boolean within(Location location, long radius) { - boolean results = false; - - if ( withinSameWorld( location ) ) { + boolean results = false; + + if ( withinSameWorld( location ) ) { - // Ignore y since this is radius from the center axis of the mine: - double distance = getDistance(location); - - results = distance <= radius; - } + // Ignore y since this is radius from the center axis of the mine: + double distance = getDistance(location); + + results = distance <= radius; + } - return results; + return results; } /** @@ -467,38 +467,38 @@ public boolean within(Location location, long radius) { * @return */ public double getDistance() { - double deltaX = getMin().getX() - getMax().getX(); - double deltaZ = getMin().getZ() - getMax().getZ(); - double distance = Math.sqrt( (deltaX * deltaX) + (deltaZ * deltaZ) ); - return Math.round( distance ); + double deltaX = getMin().getX() - getMax().getX(); + double deltaZ = getMin().getZ() - getMax().getZ(); + double distance = Math.sqrt( (deltaX * deltaX) + (deltaZ * deltaZ) ); + return Math.round( distance ); } public double getDistance3d() { - double deltaX = getMin().getX() - getMax().getX(); - double deltaY = getMin().getY() - getMax().getY(); - double deltaZ = getMin().getZ() - getMax().getZ(); - double distance = Math.sqrt( (deltaX * deltaX) + (deltaY * deltaY) + (deltaZ * deltaZ) ); - return Math.round( distance ); + double deltaX = getMin().getX() - getMax().getX(); + double deltaY = getMin().getY() - getMax().getY(); + double deltaZ = getMin().getZ() - getMax().getZ(); + double distance = Math.sqrt( (deltaX * deltaX) + (deltaY * deltaY) + (deltaZ * deltaZ) ); + return Math.round( distance ); } public double getDistance(Location location) { - double deltaX = getCenter().getX() - location.getX(); - double deltaZ = getCenter().getZ() - location.getZ(); - double distance = Math.sqrt( (deltaX * deltaX) + (deltaZ * deltaZ) ); + double deltaX = getCenter().getX() - location.getX(); + double deltaZ = getCenter().getZ() - location.getZ(); + double distance = Math.sqrt( (deltaX * deltaX) + (deltaZ * deltaZ) ); return Math.round( distance ); } public double getDistance3d(Location location) { - double deltaX = getCenter().getX() - location.getX(); - double deltaY = getCenter().getY() - location.getY(); - double deltaZ = getCenter().getZ() - location.getZ(); - double distance = Math.sqrt( (deltaX * deltaX) + (deltaY * deltaY) + (deltaZ * deltaZ) ); - return distance; + double deltaX = getCenter().getX() - location.getX(); + double deltaY = getCenter().getY() - location.getY(); + double deltaZ = getCenter().getZ() - location.getZ(); + double distance = Math.sqrt( (deltaX * deltaX) + (deltaY * deltaY) + (deltaZ * deltaZ) ); + return distance; } public String getDimensions() { - return "&7" + Math.round(getWidth()) + "&8x&7" + - Math.round(getHeight()) + "&8x&7" + Math.round(getLength()); + return "&7" + Math.round(getWidth()) + "&8x&7" + + Math.round(getHeight()) + "&8x&7" + Math.round(getLength()); } public Location getMin() { @@ -547,15 +547,12 @@ public boolean equals(Object o) { // If any point is null, then this must return false: if ( getMin() == null || getMax() == null || bounds.getMin() == null || bounds.getMax() == null ) { - return false; + return false; } return getMin().equals(bounds.getMin()) && getMax().equals(bounds.getMax()); -// return min != null ? -// min.equals(bounds.min) : -// bounds.min == null && (max != null ? max.equals(bounds.max) : bounds.max == null); } @Override public int hashCode() { diff --git a/prison-core/src/main/java/tech/mcprison/prison/util/ChatColor.java b/prison-core/src/main/java/tech/mcprison/prison/util/ChatColor.java index cba2bd4c1..5820a7fb1 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/util/ChatColor.java +++ b/prison-core/src/main/java/tech/mcprison/prison/util/ChatColor.java @@ -32,70 +32,64 @@ * @since API 1.0 */ public enum ChatColor { + BLACK('0', 0x00), + + DARK_BLUE('1', 0x1), + + DARK_GREEN('2', 0x2), + + DARK_AQUA('3', 0x3), + + DARK_RED('4', 0x4), + + DARK_PURPLE('5', 0x5), + + GOLD('6', 0x6), + + GRAY('7', 0x7), + + DARK_GRAY('8', 0x8), + + BLUE('9', 0x9), + + GREEN('a', 0xA), + + AQUA('b', 0xB), + + RED('c', 0xC), + + LIGHT_PURPLE('d', 0xD), + + YELLOW('e', 0xE), + + WHITE('f', 0xF), + /** - * Represents black - */ - BLACK('0', 0x00), /** - * Represents dark blue - */ - DARK_BLUE('1', 0x1), /** - * Represents dark green - */ - DARK_GREEN('2', 0x2), /** - * Represents dark blue (aqua) - */ - DARK_AQUA('3', 0x3), /** - * Represents dark red - */ - DARK_RED('4', 0x4), /** - * Represents dark purple - */ - DARK_PURPLE('5', 0x5), /** - * Represents gold - */ - GOLD('6', 0x6), /** - * Represents gray - */ - GRAY('7', 0x7), /** - * Represents dark gray - */ - DARK_GRAY('8', 0x8), /** - * Represents blue - */ - BLUE('9', 0x9), /** - * Represents green - */ - GREEN('a', 0xA), /** - * Represents aqua - */ - AQUA('b', 0xB), /** - * Represents red - */ - RED('c', 0xC), /** - * Represents light purple - */ - LIGHT_PURPLE('d', 0xD), /** - * Represents yellow - */ - YELLOW('e', 0xE), /** - * Represents white - */ - WHITE('f', 0xF), /** * Represents magical characters that change around randomly */ - MAGIC('k', 0x10, true), /** + MAGIC('k', 0x10, true), + + /** * Makes the text bold. */ - BOLD('l', 0x11, true), /** + BOLD('l', 0x11, true), + + /** * Makes a line appear through the text. */ - STRIKETHROUGH('m', 0x12, true), /** + STRIKETHROUGH('m', 0x12, true), + + /** * Makes the text appear underlined. */ - UNDERLINE('n', 0x13, true), /** + UNDERLINE('n', 0x13, true), + + /** * Makes the text italic. */ - ITALIC('o', 0x14, true), /** + ITALIC('o', 0x14, true), + + /** * Resets all previous chat colors or formats. */ RESET('r', 0x15); @@ -106,7 +100,7 @@ public enum ChatColor { */ public static final char COLOR_CHAR = '\u00A7'; private static final Pattern STRIP_COLOR_PATTERN = - Pattern.compile("(?i)" + String.valueOf(COLOR_CHAR) + "|&[0-9A-FK-OR]"); + Pattern.compile("(?i)" + String.valueOf(COLOR_CHAR) + "|&[0-9A-FK-OR]"); private final static Map BY_ID = Maps.newHashMap(); private final static Map BY_CHAR = Maps.newHashMap(); diff --git a/prison-core/src/main/java/tech/mcprison/prison/util/CollectionUtil.java b/prison-core/src/main/java/tech/mcprison/prison/util/CollectionUtil.java index bc66ecbec..1486b4e1b 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/util/CollectionUtil.java +++ b/prison-core/src/main/java/tech/mcprison/prison/util/CollectionUtil.java @@ -31,16 +31,9 @@ */ public class CollectionUtil { - /* - * Constructor - */ - private CollectionUtil() { } - /* - * Methods - */ /** * Creates a map out of an infinite amount of parameters. Every odd parameter (1, 3, 5, etc.) is a diff --git a/prison-core/src/main/java/tech/mcprison/prison/util/ConversionUtil.java b/prison-core/src/main/java/tech/mcprison/prison/util/ConversionUtil.java index bb7381ffe..1a09e5934 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/util/ConversionUtil.java +++ b/prison-core/src/main/java/tech/mcprison/prison/util/ConversionUtil.java @@ -8,7 +8,7 @@ public static int doubleToInt(Object d) { } public static long doubleToLong(Object d) { - return d == null ? -1 : Math.round((double) d); + return d == null ? -1 : Math.round((double) d); } } 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 b3cd94e07..92805762e 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 @@ -55,7 +55,6 @@ private ArrayList runSample() { sb.append( ".111111" ); DecimalFormat dFmt = new DecimalFormat( "#,##0.000000" ); -// DecimalFormat iFmt = new DecimalFormat( "#,##0.00000" ); for ( int i = 1; i < 35; i++ ) { sb.insert( 0, "1" ); diff --git a/prison-core/src/main/java/tech/mcprison/prison/util/ItemManager.java b/prison-core/src/main/java/tech/mcprison/prison/util/ItemManager.java index 2d72b97aa..3a1aba47f 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/util/ItemManager.java +++ b/prison-core/src/main/java/tech/mcprison/prison/util/ItemManager.java @@ -26,60 +26,6 @@ */ public class ItemManager { -// private Multimap items; - + // This commented out code has been purged. See git for the history. - /** - * This has not been used for a while. Will need to provide an alternative way to - * add custom blocks. - * - * @throws Exception - */ -// @Deprecated -// public ItemManager() throws Exception { -// items = ArrayListMultimap.create(); -// /* -// File file = new File(Prison.get().getDataFolder(), "/items.csv"); -// -// if (!file.exists()) { -// try ( -// // make sure the InputStream is properly closed. May not be 100% needed here: -// InputStream inputStream = getClass().getResourceAsStream("/items.csv"); -// ) -// { -// Files.copy(inputStream, Paths.get(file.getPath())); -// } -// catch (Exception e) { -// throw new IOException("Error while copying items.csv from the jar resource to a " + -// "file within the plugins directory:", e); -// } -// } -// try ( -// // Was a memory leak... always must be closed, so the try with resource ensures that it is: -// BufferedReader in = new BufferedReader(new FileReader(file)); -// ) -// { -// String inputLine; -// -// while ((inputLine = in.readLine()) != null) { -// if (!inputLine.startsWith("#")) { -// String[] array = inputLine.split(","); -// String itemName = array[0]; -// int id = Integer.parseInt(array[1]); -// short data = Short.parseShort(array[2]); -// items.put(BlockType.getBlockWithData(id, data), itemName.toLowerCase()); -// } -// } -// -// } -// catch (Exception e) { -// throw new IOException("Error while reading items.csv -- it's probably invalid", e); -// } -// */ -// } -// -// public Map> getItems() { -// return items.asMap(); -// } - } 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 31b9c2138..3921ff741 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 @@ -50,30 +50,31 @@ public class Location { private boolean isCorner; public Location(World world, double x, double y, double z, float pitch, float yaw, Vector direction) { - this.world = world; - this.worldName = world == null ? null : world.getName(); - - this.x = x; - this.y = y; - this.z = z; - this.pitch = pitch; - this.yaw = yaw; - this.direction = direction; + this.world = world; + this.worldName = world == null ? null : world.getName(); + + this.x = x; + this.y = y; + this.z = z; + this.pitch = pitch; + this.yaw = yaw; + this.direction = direction; } + public Location(World world, double x, double y, double z, float pitch, float yaw) { - this( world, x, y, z, pitch, yaw, new Vector() ); + this( world, x, y, z, pitch, yaw, new Vector() ); } public Location(World world, double x, double y, double z) { - this( world, x, y, z, 0.0f, 0.0f); + this( world, x, y, z, 0.0f, 0.0f); } public Location(String worldName, int x, int y, int z) { - this( Prison.get().getPlatform().getWorld( worldName ).orElse( null ), (double) x, (double) y, (double) z ); + this( Prison.get().getPlatform().getWorld( worldName ).orElse( null ), (double) x, (double) y, (double) z ); } public Location(Location clone) { - this( clone.getWorld(), clone.getX(), clone.getY(), clone.getZ(), + this( clone.getWorld(), clone.getX(), clone.getY(), clone.getZ(), clone.getPitch(), clone.getYaw(), clone.getDirection()); } @@ -81,7 +82,7 @@ public Location() { } public Location clone() { - return new Location( this ); + return new Location( this ); } @@ -202,11 +203,11 @@ public Block getBlockAt() { } public Block getBlockAt( boolean containsCustomBlocks ) { - return world.getBlockAt( this, containsCustomBlocks ); + return world.getBlockAt( this, containsCustomBlocks ); } public void setBlockAsync( PrisonBlock prisonBlock ) { - world.setBlockAsync( prisonBlock, this ); + world.setBlockAsync( prisonBlock, this ); } /** @@ -287,12 +288,6 @@ public boolean equals(Object o) { location.getBlockY() == getBlockY() && location.getBlockZ() == getBlockZ(); -// return Double.compare(location.x, x) == 0 && Double.compare(location.y, y) == 0 -// && Double.compare(location.z, z) == 0 && Float.compare(location.pitch, pitch) == 0 -// && Float.compare(location.yaw, yaw) == 0 && (world != null ? -// world.getName().equals(location.world.getName()) : -// location.world == null); - } @Override @@ -314,7 +309,7 @@ public int hashCode() { @Override public String toString() { - DecimalFormat dFmt = new DecimalFormat( "0.00" ); + DecimalFormat dFmt = new DecimalFormat( "0.00" ); return "Location{" + "world=" + world.getName() + ", " + "x=" + dFmt.format(x) + ", " diff --git a/prison-core/src/main/java/tech/mcprison/prison/util/MaterialType.java b/prison-core/src/main/java/tech/mcprison/prison/util/MaterialType.java index 7776831f4..d2c1051a9 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/util/MaterialType.java +++ b/prison-core/src/main/java/tech/mcprison/prison/util/MaterialType.java @@ -2,11 +2,14 @@ public enum MaterialType { - BLOCK, - ITEM, + // NOTE: This is no longer used. This was used with the old block system. + not_used; - NOT_SET, - - INVALID; +// BLOCK, +// ITEM, +// +// NOT_SET, +// +// INVALID; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/util/MaterialVersion.java b/prison-core/src/main/java/tech/mcprison/prison/util/MaterialVersion.java index 2374c5a27..7dba2bac4 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/util/MaterialVersion.java +++ b/prison-core/src/main/java/tech/mcprison/prison/util/MaterialVersion.java @@ -2,17 +2,20 @@ public enum MaterialVersion { - v1_8, + // NOTE: This is no longer used. This was used with the old block system. + not_used; - v1_9, - v1_10, - - v1_11, - v1_12, - v1_13, - - v1_14, - v1_15, - v1_16 - ; +// v1_8, +// +// v1_9, +// v1_10, +// +// v1_11, +// v1_12, +// v1_13, +// +// v1_14, +// v1_15, +// v1_16 +// ; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/util/ObsoleteBlockType.java b/prison-core/src/main/java/tech/mcprison/prison/util/ObsoleteBlockType.java index cbf4e6c34..dcc24c53e 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/util/ObsoleteBlockType.java +++ b/prison-core/src/main/java/tech/mcprison/prison/util/ObsoleteBlockType.java @@ -18,10 +18,6 @@ package tech.mcprison.prison.util; -import java.util.ArrayList; -import java.util.List; - - /** *

All of the old blocks in the game. This list is obsolete, and was used in * v3.2.0 and earlier. It because obsolete with the new block model which was @@ -54,1267 +50,7 @@ @Deprecated public enum ObsoleteBlockType { - /** - * Identifying a block as a MaterialType.BLOCK will allow the - * block search to only show entries that will be placable within a mine. - * - * Cannot dynamically check for blocks at run time since each major version - * has slightly different sets and the names of this enum do not match the names - * of the Material. - */ - - IGNORE( -1, "prison:ignore", -1, MaterialType.BLOCK ), - NULL_BLOCK( -2, "prison:null_block", -1, MaterialType.INVALID ), - - - // This was auto-generated from WorldEdit's blocks.json - // @formatter:off - - - // NOTE: Double slabs are ones that players cannot naturally place, and they are - // similar to the main block type. It appears like they have been replaced, - // but not sure with what. I suspect no one will use them anyway, and if they - // do, then mapping them to their counter part block. There are a few doubles - // that have been mapped to "smooth" in the later versions, so they are used when - // possible. - - - DOUBLE_STONE_SLAB( 43, "minecraft:double_stone_slab", 0, MaterialType.BLOCK, "smooth_stone" ), - DOUBLE_SANDSTONE_SLAB( 43, "minecraft:double_stone_slab", 1, MaterialType.BLOCK, "smooth_sandstone_slab" ), - DOUBLE_WOODEN_SLAB( 43, "minecraft:double_stone_slab", 2, MaterialType.BLOCK, "OAK_PLANKS" ), - DOUBLE_COBBLESTONE_SLAB( 43, "minecraft:double_stone_slab", 3, MaterialType.BLOCK, "COBBLESTONE" ), - DOUBLE_BRICK_SLAB( 43, "minecraft:double_stone_slab", 4, MaterialType.BLOCK, "BRICKS" ), - DOUBLE_STONE_BRICK_SLAB( 43, "minecraft:double_stone_slab", 5, MaterialType.BLOCK, "STONE_BRICKS" ), - DOUBLE_NETHER_BRICK_SLAB( 43, "minecraft:double_stone_slab", 6, MaterialType.BLOCK, "NETHER_BRICKS" ), - DOUBLE_QUARTZ_SLAB( 43, "minecraft:double_stone_slab", 7, MaterialType.BLOCK, "SMOOTH_QUARTZ" ), - - DOUBLE_OAK_WOOD_SLAB( 125, "minecraft:double_wooden_slab", 0, MaterialType.BLOCK, "OAK_PLANKS" ), - DOUBLE_SPRUCE_WOOD_SLAB( 125, "minecraft:double_wooden_slab", 1, MaterialType.BLOCK, "SPRUCE_PLANKS" ), - DOUBLE_BIRCH_WOOD_SLAB( 125, "minecraft:double_wooden_slab", 2, MaterialType.BLOCK, "BIRCH_PLANKS" ), - DOUBLE_JUNGLE_WOOD_SLAB( 125, "minecraft:double_wooden_slab", 3, MaterialType.BLOCK, "JUNGLE_PLANKS" ), - DOUBLE_ACACIA_WOOD_SLAB( 125, "minecraft:double_wooden_slab", 4, MaterialType.BLOCK, "ACACIA_PLANKS" ), - DOUBLE_DARK_OAK_WOOD_SLAB( 125, "minecraft:double_wooden_slab", 5, MaterialType.BLOCK, "DARK_OAK_PLANKS" ), - - DOUBLE_RED_SANDSTONE_SLAB( 181, "minecraft:double_stone_slab2", 0, MaterialType.BLOCK, "RED_SANDSTONE" ), - PURPUR_DOUBLE_SLAB( 204, "minecraft:purpur_double_slab", 0, MaterialType.BLOCK, "PURPUR_BLOCK" ), - - - - AIR( 0, "minecraft:air", 0, MaterialType.BLOCK ), - STONE( 1, "minecraft:stone", 0, MaterialType.BLOCK ), - GRANITE( 1, "minecraft:stone", 1, MaterialType.BLOCK ), - POLISHED_GRANITE( 1, "minecraft:stone", 2, MaterialType.BLOCK ), - DIORITE( 1, "minecraft:stone", 3, MaterialType.BLOCK ), - POLISHED_DIORITE( 1, "minecraft:stone", 4, MaterialType.BLOCK ), - ANDESITE( 1, "minecraft:stone", 5, MaterialType.BLOCK ), - POLISHED_ANDESITE( 1, "minecraft:stone", 6, MaterialType.BLOCK ), - - GRASS( 2, "minecraft:grass", 0, MaterialType.BLOCK ), - GRASS_BLOCK( 2, "minecraft:grass_block", 0, MaterialType.BLOCK ), - - DIRT( 3, "minecraft:dirt", 0, MaterialType.BLOCK ), - COARSE_DIRT( 3, "minecraft:dirt", 1, MaterialType.BLOCK ), - PODZOL( 3, "minecraft:dirt", 2, MaterialType.BLOCK ), - COBBLESTONE( 4, "minecraft:cobblestone", 0, MaterialType.BLOCK ), - - OAK_WOOD_PLANK( 5, "minecraft:planks", 0, MaterialType.BLOCK, "OAK_PLANKS" ), - SPRUCE_WOOD_PLANK( 5, "minecraft:planks", 1, MaterialType.BLOCK, "SPRUCE_PLANKS" ), - BIRCH_WOOD_PLANK( 5, "minecraft:planks", 2, MaterialType.BLOCK, "BIRCH_PLANKS" ), - JUNGLE_WOOD_PLANK( 5, "minecraft:planks", 3, MaterialType.BLOCK, "JUNGLE_PLANKS" ), - ACACIA_WOOD_PLANK( 5, "minecraft:planks", 4, MaterialType.BLOCK, "ACACIA_PLANKS" ), - DARK_OAK_WOOD_PLANK( 5, "minecraft:planks", 5, MaterialType.BLOCK, "DARK_OAK_PLANKS" ), - - OAK_SAPLING( 6, "minecraft:sapling", 0, MaterialType.BLOCK ), - SPRUCE_SAPLING( 6, "minecraft:sapling", 1, MaterialType.BLOCK ), - BIRCH_SAPLING( 6, "minecraft:sapling", 2, MaterialType.BLOCK ), - JUNGLE_SAPLING( 6, "minecraft:sapling", 3, MaterialType.BLOCK ), - ACACIA_SAPLING( 6, "minecraft:sapling", 4, MaterialType.BLOCK ), - DARK_OAK_SAPLING( 6, "minecraft:sapling", 5, MaterialType.BLOCK ), - BEDROCK( 7, "minecraft:bedrock", 0, MaterialType.BLOCK ), - - FLOWING_WATER( 8, "minecraft:flowing_water", 0, MaterialType.BLOCK, "WATER" ), - - STILL_WATER( 9, "minecraft:water", 0, MaterialType.BLOCK, "STATIONARY_WATER"), - - STATIONARY_WATER_01( 9, "minecraft:water", 1, MaterialType.BLOCK, "STATIONARY_WATER"), - STATIONARY_WATER_02( 9, "minecraft:water", 2, MaterialType.BLOCK, "STATIONARY_WATER"), - STATIONARY_WATER_03( 9, "minecraft:water", 3, MaterialType.BLOCK, "STATIONARY_WATER"), - STATIONARY_WATER_04( 9, "minecraft:water", 4, MaterialType.BLOCK, "STATIONARY_WATER"), - STATIONARY_WATER_05( 9, "minecraft:water", 5, MaterialType.BLOCK, "STATIONARY_WATER"), - STATIONARY_WATER_06( 9, "minecraft:water", 6, MaterialType.BLOCK, "STATIONARY_WATER"), - STATIONARY_WATER_07( 9, "minecraft:water", 7, MaterialType.BLOCK, "STATIONARY_WATER"), - STATIONARY_WATER_08( 9, "minecraft:water", 8, MaterialType.BLOCK, "STATIONARY_WATER"), - STATIONARY_WATER_09( 9, "minecraft:water", 9, MaterialType.BLOCK, "STATIONARY_WATER"), - STATIONARY_WATER_10( 9, "minecraft:water", 10, MaterialType.BLOCK, "STATIONARY_WATER"), - - - FLOWING_LAVA( 10, "minecraft:flowing_lava", 0, MaterialType.BLOCK, "LAVA" ), - STILL_LAVA( 11, "minecraft:lava", 0, MaterialType.BLOCK ), - - SAND( 12, "minecraft:sand", 0, MaterialType.BLOCK ), - RED_SAND( 12, "minecraft:sand", 1, MaterialType.BLOCK ), - GRAVEL( 13, "minecraft:gravel", 0, MaterialType.BLOCK ), - GOLD_ORE( 14, "minecraft:gold_ore", 0, MaterialType.BLOCK ), - IRON_ORE( 15, "minecraft:iron_ore", 0, MaterialType.BLOCK ), - COAL_ORE( 16, "minecraft:coal_ore", 0, MaterialType.BLOCK ), - - OAK_WOOD( 17, "minecraft:log", 0, MaterialType.BLOCK ), - SPRUCE_WOOD( 17, "minecraft:log", 1, MaterialType.BLOCK ), - BIRCH_WOOD( 17, "minecraft:log", 2, MaterialType.BLOCK ), - JUNGLE_WOOD( 17, "minecraft:log", 3, MaterialType.BLOCK, "jungle_planks" ), - - OAK_LEAVES( 18, "minecraft:leaves", 0, MaterialType.BLOCK ), - SPRUCE_LEAVES( 18, "minecraft:leaves", 1, MaterialType.BLOCK ), - BIRCH_LEAVES( 18, "minecraft:leaves", 2, MaterialType.BLOCK ), - JUNGLE_LEAVES( 18, "minecraft:leaves", 3, MaterialType.BLOCK ), - - SPONGE( 19, "minecraft:sponge", 0, MaterialType.BLOCK ), - WET_SPONGE( 19, "minecraft:sponge", 1, MaterialType.BLOCK ), - GLASS( 20, "minecraft:glass", 0, MaterialType.BLOCK ), - - - LAPIS_ORE( 21, "minecraft:lapis_ore", 0, MaterialType.BLOCK, "LAPIS_LAZULI_ORE" ), - LAPIS_LAZULI_ORE( 21, "minecraft:lapis_ore", 0, MaterialType.BLOCK ), // obsolete... - - LAPIS_BLOCK( 22, "minecraft:lapis_block", 0, MaterialType.BLOCK, "LAPIS_LAZULI_BLOCK" ), - LAPIS_LAZULI_BLOCK( 22, "minecraft:lapis_block", 0, MaterialType.BLOCK ), // obsolete... - - DISPENSER( 23, "minecraft:dispenser", 0, MaterialType.BLOCK ), - SANDSTONE( 24, "minecraft:sandstone", 0, MaterialType.BLOCK ), - CHISELED_SANDSTONE( 24, "minecraft:sandstone", 1, MaterialType.BLOCK ), - SMOOTH_SANDSTONE( 24, "minecraft:sandstone", 2, MaterialType.BLOCK ), - NOTE_BLOCK( 25, "minecraft:noteblock", 0, MaterialType.BLOCK ), - BED( 26, "minecraft:bed", 0 ), - POWERED_RAIL( 27, "minecraft:golden_rail", 0, MaterialType.BLOCK ), - DETECTOR_RAIL( 28, "minecraft:detector_rail", 0, MaterialType.BLOCK ), - STICKY_PISTON( 29, "minecraft:sticky_piston", 0, MaterialType.BLOCK ), - COBWEB( 30, "minecraft:web", 0, MaterialType.BLOCK ), - DEAD_SHRUB( 31, "minecraft:tallgrass", 0, MaterialType.BLOCK, "DEAD_BUSH" ), - TALL_GRASS( 31, "minecraft:tallgrass", 1, MaterialType.BLOCK ), - FERN( 31, "minecraft:tallgrass", 2, MaterialType.BLOCK ), - DEAD_BUSH( 32, "minecraft:deadbush", 0, MaterialType.BLOCK, "DEAD_BUSH" ), - PISTON( 33, "minecraft:piston", 0, MaterialType.BLOCK ), - PISTON_HEAD( 34, "minecraft:piston_head", 0, MaterialType.BLOCK ), - WHITE_WOOL( 35, "minecraft:wool", 0, MaterialType.BLOCK ), - ORANGE_WOOL( 35, "minecraft:wool", 1, MaterialType.BLOCK ), - MAGENTA_WOOL( 35, "minecraft:wool", 2, MaterialType.BLOCK ), - LIGHT_BLUE_WOOL( 35, "minecraft:wool", 3, MaterialType.BLOCK ), - YELLOW_WOOL( 35, "minecraft:wool", 4, MaterialType.BLOCK ), - LIME_WOOL( 35, "minecraft:wool", 5, MaterialType.BLOCK ), - PINK_WOOL( 35, "minecraft:wool", 6, MaterialType.BLOCK ), - GRAY_WOOL( 35, "minecraft:wool", 7, MaterialType.BLOCK ), - LIGHT_GRAY_WOOL( 35, "minecraft:wool", 8, MaterialType.BLOCK ), - CYAN_WOOL( 35, "minecraft:wool", 9, MaterialType.BLOCK ), - PURPLE_WOOL( 35, "minecraft:wool", 10, MaterialType.BLOCK ), - BLUE_WOOL( 35, "minecraft:wool", 11, MaterialType.BLOCK ), - BROWN_WOOL( 35, "minecraft:wool", 12, MaterialType.BLOCK ), - GREEN_WOOL( 35, "minecraft:wool", 13, MaterialType.BLOCK ), - RED_WOOL( 35, "minecraft:wool", 14, MaterialType.BLOCK ), - BLACK_WOOL( 35, "minecraft:wool", 15, MaterialType.BLOCK ), - - DANDELION( 37, "minecraft:yellow_flower", 0, MaterialType.BLOCK ), - POPPY( 38, "minecraft:red_flower", 0, MaterialType.BLOCK, "RED_ROSE" ), - BLUE_ORCHID( 38, "minecraft:red_flower", 1, MaterialType.BLOCK ), - ALLIUM( 38, "minecraft:red_flower", 2, MaterialType.BLOCK ), - AZURE_BLUET( 38, "minecraft:red_flower", 3, MaterialType.BLOCK, "AZURE_BLUET" ), - RED_TULIP( 38, "minecraft:red_flower", 4, MaterialType.BLOCK ), - ORANGE_TULIP( 38, "minecraft:red_flower", 5, MaterialType.BLOCK ), - WHITE_TULIP( 38, "minecraft:red_flower", 6, MaterialType.BLOCK ), - PINK_TULIP( 38, "minecraft:red_flower", 7, MaterialType.BLOCK ), - OXEYE_DAISY( 38, "minecraft:red_flower", 8, MaterialType.BLOCK ), - BROWN_MUSHROOM( 39, "minecraft:brown_mushroom", 0, MaterialType.BLOCK ), - RED_MUSHROOM( 40, "minecraft:red_mushroom", 0, MaterialType.BLOCK ), - GOLD_BLOCK( 41, "minecraft:gold_block", 0, MaterialType.BLOCK ), - IRON_BLOCK( 42, "minecraft:iron_block", 0, MaterialType.BLOCK ), - - - STONE_SLAB( 44, "minecraft:stone_slab", 0, MaterialType.BLOCK ), - SANDSTONE_SLAB( 44, "minecraft:stone_slab", 1, MaterialType.BLOCK ), - WOODEN_SLAB( 44, "minecraft:stone_slab", 2, MaterialType.BLOCK ), - COBBLESTONE_SLAB( 44, "minecraft:stone_slab", 3, MaterialType.BLOCK ), - BRICK_SLAB( 44, "minecraft:stone_slab", 4, MaterialType.BLOCK, "STONE_BRICK_SLAB" ), - STONE_BRICK_SLAB( 44, "minecraft:stone_slab", 5, MaterialType.BLOCK ), - NETHER_BRICK_SLAB( 44, "minecraft:stone_slab", 6, MaterialType.BLOCK ), - QUARTZ_SLAB( 44, "minecraft:stone_slab", 7, MaterialType.BLOCK ), - BRICKS( 45, "minecraft:brick_block", 0, MaterialType.BLOCK ), - TNT( 46, "minecraft:tnt", 0, MaterialType.BLOCK ), - BOOKSHELF( 47, "minecraft:bookshelf", 0, MaterialType.BLOCK ), - - MOSSY_COBBLESTONE( 48, "minecraft:mossy_cobblestone", 0, MaterialType.BLOCK, "MOSSY_COBBLESTONE" ), - MOSS_STONE( 48, "minecraft:mossy_cobblestone", 0, MaterialType.BLOCK, "MOSSY_COBBLESTONE", "MOSS_STONE" ), - - OBSIDIAN( 49, "minecraft:obsidian", 0, MaterialType.BLOCK ), - TORCH( 50, "minecraft:torch", 0, MaterialType.BLOCK ), - FIRE( 51, "minecraft:fire", 0, MaterialType.BLOCK ), - MONSTER_SPAWNER( 52, "minecraft:mob_spawner", 0, MaterialType.BLOCK ), - OAK_WOOD_STAIRS( 53, "minecraft:oak_stairs", 0, MaterialType.BLOCK ), - CHEST( 54, "minecraft:chest", 0, MaterialType.BLOCK ), - REDSTONE_WIRE( 55, "minecraft:redstone_wire", 0, MaterialType.BLOCK ), - DIAMOND_ORE( 56, "minecraft:diamond_ore", 0, MaterialType.BLOCK ), - DIAMOND_BLOCK( 57, "minecraft:diamond_block", 0, MaterialType.BLOCK ), - CRAFTING_TABLE( 58, "minecraft:crafting_table", 0, MaterialType.BLOCK ), - WHEAT_CROPS( 59, "minecraft:wheat", 0, MaterialType.BLOCK ), - FARMLAND( 60, "minecraft:farmland", 0, MaterialType.BLOCK ), - FURNACE( 61, "minecraft:furnace", 0, MaterialType.BLOCK ), - BURNING_FURNACE( 62, "minecraft:lit_furnace", 0, MaterialType.BLOCK ), - STANDING_SIGN_BLOCK( 63, "minecraft:standing_sign", 0, MaterialType.BLOCK, "OAK_SIGN" ), - OAK_DOOR_BLOCK( 64, "minecraft:wooden_door", 0, MaterialType.BLOCK ), - LADDER( 65, "minecraft:ladder", 0, MaterialType.BLOCK ), - RAIL( 66, "minecraft:rail", 0, MaterialType.BLOCK ), - COBBLESTONE_STAIRS( 67, "minecraft:stone_stairs", 0, MaterialType.BLOCK ), - WALL_MOUNTED_SIGN_BLOCK( 68, "minecraft:wall_sign", 0 ), - LEVER( 69, "minecraft:lever", 0, MaterialType.BLOCK ), - STONE_PRESSURE_PLATE( 70, "minecraft:stone_pressure_plate", 0, MaterialType.BLOCK ), - IRON_DOOR_BLOCK( 71, "minecraft:iron_door", 0, MaterialType.BLOCK ), - - WOODEN_PRESSURE_PLATE( 72, "minecraft:wooden_pressure_plate", 0, MaterialType.BLOCK, - "OAK_PRESSURE_PLATE", "WOOD_PLATE" ), - REDSTONE_ORE( 73, "minecraft:redstone_ore", 0, MaterialType.BLOCK ), - - GLOWING_REDSTONE_ORE( 74, "minecraft:lit_redstone_ore", 0, MaterialType.BLOCK ), - REDSTONE_TORCH_OFF( 75, "minecraft:unlit_redstone_torch", 0, MaterialType.BLOCK ), - REDSTONE_TORCH_ON( 76, "minecraft:redstone_torch", 0, MaterialType.BLOCK ), - STONE_BUTTON( 77, "minecraft:stone_button", 0, MaterialType.BLOCK ), - - SNOW( 78, "minecraft:snow_layer", 0, MaterialType.BLOCK ), - ICE( 79, "minecraft:ice", 0, MaterialType.BLOCK ), - SNOW_BLOCK( 80, "minecraft:snow", 0, MaterialType.BLOCK ), - - CACTUS( 81, "minecraft:cactus", 0, MaterialType.BLOCK ), - - CLAY( 82, "minecraft:clay", 0, MaterialType.BLOCK, "HARD_CLAY" ), - SUGAR_CANES( 83, "minecraft:reeds", 0, MaterialType.BLOCK, "SUGAR_CANE", "SUGAR_CANE_BLOCK" ), - JUKEBOX( 84, "minecraft:jukebox", 0, MaterialType.BLOCK ), - OAK_FENCE( 85, "minecraft:fence", 0, MaterialType.BLOCK ), - PUMPKIN( 86, "minecraft:pumpkin", 0, MaterialType.BLOCK ), - NETHERRACK( 87, "minecraft:netherrack", 0, MaterialType.BLOCK ), - - SOUL_SAND( 88, "minecraft:soul_sand", 0, MaterialType.BLOCK ), - GLOWSTONE( 89, "minecraft:glowstone", 0, MaterialType.BLOCK ), - NETHER_PORTAL( 90, "minecraft:portal", 0, MaterialType.BLOCK ), - - JACK_OLANTERN( 91, "minecraft:lit_pumpkin", 0, MaterialType.BLOCK, "jack_o_lantern" ), - - CAKE_BLOCK( 92, "minecraft:cake", 0, MaterialType.BLOCK ), - - REDSTONE_REPEATER_BLOCK_OFF( 93, "minecraft:unpowered_repeater", 0, MaterialType.BLOCK, "REPEATER" ), - REDSTONE_REPEATER_BLOCK_ON( 94, "minecraft:powered_repeater", 0, MaterialType.BLOCK, "REPEATER" ), - - WHITE_STAINED_GLASS( 95, "minecraft:stained_glass", 0, MaterialType.BLOCK ), - ORANGE_STAINED_GLASS( 95, "minecraft:stained_glass", 1, MaterialType.BLOCK ), - MAGENTA_STAINED_GLASS( 95, "minecraft:stained_glass", 2, MaterialType.BLOCK ), - LIGHT_BLUE_STAINED_GLASS( 95, "minecraft:stained_glass", 3, MaterialType.BLOCK ), - YELLOW_STAINED_GLASS( 95, "minecraft:stained_glass", 4, MaterialType.BLOCK ), - LIME_STAINED_GLASS( 95, "minecraft:stained_glass", 5, MaterialType.BLOCK ), - PINK_STAINED_GLASS( 95, "minecraft:stained_glass", 6, MaterialType.BLOCK ), - GRAY_STAINED_GLASS( 95, "minecraft:stained_glass", 7, MaterialType.BLOCK ), - LIGHT_GRAY_STAINED_GLASS( 95, "minecraft:stained_glass", 8, MaterialType.BLOCK ), - CYAN_STAINED_GLASS( 95, "minecraft:stained_glass", 9, MaterialType.BLOCK ), - PURPLE_STAINED_GLASS( 95, "minecraft:stained_glass", 10, MaterialType.BLOCK ), - BLUE_STAINED_GLASS( 95, "minecraft:stained_glass", 11, MaterialType.BLOCK ), - BROWN_STAINED_GLASS( 95, "minecraft:stained_glass", 12, MaterialType.BLOCK ), - GREEN_STAINED_GLASS( 95, "minecraft:stained_glass", 13, MaterialType.BLOCK ), - RED_STAINED_GLASS( 95, "minecraft:stained_glass", 14, MaterialType.BLOCK ), - BLACK_STAINED_GLASS( 95, "minecraft:stained_glass", 15, MaterialType.BLOCK ), - WOODEN_TRAPDOOR( 96, "minecraft:trapdoor", 0, MaterialType.BLOCK, "oak_trapdoor" ), - - STONE_MONSTER_EGG( 97, "minecraft:monster_egg", 0, MaterialType.BLOCK, "INFESTED_STONE" ), - COBBLESTONE_MONSTER_EGG( 97, "minecraft:monster_egg", 1, MaterialType.BLOCK, "INFESTED_COBBLESTONE" ), - STONE_BRICK_MONSTER_EGG( 97, "minecraft:monster_egg", 2, MaterialType.BLOCK, "INFESTED_STONE_BRICKS" ), - MOSSY_STONE_BRICK_MONSTER_EGG( 97, "minecraft:monster_egg", 3, MaterialType.BLOCK, "INFESTED_MOSSY_STONE_BRICKS" ), - CRACKED_STONE_BRICK_MONSTER_EGG( 97, "minecraft:monster_egg", 4, MaterialType.BLOCK, "INFESTED_CRACKED_STONE_BRICKS" ), - CHISELED_STONE_BRICK_MONSTER_EGG( 97, "minecraft:monster_egg", 5, MaterialType.BLOCK, "INFESTED_CHISELED_STONE_BRICKS" ), - - STONE_BRICKS( 98, "minecraft:stonebrick", 0, MaterialType.BLOCK, "STONE_BRICKS" ), - MOSSY_STONE_BRICKS( 98, "minecraft:stonebrick", 1, MaterialType.BLOCK, "MOSSY_STONE_BRICKS" ), - CRACKED_STONE_BRICKS( 98, "minecraft:stonebrick", 2, MaterialType.BLOCK, "CRACKED_STONE_BRICKS" ), - CHISELED_STONE_BRICKS( 98, "minecraft:stonebrick", 3, MaterialType.BLOCK, "CHISELED_STONE_BRICKS" ), - - BROWN_MUSHROOM_BLOCK( 99, "minecraft:brown_mushroom_block", 0, MaterialType.BLOCK ), - HUGE_MUSHROOM_1( 99, "minecraft:brown_mushroom_block", 14, MaterialType.BLOCK ), - RED_MUSHROOM_BLOCK( 100, "minecraft:red_mushroom_block", 0, MaterialType.BLOCK ), - HUGE_MUSHROOM_2( 100, "minecraft:red_mushroom_block", 14, MaterialType.BLOCK ), - - IRON_BARS( 101, "minecraft:iron_bars", 0, MaterialType.BLOCK ), - GLASS_PANE( 102, "minecraft:glass_pane", 0, MaterialType.BLOCK ), - MELON_BLOCK( 103, "minecraft:melon_block", 0, MaterialType.BLOCK ), - PUMPKIN_STEM( 104, "minecraft:pumpkin_stem", 0, MaterialType.BLOCK ), - MELON_STEM( 105, "minecraft:melon_stem", 0, MaterialType.BLOCK ), - VINES( 106, "minecraft:vine", 0, MaterialType.BLOCK ), - OAK_FENCE_GATE( 107, "minecraft:fence_gate", 0, MaterialType.BLOCK ), - BRICK_STAIRS( 108, "minecraft:brick_stairs", 0, MaterialType.BLOCK ), - STONE_BRICK_STAIRS( 109, "minecraft:stone_brick_stairs", 0, MaterialType.BLOCK ), - MYCELIUM( 110, "minecraft:mycelium", 0, MaterialType.BLOCK ), - LILY_PAD( 111, "minecraft:waterlily", 0, MaterialType.ITEM ), - - NETHER_BRICK( 112, "minecraft:nether_brick", 0, MaterialType.ITEM ), - NETHER_BRICK_FENCE( 113, "minecraft:nether_brick_fence", 0, MaterialType.BLOCK ), - NETHER_BRICK_STAIRS( 114, "minecraft:nether_brick_stairs", 0, MaterialType.BLOCK ), - NETHER_WART( 115, "minecraft:nether_wart", 0, MaterialType.ITEM ), - ENCHANTMENT_TABLE( 116, "minecraft:enchanting_table", 0, MaterialType.BLOCK ), - BREWING_STAND( 117, "minecraft:brewing_stand", 0, MaterialType.BLOCK ), - CAULDRON( 118, "minecraft:cauldron", 0, MaterialType.BLOCK), - END_PORTAL( 119, "minecraft:end_portal", 0 ), - END_PORTAL_FRAME( 120, "minecraft:end_portal_frame", 0, MaterialType.BLOCK ), - END_STONE( 121, "minecraft:end_stone", 0, MaterialType.BLOCK ), - DRAGON_EGG( 122, "minecraft:dragon_egg", 0, MaterialType.ITEM ), - - REDSTONE_LAMP_INACTIVE( 123, "minecraft:redstone_lamp", 0, MaterialType.BLOCK, "REDSTONE_LAMP_OFF" ), - REDSTONE_LAMP_ACTIVE( 124, "minecraft:lit_redstone_lamp", 0, MaterialType.BLOCK, "REDSTONE_LAMP", "REDSTONE_LAMP_ON" ), - - - OAK_WOOD_SLAB( 126, "minecraft:wooden_slab", 0, MaterialType.BLOCK ), - SPRUCE_WOOD_SLAB( 126, "minecraft:wooden_slab", 1, MaterialType.BLOCK ), - BIRCH_WOOD_SLAB( 126, "minecraft:wooden_slab", 2, MaterialType.BLOCK ), - JUNGLE_WOOD_SLAB( 126, "minecraft:wooden_slab", 3, MaterialType.BLOCK ), - ACACIA_WOOD_SLAB( 126, "minecraft:wooden_slab", 4, MaterialType.BLOCK ), - DARK_OAK_WOOD_SLAB( 126, "minecraft:wooden_slab", 5, MaterialType.BLOCK ), - COCOA( 127, "minecraft:cocoa", 0, MaterialType.BLOCK ), - SANDSTONE_STAIRS( 128, "minecraft:sandstone_stairs", 0, MaterialType.BLOCK ), - EMERALD_ORE( 129, "minecraft:emerald_ore", 0, MaterialType.BLOCK ), - ENDER_CHEST( 130, "minecraft:ender_chest", 0, MaterialType.BLOCK ), - TRIPWIRE_HOOK( 131, "minecraft:tripwire_hook", 0, MaterialType.BLOCK ), - TRIPWIRE( 132, "minecraft:tripwire_hook", 0, MaterialType.BLOCK ), - EMERALD_BLOCK( 133, "minecraft:emerald_block", 0, MaterialType.BLOCK ), - SPRUCE_WOOD_STAIRS( 134, "minecraft:spruce_stairs", 0, MaterialType.BLOCK ), - BIRCH_WOOD_STAIRS( 135, "minecraft:birch_stairs", 0, MaterialType.BLOCK ), - JUNGLE_WOOD_STAIRS( 136, "minecraft:jungle_stairs", 0, MaterialType.BLOCK ), - COMMAND_BLOCK( 137, "minecraft:command_block", 0 ), - BEACON( 138, "minecraft:beacon", 0, MaterialType.BLOCK ), - COBBLESTONE_WALL( 139, "minecraft:cobblestone_wall", 0, MaterialType.BLOCK ), - MOSSY_COBBLESTONE_WALL( 139, "minecraft:cobblestone_wall", 1, MaterialType.BLOCK ), - FLOWER_POT( 140, "minecraft:flower_pot", 0, MaterialType.BLOCK ), - CARROTS( 141, "minecraft:carrots", 0, MaterialType.BLOCK ), - POTATOES( 142, "minecraft:potatoes", 0, MaterialType.BLOCK ), - WOODEN_BUTTON( 143, "minecraft:wooden_button", 0, MaterialType.BLOCK, "OAK_BUTTON", "wood_button" ), - MOB_HEAD( 144, "minecraft:skull", 0, MaterialType.BLOCK ), - ANVIL( 145, "minecraft:anvil", 0, MaterialType.BLOCK ), - TRAPPED_CHEST( 146, "minecraft:trapped_chest", 0, MaterialType.BLOCK ), - WEIGHTED_PRESSURE_PLATE_LIGHT( 147, "minecraft:light_weighted_pressure_plate", 0, MaterialType.BLOCK ), - WEIGHTED_PRESSURE_PLATE_HEAVY( 148, "minecraft:heavy_weighted_pressure_plate", 0, MaterialType.BLOCK ), - - REDSTONE_COMPARATOR_INACTIVE( 149, "minecraft:unpowered_comparator", 0, MaterialType.BLOCK, "COMPARATOR" ), - REDSTONE_COMPARATOR_ACTIVE( 150, "minecraft:powered_comparator", 0, MaterialType.BLOCK, "COMPARATOR" ), - - DAYLIGHT_SENSOR( 151, "minecraft:daylight_detector", 0, MaterialType.BLOCK ), - REDSTONE_BLOCK( 152, "minecraft:redstone_block", 0, MaterialType.BLOCK ), - NETHER_QUARTZ_ORE( 153, "minecraft:quartz_ore", 0, MaterialType.BLOCK ), - HOPPER( 154, "minecraft:hopper", 0, MaterialType.BLOCK ), - QUARTZ_BLOCK( 155, "minecraft:quartz_block", 0, MaterialType.BLOCK ), - CHISELED_QUARTZ_BLOCK( 155, "minecraft:quartz_block", 1, MaterialType.BLOCK ), - - PILLAR_QUARTZ_BLOCK( 155, "minecraft:quartz_block", 2, MaterialType.BLOCK, "QUARTZ_PILLAR" ), - - QUARTZ_STAIRS( 156, "minecraft:quartz_stairs", 0, MaterialType.BLOCK ), - ACTIVATOR_RAIL( 157, "minecraft:activator_rail", 0, MaterialType.BLOCK ), - DROPPER( 158, "minecraft:dropper", 0, MaterialType.BLOCK ), - - WHITE_STAINED_CLAY( 159, "minecraft:stained_hardened_clay", 0, MaterialType.BLOCK, "WHITE_TERRACOTTA" ), - ORANGE_STAINED_CLAY( 159, "minecraft:stained_hardened_clay", 1, MaterialType.BLOCK, "ORANGE_TERRACOTTA" ), - MAGENTA_STAINED_CLAY( 159, "minecraft:stained_hardened_clay", 2, MaterialType.BLOCK, "MAGENTA_TERRACOTTA" ), - LIGHT_BLUE_STAINED_CLAY( 159, "minecraft:stained_hardened_clay", 3, MaterialType.BLOCK, "LIGHT_BLUE_TERRACOTTA" ), - YELLOW_STAINED_CLAY( 159, "minecraft:stained_hardened_clay", 4, MaterialType.BLOCK, "YELLOW_TERRACOTTA" ), - LIME_STAINED_CLAY( 159, "minecraft:stained_hardened_clay", 5, MaterialType.BLOCK, "LIME_TERRACOTTA" ), - PINK_STAINED_CLAY( 159, "minecraft:stained_hardened_clay", 6, MaterialType.BLOCK, "PINK_TERRACOTTA" ), - GRAY_STAINED_CLAY( 159, "minecraft:stained_hardened_clay", 7, MaterialType.BLOCK, "GRAY_TERRACOTTA" ), - LIGHT_GRAY_STAINED_CLAY( 159, "minecraft:stained_hardened_clay", 8, MaterialType.BLOCK, "LIGHT_GRAY_TERRACOTTA" ), - CYAN_STAINED_CLAY( 159, "minecraft:stained_hardened_clay", 9, MaterialType.BLOCK, "CYAN_TERRACOTTA" ), - PURPLE_STAINED_CLAY( 159, "minecraft:stained_hardened_clay", 10, MaterialType.BLOCK, "PURPLE_TERRACOTTA" ), - BLUE_STAINED_CLAY( 159, "minecraft:stained_hardened_clay", 11, MaterialType.BLOCK, "BLUE_TERRACOTTA" ), - BROWN_STAINED_CLAY( 159, "minecraft:stained_hardened_clay", 12, MaterialType.BLOCK, "BROWN_TERRACOTTA" ), - GREEN_STAINED_CLAY( 159, "minecraft:stained_hardened_clay", 13, MaterialType.BLOCK, "GREEN_TERRACOTTA" ), - RED_STAINED_CLAY( 159, "minecraft:stained_hardened_clay", 14, MaterialType.BLOCK, "RED_TERRACOTTA" ), - BLACK_STAINED_CLAY( 159, "minecraft:stained_hardened_clay", 15, MaterialType.BLOCK, "BLACK_TERRACOTTA" ), - - WHITE_STAINED_GLASS_PANE( 160, "minecraft:stained_glass_pane", 0, MaterialType.BLOCK ), - ORANGE_STAINED_GLASS_PANE( 160, "minecraft:stained_glass_pane", 1, MaterialType.BLOCK ), - MAGENTA_STAINED_GLASS_PANE( 160, "minecraft:stained_glass_pane", 2, MaterialType.BLOCK ), - LIGHT_BLUE_STAINED_GLASS_PANE( 160, "minecraft:stained_glass_pane", 3, MaterialType.BLOCK ), - YELLOW_STAINED_GLASS_PANE( 160, "minecraft:stained_glass_pane", 4, MaterialType.BLOCK ), - LIME_STAINED_GLASS_PANE( 160, "minecraft:stained_glass_pane", 5, MaterialType.BLOCK ), - PINK_STAINED_GLASS_PANE( 160, "minecraft:stained_glass_pane", 6, MaterialType.BLOCK ), - GRAY_STAINED_GLASS_PANE( 160, "minecraft:stained_glass_pane", 7, MaterialType.BLOCK ), - LIGHT_GRAY_STAINED_GLASS_PANE( 160, "minecraft:stained_glass_pane", 8, MaterialType.BLOCK ), - CYAN_STAINED_GLASS_PANE( 160, "minecraft:stained_glass_pane", 9, MaterialType.BLOCK ), - PURPLE_STAINED_GLASS_PANE( 160, "minecraft:stained_glass_pane", 10, MaterialType.BLOCK ), - BLUE_STAINED_GLASS_PANE( 160, "minecraft:stained_glass_pane", 11, MaterialType.BLOCK ), - BROWN_STAINED_GLASS_PANE( 160, "minecraft:stained_glass_pane", 12, MaterialType.BLOCK ), - GREEN_STAINED_GLASS_PANE( 160, "minecraft:stained_glass_pane", 13, MaterialType.BLOCK ), - RED_STAINED_GLASS_PANE( 160, "minecraft:stained_glass_pane", 14, MaterialType.BLOCK ), - BLACK_STAINED_GLASS_PANE( 160, "minecraft:stained_glass_pane", 15, MaterialType.BLOCK ), - - ACACIA_LEAVES( 161, "minecraft:leaves2", 0, MaterialType.BLOCK, "ACACIA_LEAVES" ), - DARK_OAK_LEAVES( 161, "minecraft:leaves2", 1, MaterialType.BLOCK ), - ACACIA_WOOD( 162, "minecraft:log2", 0, MaterialType.BLOCK ), - DARK_OAK_WOOD( 162, "minecraft:log2", 1, MaterialType.BLOCK ), - ACACIA_WOOD_STAIRS( 163, "minecraft:acacia_stairs", 0, MaterialType.BLOCK ), - DARK_OAK_WOOD_STAIRS( 164, "minecraft:dark_oak_stairs", 0, MaterialType.BLOCK ), - SLIME_BLOCK( 165, "minecraft:slime", 0, MaterialType.BLOCK ), - BARRIER( 166, "minecraft:barrier", 0, MaterialType.BLOCK ), - IRON_TRAPDOOR( 167, "minecraft:iron_trapdoor", 0, MaterialType.BLOCK ), - PRISMARINE( 168, "minecraft:prismarine", 0, MaterialType.BLOCK ), - PRISMARINE_BRICKS( 168, "minecraft:prismarine", 1, MaterialType.BLOCK ), - DARK_PRISMARINE( 168, "minecraft:prismarine", 2, MaterialType.BLOCK ), - SEA_LANTERN( 169, "minecraft:sea_lantern", 0, MaterialType.BLOCK ), - HAY_BALE( 170, "minecraft:hay_block", 0, MaterialType.BLOCK ), - WHITE_CARPET( 171, "minecraft:carpet", 0, MaterialType.BLOCK ), - ORANGE_CARPET( 171, "minecraft:carpet", 1, MaterialType.BLOCK ), - MAGENTA_CARPET( 171, "minecraft:carpet", 2, MaterialType.BLOCK ), - LIGHT_BLUE_CARPET( 171, "minecraft:carpet", 3, MaterialType.BLOCK ), - YELLOW_CARPET( 171, "minecraft:carpet", 4, MaterialType.BLOCK ), - LIME_CARPET( 171, "minecraft:carpet", 5, MaterialType.BLOCK ), - PINK_CARPET( 171, "minecraft:carpet", 6, MaterialType.BLOCK ), - GRAY_CARPET( 171, "minecraft:carpet", 7, MaterialType.BLOCK ), - LIGHT_GRAY_CARPET( 171, "minecraft:carpet", 8, MaterialType.BLOCK ), - CYAN_CARPET( 171, "minecraft:carpet", 9, MaterialType.BLOCK ), - PURPLE_CARPET( 171, "minecraft:carpet", 10, MaterialType.BLOCK ), - BLUE_CARPET( 171, "minecraft:carpet", 11, MaterialType.BLOCK ), - BROWN_CARPET( 171, "minecraft:carpet", 12, MaterialType.BLOCK ), - GREEN_CARPET( 171, "minecraft:carpet", 13, MaterialType.BLOCK ), - RED_CARPET( 171, "minecraft:carpet", 14, MaterialType.BLOCK ), - BLACK_CARPET( 171, "minecraft:carpet", 15, MaterialType.BLOCK ), - HARDENED_CLAY( 172, "minecraft:hardened_clay", 0, MaterialType.BLOCK, "TERRACOTTA" ), - - COAL_BLOCK( 173, "minecraft:coal_block", 0, MaterialType.BLOCK, "BLOCK_OF_COAL" ), - BLOCK_OF_COAL( 173, "minecraft:coal_block", 0, MaterialType.BLOCK ), // obsolete... - - PACKED_ICE( 174, "minecraft:packed_ice", 0, MaterialType.BLOCK ), - SUNFLOWER( 175, "minecraft:double_plant", 0, MaterialType.BLOCK ), - LILAC( 175, "minecraft:double_plant", 1, MaterialType.BLOCK ), - DOUBLE_TALLGRASS( 175, "minecraft:double_plant", 2, MaterialType.BLOCK ), - LARGE_FERN( 175, "minecraft:double_plant", 3, MaterialType.BLOCK ), - ROSE_BUSH( 175, "minecraft:double_plant", 4, MaterialType.BLOCK ), - PEONY( 175, "minecraft:double_plant", 5, MaterialType.BLOCK ), - FREE_STANDING_BANNER( 176, "minecraft:standing_banner", 0 ), - WALL_MOUNTED_BANNER( 177, "minecraft:wall_banner", 0 ), - INVERTED_DAYLIGHT_SENSOR( 178, "minecraft:daylight_detector_inverted", 0, MaterialType.BLOCK ), - RED_SANDSTONE( 179, "minecraft:red_sandstone", 0, MaterialType.BLOCK ), - CHISELED_RED_SANDSTONE( 179, "minecraft:red_sandstone", 1, MaterialType.BLOCK ), - SMOOTH_RED_SANDSTONE( 179, "minecraft:red_sandstone", 2, MaterialType.BLOCK ), - RED_SANDSTONE_STAIRS( 180, "minecraft:red_sandstone_stairs", 0, MaterialType.BLOCK ), - - RED_SANDSTONE_SLAB( 182, "minecraft:stone_slab2", 0, MaterialType.BLOCK ), - - SPRUCE_FENCE_GATE( 183, "minecraft:spruce_fence_gate", 0, MaterialType.BLOCK ), - BIRCH_FENCE_GATE( 184, "minecraft:birch_fence_gate", 0, MaterialType.BLOCK ), - JUNGLE_FENCE_GATE( 185, "minecraft:jungle_fence_gate", 0, MaterialType.BLOCK ), - DARK_OAK_FENCE_GATE( 186, "minecraft:dark_oak_fence_gate", 0, MaterialType.BLOCK ), - ACACIA_FENCE_GATE( 187, "minecraft:acacia_fence_gate", 0, MaterialType.BLOCK ), - SPRUCE_FENCE( 188, "minecraft:spruce_fence", 0, MaterialType.BLOCK ), - BIRCH_FENCE( 189, "minecraft:birch_fence", 0, MaterialType.BLOCK ), - JUNGLE_FENCE( 190, "minecraft:jungle_fence", 0, MaterialType.BLOCK ), - DARK_OAK_FENCE( 191, "minecraft:dark_oak_fence", 0, MaterialType.BLOCK ), - ACACIA_FENCE( 192, "minecraft:acacia_fence", 0, MaterialType.BLOCK ), - SPRUCE_DOOR_BLOCK( 193, "minecraft:spruce_door", 0, MaterialType.BLOCK ), - BIRCH_DOOR_BLOCK( 194, "minecraft:birch_door", 0, MaterialType.BLOCK ), - JUNGLE_DOOR_BLOCK( 195, "minecraft:jungle_door", 0, MaterialType.BLOCK ), - ACACIA_DOOR_BLOCK( 196, "minecraft:acacia_door", 0, MaterialType.BLOCK ), - DARK_OAK_DOOR_BLOCK( 197, "minecraft:dark_oak_door", 0, MaterialType.BLOCK ), - END_ROD( 198, "minecraft:end_rod", 0, MaterialType.BLOCK ), - CHORUS_PLANT( 199, "minecraft:chorus_plant", 0, MaterialType.BLOCK ), - CHORUS_FLOWER( 200, "minecraft:chorus_flower", 0, MaterialType.BLOCK ), - PURPUR_BLOCK( 201, "minecraft:purpur_block", 0, MaterialType.BLOCK ), - PURPUR_PILLAR( 202, "minecraft:purpur_pillar", 0, MaterialType.BLOCK ), - PURPUR_STAIRS( 203, "minecraft:purpur_stairs", 0, MaterialType.BLOCK ), - - PURPUR_SLAB( 205, "minecraft:purpur_slab", 0, MaterialType.BLOCK ), - END_STONE_BRICKS( 206, "minecraft:end_bricks", 0, MaterialType.BLOCK ), - BEETROOT_BLOCK( 207, "minecraft:beetroots", 0, MaterialType.BLOCK ), - GRASS_PATH( 208, "minecraft:grass_path", 0, MaterialType.BLOCK ), - END_GATEWAY( 209, "minecraft:end_gateway", 0, MaterialType.BLOCK ), - REPEATING_COMMAND_BLOCK( 210, "minecraft:repeating_command_block", 0 ), - CHAIN_COMMAND_BLOCK( 211, "minecraft:chain_command_block", 0 ), - FROSTED_ICE( 212, "minecraft:frosted_ice", 0, MaterialType.BLOCK ), - STRUCTURE_BLOCK( 255, "minecraft:structure_block", 0, MaterialType.BLOCK ), - IRON_SHOVEL( 256, "minecraft:iron_shovel", 0 ), - IRON_PICKAXE( 257, "minecraft:iron_pickaxe", 0 ), - IRON_AXE( 258, "minecraft:iron_axe", 0 ), - FLINT_AND_STEEL( 259, "minecraft:flint_and_steel", 0 ), - APPLE( 260, "minecraft:apple", 0 ), - BOW( 261, "minecraft:bow", 0 ), - ARROW( 262, "minecraft:arrow", 0 ), - COAL( 263, "minecraft:coal", 0 ), - CHARCOAL( 263, "minecraft:coal", 1 ), - DIAMOND( 264, "minecraft:diamond", 0 ), - IRON_INGOT( 265, "minecraft:iron_ingot", 0 ), - GOLD_INGOT( 266, "minecraft:gold_ingot", 0 ), - IRON_SWORD( 267, "minecraft:iron_sword", 0 ), - WOODEN_SWORD( 268, "minecraft:wooden_sword", 0 ), - WOODEN_SHOVEL( 269, "minecraft:wooden_shovel", 0 ), - WOODEN_PICKAXE( 270, "minecraft:wooden_pickaxe", 0 ), - WOODEN_AXE( 271, "minecraft:wooden_axe", 0 ), - STONE_SWORD( 272, "minecraft:stone_sword", 0 ), - STONE_SHOVEL( 273, "minecraft:stone_shovel", 0 ), - STONE_PICKAXE( 274, "minecraft:stone_pickaxe", 0 ), - STONE_AXE( 275, "minecraft:stone_axe", 0 ), - DIAMOND_SWORD( 276, "minecraft:diamond_sword", 0 ), - DIAMOND_SHOVEL( 277, "minecraft:diamond_shovel", 0 ), - DIAMOND_PICKAXE( 278, "minecraft:diamond_pickaxe", 0 ), - DIAMOND_AXE( 279, "minecraft:diamond_axe", 0 ), - STICK( 280, "minecraft:stick", 0 ), - BOWL( 281, "minecraft:bowl", 0 ), - MUSHROOM_STEW( 282, "minecraft:mushroom_stew", 0 ), - GOLDEN_SWORD( 283, "minecraft:golden_sword", 0 ), - GOLDEN_SHOVEL( 284, "minecraft:golden_shovel", 0 ), - GOLDEN_PICKAXE( 285, "minecraft:golden_pickaxe", 0 ), - GOLDEN_AXE( 286, "minecraft:golden_axe", 0 ), - STRING( 287, "minecraft:string", 0 ), - FEATHER( 288, "minecraft:feather", 0 ), - GUNPOWDER( 289, "minecraft:gunpowder", 0 ), - WOODEN_HOE( 290, "minecraft:wooden_hoe", 0 ), - STONE_HOE( 291, "minecraft:stone_hoe", 0 ), - IRON_HOE( 292, "minecraft:iron_hoe", 0 ), - DIAMOND_HOE( 293, "minecraft:diamond_hoe", 0 ), - GOLDEN_HOE( 294, "minecraft:golden_hoe", 0 ), - WHEAT_SEEDS( 295, "minecraft:wheat_seeds", 0 ), - WHEAT( 296, "minecraft:wheat", 0 ), - BREAD( 297, "minecraft:bread", 0 ), - LEATHER_HELMET( 298, "minecraft:leather_helmet", 0 ), - LEATHER_TUNIC( 299, "minecraft:leather_chestplate", 0 ), - LEATHER_PANTS( 300, "minecraft:leather_leggings", 0 ), - LEATHER_BOOTS( 301, "minecraft:leather_boots", 0 ), - CHAINMAIL_HELMET( 302, "minecraft:chainmail_helmet", 0 ), - CHAINMAIL_CHESTPLATE( 303, "minecraft:chainmail_chestplate", 0 ), - CHAINMAIL_LEGGINGS( 304, "minecraft:chainmail_leggings", 0 ), - CHAINMAIL_BOOTS( 305, "minecraft:chainmail_boots", 0 ), - IRON_HELMET( 306, "minecraft:iron_helmet", 0 ), - IRON_CHESTPLATE( 307, "minecraft:iron_chestplate", 0 ), - IRON_LEGGINGS( 308, "minecraft:iron_leggings", 0 ), - IRON_BOOTS( 309, "minecraft:iron_boots", 0 ), - DIAMOND_HELMET( 310, "minecraft:diamond_helmet", 0 ), - DIAMOND_CHESTPLATE( 311, "minecraft:diamond_chestplate", 0 ), - DIAMOND_LEGGINGS( 312, "minecraft:diamond_leggings", 0 ), - DIAMOND_BOOTS( 313, "minecraft:diamond_boots", 0 ), - GOLDEN_HELMET( 314, "minecraft:golden_helmet", 0 ), - GOLDEN_CHESTPLATE( 315, "minecraft:golden_chestplate", 0 ), - GOLDEN_LEGGINGS( 316, "minecraft:golden_leggings", 0 ), - GOLDEN_BOOTS( 317, "minecraft:golden_boots", 0 ), - FLINT( 318, "minecraft:flint", 0 ), - RAW_PORKCHOP( 319, "minecraft:porkchop", 0 ), - COOKED_PORKCHOP( 320, "minecraft:cooked_porkchop", 0 ), - PAINTING( 321, "minecraft:painting", 0 ), - GOLDEN_APPLE( 322, "minecraft:golden_apple", 0 ), - ENCHANTED_GOLDEN_APPLE( 322, "minecraft:golden_apple", 1 ), - SIGN( 323, "minecraft:sign", 0, MaterialType.BLOCK ), - OAK_DOOR( 324, "minecraft:wooden_door", 0, MaterialType.BLOCK ), - BUCKET( 325, "minecraft:bucket", 0 ), - WATER_BUCKET( 326, "minecraft:water_bucket", 0 ), - LAVA_BUCKET( 327, "minecraft:lava_bucket", 0 ), - MINECART( 328, "minecraft:minecart", 0 ), - SADDLE( 329, "minecraft:saddle", 0 ), - IRON_DOOR( 330, "minecraft:iron_door", 0, MaterialType.BLOCK ), - REDSTONE( 331, "minecraft:redstone", 0, MaterialType.ITEM ), - SNOWBALL( 332, "minecraft:snowball", 0 ), - OAK_BOAT( 333, "minecraft:boat", 0 ), - LEATHER( 334, "minecraft:leather", 0 ), - MILK_BUCKET( 335, "minecraft:milk_bucket", 0 ), - BRICK( 336, "minecraft:brick", 0, MaterialType.BLOCK ), - CLAY_BALL( 337, "minecraft:clay_ball", 0 ), - SUGAR_CANES_ITEM( 338, "minecraft:reeds", 0, MaterialType.BLOCK, "SUGAR_CANE" ), - PAPER( 339, "minecraft:paper", 0 ), - BOOK( 340, "minecraft:book", 0 ), - SLIMEBALL( 341, "minecraft:slime_ball", 0 ), - MINECART_WITH_CHEST( 342, "minecraft:chest_minecart", 0 ), - MINECART_WITH_FURNACE( 343, "minecraft:furnace_minecart", 0 ), - EGG( 344, "minecraft:egg", 0 ), - COMPASS( 345, "minecraft:compass", 0 ), - FISHING_ROD( 346, "minecraft:fishing_rod", 0 ), - CLOCK( 347, "minecraft:clock", 0 ), - GLOWSTONE_DUST( 348, "minecraft:glowstone_dust", 0 ), - RAW_FISH( 349, "minecraft:fish", 0 ), - RAW_SALMON( 349, "minecraft:fish", 1 ), - CLOWNFISH( 349, "minecraft:fish", 2 ), - PUFFERFISH( 349, "minecraft:fish", 3 ), - COOKED_FISH( 350, "minecraft:cooked_fish", 0 ), - COOKED_SALMON( 350, "minecraft:cooked_fish", 1 ), - - INK_SACK( 351, "minecraft:dye", 0 ), - ROSE_RED( 351, "minecraft:dye", 1 ), - CACTUS_GREEN( 351, "minecraft:dye", 2 ), - COCO_BEANS( 351, "minecraft:dye", 3 ), - - // NOTE: May actually be minecraft:ink_sack which is what XMaterial uses? - LAPIS_LAZULI( 351, "minecraft:dye", 4 ), - - PURPLE_DYE( 351, "minecraft:dye", 5 ), - CYAN_DYE( 351, "minecraft:dye", 6 ), - LIGHT_GRAY_DYE( 351, "minecraft:dye", 7 ), - GRAY_DYE( 351, "minecraft:dye", 8 ), - PINK_DYE( 351, "minecraft:dye", 9 ), - LIME_DYE( 351, "minecraft:dye", 10 ), - DANDELION_YELLOW( 351, "minecraft:dye", 11 ), - LIGHT_BLUE_DYE( 351, "minecraft:dye", 12 ), - MAGENTA_DYE( 351, "minecraft:dye", 13 ), - ORANGE_DYE( 351, "minecraft:dye", 14 ), - BONE_MEAL( 351, "minecraft:dye", 15 ), - - - BONE( 352, "minecraft:bone", 0 ), - SUGAR( 353, "minecraft:sugar", 0 ), - CAKE( 354, "minecraft:cake", 0 ), - BED_ITEM( 355, "minecraft:bed", 0 ), - REDSTONE_REPEATER( 356, "minecraft:repeater", 0, MaterialType.BLOCK ), - COOKIE( 357, "minecraft:cookie", 0 ), - MAP( 358, "minecraft:filled_map", 0 ), - SHEARS( 359, "minecraft:shears", 0 ), - MELON( 360, "minecraft:melon", 0, MaterialType.BLOCK ), - PUMPKIN_SEEDS( 361, "minecraft:pumpkin_seeds", 0 ), - MELON_SEEDS( 362, "minecraft:melon_seeds", 0 ), - RAW_BEEF( 363, "minecraft:beef", 0 ), - STEAK( 364, "minecraft:cooked_beef", 0 ), - RAW_CHICKEN( 365, "minecraft:chicken", 0 ), - COOKED_CHICKEN( 366, "minecraft:cooked_chicken", 0 ), - ROTTEN_FLESH( 367, "minecraft:rotten_flesh", 0 ), - ENDER_PEARL( 368, "minecraft:ender_pearl", 0 ), - BLAZE_ROD( 369, "minecraft:blaze_rod", 0 ), - GHAST_TEAR( 370, "minecraft:ghast_tear", 0 ), - GOLD_NUGGET( 371, "minecraft:gold_nugget", 0 ), - NETHER_WART_ITEM( 372, "minecraft:nether_wart", 0 ), - POTION( 373, "minecraft:potion", 0 ), - GLASS_BOTTLE( 374, "minecraft:glass_bottle", 0 ), - SPIDER_EYE( 375, "minecraft:spider_eye", 0 ), - FERMENTED_SPIDER_EYE( 376, "minecraft:fermented_spider_eye", 0 ), - BLAZE_POWDER( 377, "minecraft:blaze_powder", 0 ), - MAGMA_CREAM( 378, "minecraft:magma_cream", 0 ), - BREWING_STAND_ITEM( 379, "minecraft:brewing_stand", 0, MaterialType.BLOCK ), - CAULDRON_ITEM( 380, "minecraft:cauldron", 0, MaterialType.BLOCK ), - EYE_OF_ENDER( 381, "minecraft:ender_eye", 0 ), - GLISTERING_MELON( 382, "minecraft:speckled_melon", 0 ), - SPAWN_CREEPER( 383, "minecraft:spawn_egg", 50 ), - SPAWN_SKELETON( 383, "minecraft:spawn_egg", 51 ), - SPAWN_SPIDER( 383, "minecraft:spawn_egg", 52 ), - SPAWN_ZOMBIE( 383, "minecraft:spawn_egg", 54 ), - SPAWN_SLIME( 383, "minecraft:spawn_egg", 55 ), - SPAWN_GHAST( 383, "minecraft:spawn_egg", 56 ), - SPAWN_PIGMAN( 383, "minecraft:spawn_egg", 57 ), - SPAWN_ENDERMAN( 383, "minecraft:spawn_egg", 58 ), - SPAWN_CAVE_SPIDER( 383, "minecraft:spawn_egg", 59 ), - SPAWN_SILVERFISH( 383, "minecraft:spawn_egg", 60 ), - SPAWN_BLAZE( 383, "minecraft:spawn_egg", 61 ), - SPAWN_MAGMA_CUBE( 383, "minecraft:spawn_egg", 62 ), - SPAWN_BAT( 383, "minecraft:spawn_egg", 65 ), - SPAWN_WITCH( 383, "minecraft:spawn_egg", 66 ), - SPAWN_ENDERMITE( 383, "minecraft:spawn_egg", 67 ), - SPAWN_GUARDIAN( 383, "minecraft:spawn_egg", 68 ), - SPAWN_SHULKER( 383, "minecraft:spawn_egg", 69 ), - SPAWN_PIG( 383, "minecraft:spawn_egg", 90 ), - SPAWN_SHEEP( 383, "minecraft:spawn_egg", 91 ), - SPAWN_COW( 383, "minecraft:spawn_egg", 92 ), - SPAWN_CHICKEN( 383, "minecraft:spawn_egg", 93 ), - SPAWN_SQUID( 383, "minecraft:spawn_egg", 94 ), - SPAWN_WOLF( 383, "minecraft:spawn_egg", 95 ), - SPAWN_MOOSHROOM( 383, "minecraft:spawn_egg", 96 ), - SPAWN_OCELOT( 383, "minecraft:spawn_egg", 98 ), - SPAWN_HORSE( 383, "minecraft:spawn_egg", 100 ), - SPAWN_RABBIT( 383, "minecraft:spawn_egg", 101 ), - SPAWN_VILLAGER( 383, "minecraft:spawn_egg", 120 ), - BOTTLE_O_ENCHANTING( 384, "minecraft:experience_bottle", 0 ), - FIRE_CHARGE( 385, "minecraft:fire_charge", 0 ), - BOOK_AND_QUILL( 386, "minecraft:writable_book", 0 ), - WRITTEN_BOOK( 387, "minecraft:written_book", 0 ), - EMERALD( 388, "minecraft:emerald", 0 ), - ITEM_FRAME( 389, "minecraft:item_frame", 0, MaterialType.BLOCK ), - FLOWER_POT_ITEM( 390, "minecraft:flower_pot", 0, MaterialType.BLOCK ), - CARROT( 391, "minecraft:carrot", 0, MaterialType.BLOCK ), - POTATO( 392, "minecraft:potato", 0, MaterialType.BLOCK ), - BAKED_POTATO( 393, "minecraft:baked_potato", 0 ), - POISONOUS_POTATO( 394, "minecraft:poisonous_potato", 0 ), - EMPTY_MAP( 395, "minecraft:map", 0 ), - GOLDEN_CARROT( 396, "minecraft:golden_carrot", 0 ), - MOB_HEAD_SKELETON( 397, "minecraft:skull", 0 ), - MOB_HEAD_WITHER_SKELETON( 397, "minecraft:skull", 1 ), - MOB_HEAD_ZOMBIE( 397, "minecraft:skull", 2 ), - MOB_HEAD_HUMAN( 397, "minecraft:skull", 3 ), - MOB_HEAD_CREEPER( 397, "minecraft:skull", 4 ), - MOB_HEAD_DRAGON( 397, "minecraft:skull", 5 ), - CARROT_ON_A_STICK( 398, "minecraft:carrot_on_a_stick", 0 ), - NETHER_STAR( 399, "minecraft:nether_star", 0 ), - PUMPKIN_PIE( 400, "minecraft:pumpkin_pie", 0 ), - FIREWORK_ROCKET( 401, "minecraft:fireworks", 0 ), - FIREWORK_STAR( 402, "minecraft:firework_charge", 0 ), - ENCHANTED_BOOK( 403, "minecraft:enchanted_book", 0 ), - REDSTONE_COMPARATOR( 404, "minecraft:comparator", 0, MaterialType.BLOCK ), - NETHER_BRICK_ITEM( 405, "minecraft:netherbrick", 0, MaterialType.ITEM ), - NETHER_QUARTZ( 406, "minecraft:quartz", 0 ), - MINECART_WITH_TNT( 407, "minecraft:tnt_minecart", 0 ), - MINECART_WITH_HOPPER( 408, "minecraft:hopper_minecart", 0 ), - PRISMARINE_SHARD( 409, "minecraft:prismarine_shard", 0 ), - PRISMARINE_CRYSTALS( 410, "minecraft:prismarine_crystals", 0 ), - RAW_RABBIT( 411, "minecraft:rabbit", 0 ), - COOKED_RABBIT( 412, "minecraft:cooked_rabbit", 0 ), - RABBIT_STEW( 413, "minecraft:rabbit_stew", 0 ), - RABBITS_FOOT( 414, "minecraft:rabbit_foot", 0 ), - RABBIT_HIDE( 415, "minecraft:rabbit_hide", 0 ), - ARMOR_STAND( 416, "minecraft:armor_stand", 0, MaterialType.BLOCK ), - IRON_HORSE_ARMOR( 417, "minecraft:iron_horse_armor", 0 ), - GOLDEN_HORSE_ARMOR( 418, "minecraft:golden_horse_armor", 0 ), - DIAMOND_HORSE_ARMOR( 419, "minecraft:diamond_horse_armor", 0 ), - LEAD( 420, "minecraft:lead", 0 ), - NAME_TAG( 421, "minecraft:name_tag", 0 ), - MINECART_WITH_COMMAND_BLOCK( 422, "minecraft:command_block_minecart", 0 ), - RAW_MUTTON( 423, "minecraft:mutton", 0 ), - COOKED_MUTTON( 424, "minecraft:cooked_mutton", 0 ), - BANNER( 425, "minecraft:banner", 0, MaterialType.BLOCK ), - SPRUCE_DOOR( 427, "minecraft:spruce_door", 0, MaterialType.BLOCK ), - BIRCH_DOOR( 428, "minecraft:birch_door", 0, MaterialType.BLOCK ), - JUNGLE_DOOR( 429, "minecraft:jungle_door", 0, MaterialType.BLOCK ), - ACACIA_DOOR( 430, "minecraft:acacia_door", 0, MaterialType.BLOCK ), - DARK_OAK_DOOR( 431, "minecraft:dark_oak_door", 0, MaterialType.BLOCK ), - CHORUS_FRUIT( 432, "minecraft:chorus_fruit", 0, MaterialType.BLOCK ), - POPPED_CHORUS_FRUIT( 433, "minecraft:popped_chorus_fruit", 0 ), - BEETROOT( 434, "minecraft:beetroot", 0, MaterialType.BLOCK ), - BEETROOT_SEEDS( 435, "minecraft:beetroot_seeds", 0 ), - BEETROOT_SOUP( 436, "minecraft:beetroot_soup", 0 ), - DRAGONS_BREATH( 437, "minecraft:dragon_breath", 0, MaterialType.BLOCK ), - SPLASH_POTION( 438, "minecraft:splash_potion", 0 ), - SPECTRAL_ARROW( 439, "minecraft:spectral_arrow", 0 ), - TIPPED_ARROW( 440, "minecraft:tipped_arrow", 0 ), - LINGERING_POTION( 441, "minecraft:lingering_potion", 0 ), - SHIELD( 442, "minecraft:shield", 0 ), - ELYTRA( 443, "minecraft:elytra", 0 ), - SPRUCE_BOAT( 444, "minecraft:spruce_boat", 0 ), - BIRCH_BOAT( 445, "minecraft:birch_boat", 0 ), - JUNGLE_BOAT( 446, "minecraft:jungle_boat", 0 ), - ACACIA_BOAT( 447, "minecraft:acacia_boat", 0 ), - DARK_OAK_BOAT( 448, "minecraft:dark_oak_boat", 0 ), - DISC_13( 2256, "minecraft:record_13", 0 ), - CAT_DISC( 2257, "minecraft:record_cat", 0 ), - BLOCKS_DISC( 2258, "minecraft:record_blocks", 0 ), - CHIRP_DISC( 2259, "minecraft:record_chirp", 0 ), - FAR_DISC( 2260, "minecraft:record_far", 0 ), - MALL_DISC( 2261, "minecraft:record_mall", 0 ), - MELLOHI_DISC( 2262, "minecraft:record_mellohi", 0 ), - STAL_DISC( 2263, "minecraft:record_stal", 0 ), - STRAD_DISC( 2264, "minecraft:record_strad", 0 ), - WARD_DISC( 2265, "minecraft:record_ward", 0 ), - DISC_11( 2266, "minecraft:record_11", 0 ), - WAIT_DISC( 2267, "minecraft:record_wait", 0 ), - - - // Minecraft v1.10.x blocks: - - STRUCTURE_VOID( "minecraft:structure_void", MaterialType.BLOCK, MaterialVersion.v1_10 ), - MAGMA_BLOCK( "minecraft:magma_block", MaterialType.BLOCK, MaterialVersion.v1_10 ), - BONE_BLOCK( "minecraft:bone_block", MaterialType.BLOCK, MaterialVersion.v1_10 ), - - - // Minecraft v1.11.x blocks: - - SHULKER_BOX( "minecraft:shulker_box", MaterialType.BLOCK, MaterialVersion.v1_11 ), - - WHITE_SHULKER_BOX( "minecraft:white_shulker_box", MaterialType.BLOCK, MaterialVersion.v1_11 ), - ORANGE_SHULKER_BOX( "minecraft:orange_shulker_box", MaterialType.BLOCK, MaterialVersion.v1_11 ), - MAGENTA_SHULKER_BOX( "minecraft:magenta_shulker_box", MaterialType.BLOCK, MaterialVersion.v1_11 ), - LIGHT_BLUE_SHULKER_BOX( "minecraft:light_blue_shulker_box", MaterialType.BLOCK, MaterialVersion.v1_11 ), - YELLOW_SHULKER_BOX( "minecraft:yellow_shulker_box", MaterialType.BLOCK, MaterialVersion.v1_11 ), - - LIME_SHULKER_BOX( "minecraft:lime_shulker_box", MaterialType.BLOCK, MaterialVersion.v1_11 ), - PINK_SHULKER_BOX( "minecraft:pink_shulker_box", MaterialType.BLOCK, MaterialVersion.v1_11 ), - GRAY_SHULKER_BOX( "minecraft:gray_shulker_box", MaterialType.BLOCK, MaterialVersion.v1_11 ), - LIGHT_GRAY_SHULKER_BOX( "minecraft:light_gray_shulker_box", MaterialType.BLOCK, MaterialVersion.v1_11 ), - CYAN_SHULKER_BOX( "minecraft:cyan_shulker_box", MaterialType.BLOCK, MaterialVersion.v1_11 ), - - PURPLE_SHULKER_BOX( "minecraft:purple_shulker_box", MaterialType.BLOCK, MaterialVersion.v1_11 ), - BLUE_SHULKER_BOX( "minecraft:blue_shulker_box", MaterialType.BLOCK, MaterialVersion.v1_11 ), - BROWN_SHULKER_BOX( "minecraft:brown_shulker_box", MaterialType.BLOCK, MaterialVersion.v1_11 ), - GREEN_SHULKER_BOX( "minecraft:green_shulker_box", MaterialType.BLOCK, MaterialVersion.v1_11 ), - RED_SHULKER_BOX( "minecraft:red_shulker_box", MaterialType.BLOCK, MaterialVersion.v1_11 ), - BLACK_SHULKER_BOX( "minecraft:black_shulker_box", MaterialType.BLOCK, MaterialVersion.v1_11 ), - - - - // Minecraft v1.12.x blocks: - - WHITE_GLAZED_TERRACOTTA( "minecraft:white_glazed_terracotta", MaterialType.BLOCK, MaterialVersion.v1_12 ), - ORANGE_GLAZED_TERRACOTTA( "minecraft:orange_glazed_terracotta", MaterialType.BLOCK, MaterialVersion.v1_12 ), - MAGENTA_GLAZED_TERRACOTTA( "minecraft:magenta_glazed_terracotta", MaterialType.BLOCK, MaterialVersion.v1_12 ), - LIGHT_BLUE_GLAZED_TERRACOTTA( "minecraft:light_blue_glazed_terracotta", MaterialType.BLOCK, MaterialVersion.v1_12 ), - YELLOW_GLAZED_TERRACOTTA( "minecraft:yellow_glazed_terracotta", MaterialType.BLOCK, MaterialVersion.v1_12 ), - - LIME_GLAZED_TERRACOTTA( "minecraft:lime_glazed_terracotta", MaterialType.BLOCK, MaterialVersion.v1_12 ), - PINK_GLAZED_TERRACOTTA( "minecraft:pink_glazed_terracotta", MaterialType.BLOCK, MaterialVersion.v1_12 ), - GRAY_GLAZED_TERRACOTTA( "minecraft:gray_glazed_terracotta", MaterialType.BLOCK, MaterialVersion.v1_12 ), - LIGHT_GRAY_GLAZED_TERRACOTTA( "minecraft:light_gray_glazed_terracotta", MaterialType.BLOCK, MaterialVersion.v1_12 ), - CYAN_GLAZED_TERRACOTTA( "minecraft:cyan_glazed_terracotta", MaterialType.BLOCK, MaterialVersion.v1_12 ), + // NOTE: This obsolete source has been purged. See the history in git. - PURPLE_GLAZED_TERRACOTTA( "minecraft:purple_glazed_terracotta", MaterialType.BLOCK, MaterialVersion.v1_12 ), - BLUE_GLAZED_TERRACOTTA( "minecraft:blue_glazed_terracotta", MaterialType.BLOCK, MaterialVersion.v1_12 ), - BROWN_GLAZED_TERRACOTTA( "minecraft:brown_glazed_terracotta", MaterialType.BLOCK, MaterialVersion.v1_12 ), - GREEN_GLAZED_TERRACOTTA( "minecraft:green_glazed_terracotta", MaterialType.BLOCK, MaterialVersion.v1_12 ), - RED_GLAZED_TERRACOTTA( "minecraft:red_glazed_terracotta", MaterialType.BLOCK, MaterialVersion.v1_12 ), - BLACK_GLAZED_TERRACOTTA( "minecraft:black_glazed_terracotta", MaterialType.BLOCK, MaterialVersion.v1_12 ), - - - WHITE_CONCRETE( "minecraft:white_concrete", MaterialType.BLOCK, MaterialVersion.v1_12 ), - ORANGE_CONCRETE( "minecraft:orange_concrete", MaterialType.BLOCK, MaterialVersion.v1_12 ), - MAGENTA_CONCRETE( "minecraft:magenta_concrete", MaterialType.BLOCK, MaterialVersion.v1_12 ), - LIGHT_BLUE_CONCRETE( "minecraft:light_blue_concrete", MaterialType.BLOCK, MaterialVersion.v1_12 ), - YELLOW_CONCRETE( "minecraft:yellow_concrete", MaterialType.BLOCK, MaterialVersion.v1_12 ), - - LIME_CONCRETE( "minecraft:lime_concrete", MaterialType.BLOCK, MaterialVersion.v1_12 ), - PINK_CONCRETE( "minecraft:pink_concrete", MaterialType.BLOCK, MaterialVersion.v1_12 ), - GRAY_CONCRETE( "minecraft:gray_concrete", MaterialType.BLOCK, MaterialVersion.v1_12 ), - LIGHT_GRAY_CONCRETE( "minecraft:light_gray_concrete", MaterialType.BLOCK, MaterialVersion.v1_12 ), - CYAN_CONCRETE( "minecraft:cyan_concrete", MaterialType.BLOCK, MaterialVersion.v1_12 ), - - PURPLE_CONCRETE( "minecraft:purple_concrete", MaterialType.BLOCK, MaterialVersion.v1_12 ), - BLUE_CONCRETE( "minecraft:blue_concrete", MaterialType.BLOCK, MaterialVersion.v1_12 ), - BROWN_CONCRETE( "minecraft:brown_concrete", MaterialType.BLOCK, MaterialVersion.v1_12 ), - GREEN_CONCRETE( "minecraft:green_concrete", MaterialType.BLOCK, MaterialVersion.v1_12 ), - RED_CONCRETE( "minecraft:red_concrete", MaterialType.BLOCK, MaterialVersion.v1_12 ), - BLACK_CONCRETE( "minecraft:black_concrete", MaterialType.BLOCK, MaterialVersion.v1_12 ), - - - WHITE_CONCRETE_POWDER( "minecraft:white_concrete_powder", MaterialType.BLOCK, MaterialVersion.v1_12 ), - ORANGE_CONCRETE_POWDER( "minecraft:orange_concrete_powder", MaterialType.BLOCK, MaterialVersion.v1_12 ), - MAGENTA_CONCRETE_POWDER( "minecraft:magenta_concrete_powder", MaterialType.BLOCK, MaterialVersion.v1_12 ), - LIGHT_BLUE_CONCRETE_POWDER( "minecraft:light_blue_concrete_powder", MaterialType.BLOCK, MaterialVersion.v1_12 ), - YELLOW_CONCRETE_POWDER( "minecraft:yellow_concrete_powder", MaterialType.BLOCK, MaterialVersion.v1_12 ), - - LIME_CONCRETE_POWDER( "minecraft:lime_concrete_powder", MaterialType.BLOCK, MaterialVersion.v1_12 ), - PINK_CONCRETE_POWDER( "minecraft:pink_concrete_powder", MaterialType.BLOCK, MaterialVersion.v1_12 ), - GRAY_CONCRETE_POWDER( "minecraft:gray_concrete_powder", MaterialType.BLOCK, MaterialVersion.v1_12 ), - LIGHT_GRAY_CONCRETE_POWDER( "minecraft:light_gray_concrete_powder", MaterialType.BLOCK, MaterialVersion.v1_12 ), - CYAN_CONCRETE_POWDER( "minecraft:cyan_concrete_powder", MaterialType.BLOCK, MaterialVersion.v1_12 ), - - PURPLE_CONCRETE_POWDER( "minecraft:purple_concrete_powder", MaterialType.BLOCK, MaterialVersion.v1_12 ), - BLUE_CONCRETE_POWDER( "minecraft:blue_concrete_powder", MaterialType.BLOCK, MaterialVersion.v1_12 ), - BROWN_CONCRETE_POWDER( "minecraft:brown_concrete_powder", MaterialType.BLOCK, MaterialVersion.v1_12 ), - GREEN_CONCRETE_POWDER( "minecraft:green_concrete_powder", MaterialType.BLOCK, MaterialVersion.v1_12 ), - RED_CONCRETE_POWDER( "minecraft:red_concrete_powder", MaterialType.BLOCK, MaterialVersion.v1_12 ), - BLACK_CONCRETE_POWDER( "minecraft:black_concrete_powder", MaterialType.BLOCK, MaterialVersion.v1_12 ), - - - - - // Minecraft v1.13.x blocks: - - CAVE_AIR( "minecraft:cave_air", MaterialType.BLOCK, MaterialVersion.v1_13 ), - VOID_AIR( "minecraft:void_air", MaterialType.BLOCK, MaterialVersion.v1_13 ), - - BLUE_ICE( "minecraft:blue_ice", MaterialType.BLOCK, MaterialVersion.v1_13 ), - BUBBLE_COLUMN( "minecraft:bubble_column", MaterialType.BLOCK, MaterialVersion.v1_13 ), - - TUBE_CORAL( "minecraft:tube_coral", MaterialType.BLOCK, MaterialVersion.v1_13 ), - BRAIN_CORAL( "minecraft:brain_coral", MaterialType.BLOCK, MaterialVersion.v1_13 ), - BUBBLE_CORAL( "minecraft:bubble_coral", MaterialType.BLOCK, MaterialVersion.v1_13 ), - FIRE_CORAL( "minecraft:fire_coral", MaterialType.BLOCK, MaterialVersion.v1_13 ), - HORN_CORAL( "minecraft:horn_coral", MaterialType.BLOCK, MaterialVersion.v1_13 ), - - DEAD_TUBE_CORAL( "minecraft:dead_tube_coral", MaterialType.BLOCK, MaterialVersion.v1_13 ), - DEAD_BRAIN_CORAL( "minecraft:dead_brain_coral", MaterialType.BLOCK, MaterialVersion.v1_13 ), - DEAD_BUBBLE_CORAL( "minecraft:dead_bubble_coral", MaterialType.BLOCK, MaterialVersion.v1_13 ), - DEAD_FIRE_CORAL( "minecraft:dead_fire_coral", MaterialType.BLOCK, MaterialVersion.v1_13 ), - DEAD_HORN_CORAL( "minecraft:dead_horn_coral", MaterialType.BLOCK, MaterialVersion.v1_13 ), - - - TUBE_CORAL_BLOCK( "minecraft:tube_coral_block", MaterialType.BLOCK, MaterialVersion.v1_13 ), - BRAIN_CORAL_BLOCK( "minecraft:brain_coral_block", MaterialType.BLOCK, MaterialVersion.v1_13 ), - BUBBLE_CORAL_BLOCK( "minecraft:bubble_coral_block", MaterialType.BLOCK, MaterialVersion.v1_13 ), - FIRE_CORAL_BLOCK( "minecraft:fire_coral_block", MaterialType.BLOCK, MaterialVersion.v1_13 ), - HORN_CORAL_BLOCK( "minecraft:horn_coral_block", MaterialType.BLOCK, MaterialVersion.v1_13 ), - - DEAD_TUBE_CORAL_BLOCK( "minecraft:dead_tube_coral_block", MaterialType.BLOCK, MaterialVersion.v1_13 ), - DEAD_BRAIN_CORAL_BLOCK( "minecraft:dead_brain_coral_block", MaterialType.BLOCK, MaterialVersion.v1_13 ), - DEAD_BUBBLE_CORAL_BLOCK( "minecraft:dead_bubble_coral_block", MaterialType.BLOCK, MaterialVersion.v1_13 ), - DEAD_FIRE_CORAL_BLOCK( "minecraft:dead_fire_coral_block", MaterialType.BLOCK, MaterialVersion.v1_13 ), - DEAD_HORN_CORAL_BLOCK( "minecraft:dead_horn_coral_block", MaterialType.BLOCK, MaterialVersion.v1_13 ), - - - TUBE_CORAL_FAN( "minecraft:tube_coral_fan", MaterialType.BLOCK, MaterialVersion.v1_13 ), - BRAIN_CORAL_FAN( "minecraft:brain_coral_fan", MaterialType.BLOCK, MaterialVersion.v1_13 ), - BUBBLE_CORAL_FAN( "minecraft:bubble_coral_fan", MaterialType.BLOCK, MaterialVersion.v1_13 ), - FIRE_CORAL_FAN( "minecraft:fire_coral_fan", MaterialType.BLOCK, MaterialVersion.v1_13 ), - HORN_CORAL_FAN( "minecraft:horn_coral_fan", MaterialType.BLOCK, MaterialVersion.v1_13 ), - - DEAD_TUBE_CORAL_FAN( "minecraft:dead_tube_coral_fan", MaterialType.BLOCK, MaterialVersion.v1_13 ), - DEAD_BRAIN_CORAL_FAN( "minecraft:dead_brain_coral_fan", MaterialType.BLOCK, MaterialVersion.v1_13 ), - DEAD_BUBBLE_CORAL_FAN( "minecraft:dead_bubble_coral_fan", MaterialType.BLOCK, MaterialVersion.v1_13 ), - DEAD_FIRE_CORAL_FAN( "minecraft:dead_fire_coral_fan", MaterialType.BLOCK, MaterialVersion.v1_13 ), - DEAD_HORN_CORAL_FAN( "minecraft:dead_horn_coral_fan", MaterialType.BLOCK, MaterialVersion.v1_13 ), - - - TUBE_CORAL_WALL_FAN( "minecraft:tube_coral_wall_fan", MaterialType.BLOCK, MaterialVersion.v1_13 ), - BRAIN_CORAL_WALL_FAN( "minecraft:brain_coral_wall_fan", MaterialType.BLOCK, MaterialVersion.v1_13 ), - BUBBLE_CORAL_WALL_FAN( "minecraft:bubble_coral_wall_fan", MaterialType.BLOCK, MaterialVersion.v1_13 ), - FIRE_CORAL_WALL_FAN( "minecraft:fire_coral_wall_fan", MaterialType.BLOCK, MaterialVersion.v1_13 ), - HORN_CORAL_WALL_FAN( "minecraft:horn_coral_wall_fan", MaterialType.BLOCK, MaterialVersion.v1_13 ), - - DEAD_TUBE_CORAL_WALL_FAN( "minecraft:dead_tube_coral_wall_fan", MaterialType.BLOCK, MaterialVersion.v1_13 ), - DEAD_BRAIN_CORAL_WALL_FAN( "minecraft:dead_brain_coral_wall_fan", MaterialType.BLOCK, MaterialVersion.v1_13 ), - DEAD_BUBBLE_CORAL_WALL_FAN( "minecraft:dead_bubble_coral_wall_fan", MaterialType.BLOCK, MaterialVersion.v1_13 ), - DEAD_FIRE_CORAL_WALL_FAN( "minecraft:dead_fire_coral_wall_fan", MaterialType.BLOCK, MaterialVersion.v1_13 ), - DEAD_HORN_CORAL_WALL_FAN( "minecraft:dead_horn_coral_wall_fan", MaterialType.BLOCK, MaterialVersion.v1_13 ), - - - - - ACACIA_LOG( "minecraft:acacia_log", MaterialType.BLOCK, MaterialVersion.v1_13 ), - BIRCH_LOG( "minecraft:birch_log", MaterialType.BLOCK, MaterialVersion.v1_13 ), - DARK_OAK_LOG( "minecraft:dark_oak_log", MaterialType.BLOCK, MaterialVersion.v1_13 ), - JUNGLE_LOG( "minecraft:jungle_log", MaterialType.BLOCK, MaterialVersion.v1_13 ), - OAK_LOG( "minecraft:oak_log", MaterialType.BLOCK, MaterialVersion.v1_13 ), - SPRUCE_LOG( "minecraft:spruce_log", MaterialType.BLOCK, MaterialVersion.v1_13 ), - - - STRIPPED_ACACIA_LOG( "minecraft:stripped_acacia_log", MaterialType.BLOCK, MaterialVersion.v1_13 ), - STRIPPED_BIRCH_LOG( "minecraft:stripped_birch_log", MaterialType.BLOCK, MaterialVersion.v1_13 ), - STRIPPED_DARK_OAK_LOG( "minecraft:stripped_dark_oak_log", MaterialType.BLOCK, MaterialVersion.v1_13 ), - STRIPPED_JUNGLE_LOG( "minecraft:stripped_jungle_log", MaterialType.BLOCK, MaterialVersion.v1_13 ), - STRIPPED_OAK_LOG( "minecraft:stripped_oak_log", MaterialType.BLOCK, MaterialVersion.v1_13 ), - STRIPPED_SPRUCE_LOG( "minecraft:stripped_spruce_log", MaterialType.BLOCK, MaterialVersion.v1_13 ), - - STRIPPED_ACACIA_WOOD( "minecraft:stripped_acacia_wood", MaterialType.BLOCK, MaterialVersion.v1_13 ), - STRIPPED_BIRCH_WOOD( "minecraft:stripped_birch_wood", MaterialType.BLOCK, MaterialVersion.v1_13 ), - STRIPPED_DARK_OAK_WOOD( "minecraft:stripped_dark_oak_wood", MaterialType.BLOCK, MaterialVersion.v1_13 ), - STRIPPED_JUNGLE_WOOD( "minecraft:stripped_jungle_wood", MaterialType.BLOCK, MaterialVersion.v1_13 ), - STRIPPED_OAK_WOOD( "minecraft:stripped_oak_wood", MaterialType.BLOCK, MaterialVersion.v1_13 ), - STRIPPED_SPRUCE_WOOD( "minecraft:stripped_spruce_wood", MaterialType.BLOCK, MaterialVersion.v1_13 ), - - - - // Minecraft v1.14.x blocks: - BAMBOO( "minecraft:bamboo", MaterialType.BLOCK, MaterialVersion.v1_14 ), - BAMBOO_SAPLING( "minecraft:bamboo_sapling", MaterialType.BLOCK, MaterialVersion.v1_14 ), - - BARREL( "minecraft:barrel", MaterialType.BLOCK, MaterialVersion.v1_14 ), - BELL( "minecraft:bell", MaterialType.BLOCK, MaterialVersion.v1_14 ), - BLAST_FURNACE( "minecraft:blast_furnace", MaterialType.BLOCK, MaterialVersion.v1_14 ), - - CAMPFIRE( "minecraft:campfire", MaterialType.BLOCK, MaterialVersion.v1_14 ), - CARTOGRAPHY_TABLE( "minecraft:cartography_table", MaterialType.BLOCK, MaterialVersion.v1_14 ), - COMPOSTER( "minecraft:composter", MaterialType.BLOCK, MaterialVersion.v1_14 ), - FLETCHING_TABLE( "minecraft:fletching_table", MaterialType.BLOCK, MaterialVersion.v1_14 ), - //FLOWERS( "minecraft:bee_nest", MaterialType.BLOCK, MaterialVersion.v1_14 ), - GRINDSTONE( "minecraft:grindstone", MaterialType.BLOCK, MaterialVersion.v1_14 ), - JIGSAW( "minecraft:jigsaw", MaterialType.BLOCK, MaterialVersion.v1_14 ), - LANTERN( "minecraft:lantern", MaterialType.BLOCK, MaterialVersion.v1_14 ), - LECTERN( "minecraft:lectern", MaterialType.BLOCK, MaterialVersion.v1_14 ), - - LOOM( "minecraft:loom", MaterialType.BLOCK, MaterialVersion.v1_14 ), - // Already exists: NOTE_BLOCK( "minecraft:note_block", MaterialType.BLOCK, MaterialVersion.v1_14 ), - SCAFFOLDING( "minecraft:scaffolding", MaterialType.BLOCK, MaterialVersion.v1_14 ), - //SIGNS( "minecraft:bee_nest", MaterialType.BLOCK, MaterialVersion.v1_14 ), - //SLABS( "minecraft:bee_nest", MaterialType.BLOCK, MaterialVersion.v1_14 ), - SMITHING_TABLE( "minecraft:smithing_table", MaterialType.BLOCK, MaterialVersion.v1_14 ), - SMOKER( "minecraft:smoker", MaterialType.BLOCK, MaterialVersion.v1_14 ), - //STAIRS( "minecraft:bee_nest", MaterialType.BLOCK, MaterialVersion.v1_14 ), - STONECUTTER( "minecraft:stonecutter", MaterialType.BLOCK, MaterialVersion.v1_14 ), - SWEET_BERRY_BUSH( "minecraft:sweet_berry_bush", MaterialType.BLOCK, MaterialVersion.v1_14 ), - //WALLS( "minecraft:bee_nest", MaterialType.BLOCK, MaterialVersion.v1_14 ), - - - - - // Minecraft v1.15.x blocks: - BEE_NEST( "minecraft:bee_nest", MaterialType.BLOCK, MaterialVersion.v1_15 ), - BEEHIVE( "minecraft:beehive", MaterialType.BLOCK, MaterialVersion.v1_15 ), - HONEY_BLOCK( "minecraft:honey_block", MaterialType.BLOCK, MaterialVersion.v1_15 ), - HONEYCOMB_BLOCK( "minecraft:honeycomb_block", MaterialType.BLOCK, MaterialVersion.v1_15 ), - - - - // Minecraft v1.16.x blocks: - ANCIENT_DEBRIS( "minecraft:ancient_debris", MaterialType.BLOCK, MaterialVersion.v1_16 ), - CRYING_OBSIDIAN( "minecraft:crying_obsidian", MaterialType.BLOCK, MaterialVersion.v1_16 ), - NETHER_GOLD_ORE( "minecraft:nether_gold_ore", MaterialType.BLOCK, MaterialVersion.v1_16 ), - - - BASALT( "minecraft:basal", MaterialType.BLOCK, MaterialVersion.v1_16 ), - POLISHED_BASALT( "minecraft:polished_basalt", MaterialType.BLOCK, MaterialVersion.v1_16 ), - NETHERITE_BLOCK( "minecraft:netherite_block", MaterialType.BLOCK, MaterialVersion.v1_16 ), - - - BLACKSTONE( "minecraft:base_stone_blackstone", MaterialType.BLOCK, MaterialVersion.v1_16 ), - POLISHED_BLACKSTONE( "minecraft:polished_blackstone", MaterialType.BLOCK, MaterialVersion.v1_16 ), - CHISELED_POLISHED_BLACKSTONE( "minecraft:chiseled_polished_blackstone", MaterialType.BLOCK, MaterialVersion.v1_16 ), - - - NETHER_BRICKS( "minecraft:nether_bricks", MaterialType.BLOCK, MaterialVersion.v1_8 ), - RED_NETHER_BRICKS( "minecraft:red_nether_bricks", MaterialType.BLOCK, MaterialVersion.v1_10, "RED_NETHER_BRICK" ), - CRACKED_NETHER_BRICKS( "minecraft:cracked_nether_bricks", MaterialType.BLOCK, MaterialVersion.v1_16 ), - CHISELED_NETHER_BRICKS( "minecraft:chiseled_nether_bricks", MaterialType.BLOCK, MaterialVersion.v1_16 ), - - - CRIMSON_PLANKS( "minecraft:crimson_planks", MaterialType.BLOCK, MaterialVersion.v1_16 ), - WARPED_PLANKS( "minecraft:warped_planks", MaterialType.BLOCK, MaterialVersion.v1_16 ), - STRIPPED_CRIMSON_HYPHAE( "minecraft:stripped_crimson_hyphae", MaterialType.BLOCK, MaterialVersion.v1_16 ), - STRIPPED_WARPED_HYPHAE( "minecraft:stripped_warped_hyphae", MaterialType.BLOCK, MaterialVersion.v1_16 ), - NETHER_WART_BLOCK( "minecraft:nether_wart_block", MaterialType.BLOCK, MaterialVersion.v1_16 ), - WARPED_WART_BLOCK( "minecraft:warped_wart_block", MaterialType.BLOCK, MaterialVersion.v1_16 ), - - - LODESTONE( "minecraft:lodestone", MaterialType.BLOCK, MaterialVersion.v1_16 ), - QUARTZ_BRICKS( "minecraft:quartz_bricks", MaterialType.BLOCK, MaterialVersion.v1_16 ), - RESPAWN_ANCHOR( "minecraft:respawn_anchor", MaterialType.BLOCK, MaterialVersion.v1_16 ), - - - SHROOMLIGHT( "minecraft:shroomlight", MaterialType.BLOCK, MaterialVersion.v1_16 ), - SOUL_CAMPFIRE( "minecraft:soul_campfire", MaterialType.BLOCK, MaterialVersion.v1_16 ), - - - SOUL_LANTERN( "minecraft:soul_lantern", MaterialType.BLOCK, MaterialVersion.v1_16 ), - SOUL_TORCH( "minecraft:soul_torch", MaterialType.BLOCK, MaterialVersion.v1_16 ), - SOUL_SOIL( "minecraft:soul_soil", MaterialType.BLOCK, MaterialVersion.v1_16 ), - TARGET( "minecraft:target", MaterialType.BLOCK, MaterialVersion.v1_16 ), - - - TWISTING_VINES( "minecraft:twisting_vines", MaterialType.BLOCK, MaterialVersion.v1_16 ), - WEEPING_VINES( "minecraft:weeping_vines", MaterialType.BLOCK, MaterialVersion.v1_16 ), - - - - - - ; - // @formatter:on - - private final int legacyId; - private final String id; - private final short data; - private final MaterialType materialType; - private final MaterialVersion materialVersion; - - private final List altNames; - - ObsoleteBlockType(int legacyId, String id, int data, MaterialType materialType) { - this.legacyId = legacyId; - this.id = (id != null ? id : "minecraft:" + this.name().toLowerCase()); - this.data = (short) data; - this.materialType = materialType; - this.materialVersion = MaterialVersion.v1_8; - - this.altNames = new ArrayList<>(); - } - - - ObsoleteBlockType(int legacyId, String id, int data, MaterialType materialType, String... altNames) { - this( legacyId, id, data, materialType ); - - for ( String altName : altNames ) { - this.altNames.add( altName ); - } - } - - - - ObsoleteBlockType(String id, MaterialType materialType, MaterialVersion materialVersion, String... altNames ) { - this( id, materialType, materialVersion ); - - for ( String altName : altNames ) { - this.altNames.add( altName ); - } - } - - ObsoleteBlockType(String id, MaterialType materialType, MaterialVersion materialVersion ) { - this.legacyId = -1; - this.id = (id != null ? id : "minecraft:" + this.name().toLowerCase()); - this.data = 0; - this.materialType = materialType; - this.materialVersion = materialVersion; - - this.altNames = new ArrayList<>(); - } - - ObsoleteBlockType(MaterialType materialType) { - this(0, null, 0, materialType); - } - - ObsoleteBlockType(int legacyId, String id) { - this(legacyId, id, 0, MaterialType.NOT_SET); - } - - ObsoleteBlockType(int legacyId, String id, int data) { - this(legacyId, id, data, MaterialType.NOT_SET); - } - - /** - *

This function is for legacy versions of spigot that - * uses the data value. This function will returns a - * string value of a material name that - * XMaterial will be able to use to look up the correct - * bukkit material type. - *

- * - *

The way it needs to be constructed, is by taking the id, - * dropping the "minecraft:" prefix, then if data is non-zero, - * add a colon and the value of data. - *

- * - * - * @return - */ - public String getXMaterialNameLegacy() { - String xMatName = getId().replace( "minecraft:", "" ) + - ( getData() > 0 ? ":" + getData() : "" ); - return xMatName; - } - - /** - *

This function will return the lower case name of the BlockType. - * This should match - * @return - */ - public String getXMaterialName() { - return name().toLowerCase(); - } - - public List getXMaterialAltNames() { - return getAltNames(); - } - - public static ObsoleteBlockType getBlock(int legacyId) { - return getBlock(legacyId, (short) 0); - } - - public static ObsoleteBlockType getBlock(int legacyId, short data) { - for (ObsoleteBlockType block : values()) { - if (block.getLegacyId() == legacyId) { - if (block.getData() == data) { - return block; - } - } - } - return null; - } - - /** - * This is just an alias for getBlock() which checks for matches in - * many robust ways with numerous fall backs to ensure the best matching. - * @param key - * @return - */ - public static ObsoleteBlockType fromString( String key ) { - return getBlock( key ); - } - /** - *

Must search first on block name since the block id has potential for duplicates which - * will corrupt the block list for the mine. If at all possible, only search by the block name. - *

- * - * @param key Block name, id, or number. - * @return - */ - public static ObsoleteBlockType getBlock(String key) { - ObsoleteBlockType blockType = getBlockByName( key ); - if ( blockType == null ) { - blockType = getBlockById( key ); - } - if ( blockType == null ) { - blockType = getBlockByXMaterialName(key); - } - - return blockType; - } - - private static ObsoleteBlockType getBlockById(String id) { - for (ObsoleteBlockType block : values()) { - if (block.getId().equalsIgnoreCase(id) || block.name().equalsIgnoreCase(id) || - block.getId().equalsIgnoreCase( "minecraft:" + id )) { - return block; - } - } - boolean isInt = false; - try { - Integer.parseInt(id.replaceAll(":", "")); - isInt = true; - } catch (Exception e) { - isInt = false; - } - if (isInt) { - if (!id.contains(":")) { - return getBlockWithData(Integer.parseInt(id), (short) 0); - } - return getBlockWithData(Integer.parseInt(id.split(":")[0]), - Short.parseShort(id.split(":")[1])); - } -// Prison prison = Prison.get(); -// if ( prison != null && prison.getItemManager() != null ) { -// Set>> entrySet = prison.getItemManager().getItems().entrySet(); -// for (Map.Entry> entry : entrySet) { -// if (entry.getValue().contains(id.toLowerCase())) { -// return entry.getKey(); -// } -// } -// -// return getBlockByName(id); -// } - return null; - } - - private static ObsoleteBlockType getBlockByName(String name) { - for (ObsoleteBlockType block : values()) { - if (block.name().equalsIgnoreCase(name)) { - return block; - } - } - return null; - } - - private static ObsoleteBlockType getBlockByXMaterialName(String name) { - for (ObsoleteBlockType block : values()) { - if (block.getXMaterialAltNames().size() > 0 ) { - for ( String altName : block.getXMaterialAltNames() ) { - - if ( altName.equalsIgnoreCase(name)) { - return block; - } - } - } - - } - return null; - } - - public static ObsoleteBlockType getBlockWithData(int id, short data) { - for (ObsoleteBlockType block : values()) { - if (block.getLegacyId() == id && block.getData() == data) { - return block; - } - } - return null; - } - - public static boolean isDoor(ObsoleteBlockType block) { - return block == ACACIA_DOOR_BLOCK || block == BIRCH_DOOR_BLOCK - || block == DARK_OAK_DOOR_BLOCK || block == IRON_DOOR_BLOCK - || block == JUNGLE_DOOR_BLOCK || block == OAK_DOOR_BLOCK || block == SPRUCE_DOOR_BLOCK; - } - - public int getLegacyId() { - return legacyId; - } - - public String getId() { - return id; - } - - public short getData() { - return data; - } - - public boolean isBlock() { - return materialType == MaterialType.BLOCK; - } - - public boolean isItem() { - return materialType == MaterialType.ITEM; - } - - public MaterialType getMaterialType() { - return materialType; - } - - public MaterialVersion getMaterialVersion() { - return materialVersion; - } - - public List getAltNames() { - return altNames; - } - - @Override public String toString() { - return id + ":" + data; - } } diff --git a/prison-core/src/main/java/tech/mcprison/prison/util/PrisonJarReporter.java b/prison-core/src/main/java/tech/mcprison/prison/util/PrisonJarReporter.java index 9f29a2ec6..4086a1f76 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/util/PrisonJarReporter.java +++ b/prison-core/src/main/java/tech/mcprison/prison/util/PrisonJarReporter.java @@ -257,16 +257,6 @@ public void scanForJars() { // These are not our plugins, so if there is a problem, then it really does not matter } -// catch ( ZipException e ) -// { -// e.printStackTrace(); -// } -// catch ( IOException e ) -// { -// e.printStackTrace(); -// } - - } } 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 dd604581b..be5846f61 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 @@ -341,13 +341,6 @@ public StringBuilder getSupportSubmitRanksData() { 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; } @@ -368,8 +361,6 @@ public StringBuilder getSupportSubmitRanksFileData() { } public StringBuilder getSupportSubmitMinesData() { -// List files = listFiles("data_storage/mines/mines/", ".json"); -// Collections.sort(files); StringBuilder text = new StringBuilder(); @@ -383,13 +374,6 @@ public StringBuilder getSupportSubmitMinesData() { // Display a list of all mines, then display the /mines info all for // each: text.append(Prison.get().getPlatform().getMinesListString()); -// printFooter(text); - -// // get all the file details for each mine: -// for (File file : files) { -// -// addFileToText(file, text); -// } return text; } @@ -419,48 +403,42 @@ public StringBuilder getSupportSubmitListenersData( String listenerType ) { listenerType = "all"; } - if ( "blockBreak".equalsIgnoreCase( listenerType ) || "all".equalsIgnoreCase( listenerType ) ) { - - sb.append( "||Listeners blockBreak||" ); - sb.append( Prison.get().getPlatform().dumpEventListenersBlockBreakEvents() ); - } - - if ( "blockPlace".equalsIgnoreCase( listenerType ) || "all".equalsIgnoreCase( listenerType ) ) { - - sb.append( "||Listeners blockPlace||" ); - sb.append( Prison.get().getPlatform().dumpEventListenersBlockPlaceEvents() ); - } - - if ( "chat".equalsIgnoreCase( listenerType ) || "all".equalsIgnoreCase( listenerType ) ) { - - sb.append( "||Listeners chat||" ); - sb.append( Prison.get().getPlatform().dumpEventListenersPlayerChatEvents() ); - } - -// if ( "traceBlockBreak".equalsIgnoreCase( listenerType ) ) { -// -// Prison.get().getPlatform().traceEventListenersBlockBreakEvents( sender ); -// -// } - - if ( "playerInteract".equalsIgnoreCase( listenerType ) || "all".equalsIgnoreCase( listenerType ) ) { - - sb.append( "||Listeners playerInteract||" ); - sb.append( Prison.get().getPlatform().dumpEventListenersPlayerInteractEvents() ); - } - - if ( "playerDropItem".equalsIgnoreCase( listenerType ) || "all".equalsIgnoreCase( listenerType ) ) { - - sb.append( "||Listeners playerDropItem||" ); - sb.append( Prison.get().getPlatform().dumpEventListenersPlayerDropItemEvents() ); - } - - if ( "playerPickupItem".equalsIgnoreCase( listenerType ) || "all".equalsIgnoreCase( listenerType ) ) { - - sb.append( "||Listeners playerPickupItem||" ); - sb.append( Prison.get().getPlatform().dumpEventListenersPlayerPickupItemEvents() ); - } - + if ( "blockBreak".equalsIgnoreCase( listenerType ) || "all".equalsIgnoreCase( listenerType ) ) { + + sb.append( "||Listeners blockBreak||" ); + sb.append( Prison.get().getPlatform().dumpEventListenersBlockBreakEvents() ); + } + + if ( "blockPlace".equalsIgnoreCase( listenerType ) || "all".equalsIgnoreCase( listenerType ) ) { + + sb.append( "||Listeners blockPlace||" ); + sb.append( Prison.get().getPlatform().dumpEventListenersBlockPlaceEvents() ); + } + + if ( "chat".equalsIgnoreCase( listenerType ) || "all".equalsIgnoreCase( listenerType ) ) { + + sb.append( "||Listeners chat||" ); + sb.append( Prison.get().getPlatform().dumpEventListenersPlayerChatEvents() ); + } + + if ( "playerInteract".equalsIgnoreCase( listenerType ) || "all".equalsIgnoreCase( listenerType ) ) { + + sb.append( "||Listeners playerInteract||" ); + sb.append( Prison.get().getPlatform().dumpEventListenersPlayerInteractEvents() ); + } + + if ( "playerDropItem".equalsIgnoreCase( listenerType ) || "all".equalsIgnoreCase( listenerType ) ) { + + sb.append( "||Listeners playerDropItem||" ); + sb.append( Prison.get().getPlatform().dumpEventListenersPlayerDropItemEvents() ); + } + + if ( "playerPickupItem".equalsIgnoreCase( listenerType ) || "all".equalsIgnoreCase( listenerType ) ) { + + sb.append( "||Listeners playerPickupItem||" ); + sb.append( Prison.get().getPlatform().dumpEventListenersPlayerPickupItemEvents() ); + } + return sb; } @@ -474,9 +452,9 @@ public StringBuilder getCommandStatsDetailData() { List cmds = getCommandStats(); cmds.add( 1, "||CommandStats List||" ); - for (String cmd : cmds) { - - sb.append( cmd ).append( "\n" ); + for (String cmd : cmds) { + + sb.append( cmd ).append( "\n" ); } return sb; @@ -497,41 +475,41 @@ private List getCommandStats() { 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(); - } + 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. " ); + + 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; @@ -541,13 +519,13 @@ private List getCommandStats() { public StringBuilder getPrisonBackupLogsData() { StringBuilder sb = new StringBuilder(); - // Include Prison backup logs: + // 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" ); + List backupLogs = getPrisonBackupLogs(); + + for (String log : backupLogs) { + sb.append( Output.decodePercentEncoding(log) ).append( "\n" ); } return sb; @@ -555,9 +533,9 @@ public StringBuilder getPrisonBackupLogsData() { public List getPrisonBackupLogs() { - PrisonBackups prisonBackup = new PrisonBackups(); - List backupLogs = prisonBackup.backupReport02BackupLog(); - return backupLogs; + PrisonBackups prisonBackup = new PrisonBackups(); + List backupLogs = prisonBackup.backupReport02BackupLog(); + return backupLogs; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/util/PrisonTPSSingleton.java b/prison-core/src/main/java/tech/mcprison/prison/util/PrisonTPSSingleton.java index cc2a094b9..58d6eab47 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/util/PrisonTPSSingleton.java +++ b/prison-core/src/main/java/tech/mcprison/prison/util/PrisonTPSSingleton.java @@ -339,72 +339,63 @@ public void setHighResolution( boolean highResolution ) { * @return */ public double getAverageTPS() { - double avg = 0d; - - int cnt = 0; - - // Start collecting readings from the tail-end of the tpsHistory collection - // since that is the most recent reading: - synchronized ( tpsLock ) { - - for ( int i = tpsHistory.size(); i > 0; i-- ) { - double reading = tpsHistory.get( i - 1 ); - - // Ignore readings above TPS_THRESHOLD_TO_RECORD - if ( reading <= TPS_THRESHOLD_TO_RECORD ) { - avg += reading; - - // Once we get our target count, then break out of the for loop: - if ( cnt++ < TPS_AVERAGE_READINGS_TO_INCLUDE ) { - break; - } - } - } - } - - // Do not divide avg by count if zero or one: - if ( cnt > 1 ) { - avg /= cnt; - } - return avg; - - // The following was averaging all counts in the history, including very high values. - // This is no longer favorable. -// for (final Double f : tpsHistory) { -// if (f != null) { -// avg += f; -// } -// } -// return tpsHistory.size() == 0 ? 0 : avg / tpsHistory.size(); + double avg = 0d; + + int cnt = 0; + + // Start collecting readings from the tail-end of the tpsHistory collection + // since that is the most recent reading: + synchronized ( tpsLock ) { + + for ( int i = tpsHistory.size(); i > 0; i-- ) { + double reading = tpsHistory.get( i - 1 ); + + // Ignore readings above TPS_THRESHOLD_TO_RECORD + if ( reading <= TPS_THRESHOLD_TO_RECORD ) { + avg += reading; + + // Once we get our target count, then break out of the for loop: + if ( cnt++ < TPS_AVERAGE_READINGS_TO_INCLUDE ) { + break; + } + } + } + } + + // Do not divide avg by count if zero or one: + if ( cnt > 1 ) { + avg /= cnt; + } + return avg; } public String getAverageTPSFormatted() { - return tpsFmt.format( getAverageTPS() ); + return tpsFmt.format( getAverageTPS() ); } public String getTPSMinFormatted() { - return tpsFmt.format( getTpsMin() ); + return tpsFmt.format( getTpsMin() ); } public String getTPSMaxFormatted() { - return tpsFmt.format( getTpsMax() ); + return tpsFmt.format( getTpsMax() ); } public String getLastFewTPS() { - StringBuilder sb = new StringBuilder(); - - int cnt = 0; - - synchronized ( tpsLock ) { - - for ( int i = tpsHistory.size(); i > 0 && cnt++ < 15; i-- ) { - sb.append( tpsFmt.format( tpsHistory.get( i - 1 ) ) ).append( " " ); - } - } - - return sb.toString(); + StringBuilder sb = new StringBuilder(); + + int cnt = 0; + + synchronized ( tpsLock ) { + + for ( int i = tpsHistory.size(); i > 0 && cnt++ < 15; i-- ) { + sb.append( tpsFmt.format( tpsHistory.get( i - 1 ) ) ).append( " " ); + } + } + + return sb.toString(); } 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 06b783a0f..8ca681dfb 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 @@ -113,13 +113,13 @@ public class Text private static DecimalFormat iFmt = Prison.getDecimalFormatStaticInt(); static { - if ( Prison.get() != null ) { - - } + if ( Prison.get() != null ) { + + } } protected Text() { - super(); + super(); } @@ -352,7 +352,7 @@ public static String implodeCommaAnd(final Collection objects) { * @return The translated string. */ public static String translateColorCodes(String text, char prefix) { - return translateColorCodes( text, prefix, COLOR_CHAR, COLOR_CHAR ); + return translateColorCodes( text, prefix, COLOR_CHAR, COLOR_CHAR ); } @@ -435,7 +435,7 @@ public static String translateAmpColorCodes(String text) { * @return */ public static String translateAmpColorCodesAltHexCode(String text) { - return translateColorCodes( text, '&', COLOR_CHAR, '&' ); + return translateColorCodes( text, '&', COLOR_CHAR, '&' ); } // NOTE: It's not needed to remove the '&' @@ -475,40 +475,40 @@ public static String stripColor(String text) { * @return */ protected static String translateHexColorCodes( String text, char targetColorCode ) { - StringBuilder sb = new StringBuilder(); - - if ( text != null && !text.trim().isEmpty() ) { - - int idxStart = text.indexOf( "\\Q" ); - int idxEnd = -1; - - if ( idxStart == -1 ) { - sb.append( translateHexColorCodesCore( text, targetColorCode ) ); - } - else { - while ( idxStart >= 0 ) { - sb.append( translateHexColorCodesCore( - text.substring( idxEnd + (idxEnd == -1 ? 1 : 0), idxStart ), targetColorCode) ); - - idxEnd = text.indexOf( "\\E", idxStart ); - - if ( idxEnd == -1 ) { - sb.append( text.substring( idxStart ) ); - idxStart = -1; - } - else { - sb.append( text.substring( idxStart, idxEnd ) ); - - idxStart = text.indexOf( "\\Q", idxEnd ); - } - } - if ( idxStart == -1 && idxEnd >= 0 && (idxEnd) < text.length() ) { - sb.append( text.substring( idxEnd ) ); - } - } - } - - return sb.toString(); + StringBuilder sb = new StringBuilder(); + + if ( text != null && !text.trim().isEmpty() ) { + + int idxStart = text.indexOf( "\\Q" ); + int idxEnd = -1; + + if ( idxStart == -1 ) { + sb.append( translateHexColorCodesCore( text, targetColorCode ) ); + } + else { + while ( idxStart >= 0 ) { + sb.append( translateHexColorCodesCore( + text.substring( idxEnd + (idxEnd == -1 ? 1 : 0), idxStart ), targetColorCode) ); + + idxEnd = text.indexOf( "\\E", idxStart ); + + if ( idxEnd == -1 ) { + sb.append( text.substring( idxStart ) ); + idxStart = -1; + } + else { + sb.append( text.substring( idxStart, idxEnd ) ); + + idxStart = text.indexOf( "\\Q", idxEnd ); + } + } + if ( idxStart == -1 && idxEnd >= 0 && (idxEnd) < text.length() ) { + sb.append( text.substring( idxEnd ) ); + } + } + } + + return sb.toString(); } /** @@ -521,44 +521,44 @@ protected static String translateHexColorCodes( String text, char targetColorCod * @return */ private static String translateHexColorCodesCore(String message, char targetColorCode) { - String results = ""; - - if ( message != null ) { - - // NOTE: if '&#' is used, then it will convert the hex codes, but it will also - // leave the leading '&' there. So remove the '&' prefix. - if ( message != null && message.contains( "&#" ) ) { - message = message.replace( "&#", "#" ); - } - -// final Pattern hexPattern = Pattern.compile(startTag + "([A-Fa-f0-9]{6})" + endTag); - - Matcher matcher = HEX_PATTERN.matcher(message); - StringBuffer buffer = new StringBuffer(message.length() + 4 * 8); - while (matcher.find()) { - String group = matcher.group(1); - matcher.appendReplacement(buffer, targetColorCode + "x" - + targetColorCode + group.charAt(0) + targetColorCode + group.charAt(1) - + targetColorCode + group.charAt(2) + targetColorCode + group.charAt(3) - + targetColorCode + group.charAt(4) + targetColorCode + group.charAt(5) - ); - } - results = matcher.appendTail(buffer).toString(); - } - - return results; + String results = ""; + + if ( message != null ) { + + // NOTE: if '&#' is used, then it will convert the hex codes, but it will also + // leave the leading '&' there. So remove the '&' prefix. + if ( message != null && message.contains( "&#" ) ) { + message = message.replace( "&#", "#" ); + } + + // final Pattern hexPattern = Pattern.compile(startTag + "([A-Fa-f0-9]{6})" + endTag); + + Matcher matcher = HEX_PATTERN.matcher(message); + StringBuffer buffer = new StringBuffer(message.length() + 4 * 8); + while (matcher.find()) { + String group = matcher.group(1); + matcher.appendReplacement(buffer, targetColorCode + "x" + + targetColorCode + group.charAt(0) + targetColorCode + group.charAt(1) + + targetColorCode + group.charAt(2) + targetColorCode + group.charAt(3) + + targetColorCode + group.charAt(4) + targetColorCode + group.charAt(5) + ); + } + results = matcher.appendTail(buffer).toString(); + } + + return results; } private static String convertToAmpColorCodes( String textEncoded ) { - String results = textEncoded; - - if ( textEncoded != null && textEncoded.contains( COLOR_ ) ) { - results = textEncoded.replaceAll( COLOR_, "&" ); - } - - return results; + String results = textEncoded; + + if ( textEncoded != null && textEncoded.contains( COLOR_ ) ) { + results = textEncoded.replaceAll( COLOR_, "&" ); + } + + return results; } /** @@ -573,7 +573,7 @@ private static String convertToAmpColorCodes( String textEncoded ) { * @return */ public static String escapeAmpCodes( String textEncoded ) { - return convertToAmpColorCodes(textEncoded).replaceAll("&", "U+0026"); + return convertToAmpColorCodes(textEncoded).replaceAll("&", "U+0026"); } /** @@ -649,17 +649,17 @@ public static String tab(String text) { * @return The human-readable string. */ public static String getTimeUntilString(long millis) { - return getTimeUntilString( millis, unitMillis, unitPrefixSpacer, null ); + return getTimeUntilString( millis, unitMillis, unitPrefixSpacer, null ); } public static String getTimeUntilString(long millis, String spaces ) { - return getTimeUntilString( millis, unitMillis, spaces, null ); + return getTimeUntilString( millis, unitMillis, spaces, null ); } public static String getTimeUntilShortString(long millis, String spaces ) { - return getTimeUntilString( millis, unitMillisShort, spaces, null ); + 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 ); + DecimalFormat dFmt = new DecimalFormat( "00" ); + return getTimeUntilString( millis, unitMillisColons, spaces, dFmt ); } private static String getTimeUntilString(long millis, Map units, String unitSpacer, DecimalFormat dFmt ) { @@ -725,16 +725,16 @@ public static String pluralize(String baseNoun, int quantity) { public static String formatTimeDaysHhMmSs( long timeMs ) { - DecimalFormat iFmt = Prison.getDecimalFormatStaticInt(); - DecimalFormat tFmt = Prison.getDecimalFormatStatic("00"); + DecimalFormat iFmt = Prison.getDecimalFormatStaticInt(); + DecimalFormat tFmt = Prison.getDecimalFormatStatic("00"); // SimpleDateFormat sdFmt = new SimpleDateFormat( "HH:mm:ss" ); // long _sec = 1000; // long _min = _sec * 60; // long _hour = _min * 60; // long _day = _hour * 24; - - long ms = timeMs; + + long ms = timeMs; long days = millisPerDay < ms ? ms / millisPerDay : 0; ms -= (days * millisPerDay); @@ -760,22 +760,18 @@ public static String formatTimeDaysHhMmSs( long timeMs ) { public static List formatTreeMapStats( TreeMap statMap, int columns ) { - return formatTreeMapStats( statMap, columns, false ); + return formatTreeMapStats( statMap, columns, false ); } public static List formatTreeMapStats( TreeMap statMap, int columns, boolean timeFormat ) { - List msgs = new ArrayList<>(); + List msgs = new ArrayList<>(); Set keys = statMap.keySet(); List values = new ArrayList<>(); -// List valueMaxLen = new ArrayList<>(); - -// StringBuilder sb = new StringBuilder(); -// int count = 0; for ( String earningKey : keys ) { @@ -804,84 +800,31 @@ else if ( valueObj instanceof Long ) { String msg = String.format( "&3%s&8: &b%s", earningKey, value ).trim(); -// String msgNoColor = Text.stripColor( msg ); -// int lenMNC = msgNoColor.length(); -// -// -// int col = values.size() % columns; values.add( msg ); -// if ( col >= valueMaxLen.size() || lenMNC > valueMaxLen.get( col ) ) { -// -// if ( col > valueMaxLen.size() - 1 ) { -// valueMaxLen.add( lenMNC ); -// } -// else { -// -// valueMaxLen.set( col, lenMNC ); -// } -// } } msgs = formatColumnsFromList( values, columns ); - -// for ( int j = 0; j < values.size(); j++ ) -// { -// String msg = values.get( j ); -// -// int col = j % columns; -// -// int maxColumnWidth = col > valueMaxLen.size() - 1 ? -// msg.length() : -// valueMaxLen.get( col ); -// -// sb.append( msg ); -// -// // Pad the right of all content with spaces to align columns, up to a -// // given maxLength: -// String msgNoColor = Text.stripColor( msg ); -// int lenMNC = msgNoColor.length(); -// for( int i = lenMNC; i < maxColumnWidth; i++ ) { -// sb.append( " " ); -// } -// -// // The spacer: -// sb.append( " " ); -// -// if ( ++count % columns == 0 ) { -// msgs.add( String.format( -// " " + sb.toString() ) ); -// sb.setLength( 0 ); -// -// } -// } -// -// if ( sb.length() > 0 ) { -// -// msgs.add( String.format( -// " " + sb.toString() ) ); -// } - - return msgs; + + return msgs; } public static List formatColumnsFromList( List textItems, int columns ) { - List msgs = new ArrayList<>(); - - List valueMaxLen = new ArrayList<>(); - - StringBuilder sb = new StringBuilder(); - int count = 0; - - // Find the maxLenght value for each column that will be generated: - for ( int i = 0; i < textItems.size(); i++ ) - { - String msg = textItems.get( i ); - - String msgNoColor = Text.stripColor( msg ); + List msgs = new ArrayList<>(); + + List valueMaxLen = new ArrayList<>(); + + StringBuilder sb = new StringBuilder(); + int count = 0; + + // Find the maxLenght value for each column that will be generated: + for ( int i = 0; i < textItems.size(); i++ ) { + String msg = textItems.get( i ); + + String msgNoColor = Text.stripColor( msg ); int lenMNC = msgNoColor.length(); @@ -898,7 +841,7 @@ public static List formatColumnsFromList( List textItems, } } } - + for ( int j = 0; j < textItems.size(); j++ ) { @@ -930,14 +873,14 @@ public static List formatColumnsFromList( List textItems, } } - + if ( sb.length() > 0 ) { msgs.add( String.format( " " + sb.toString() ) ); } - - return msgs; + + return msgs; } } diff --git a/prison-core/src/main/java/tech/mcprison/prison/util/Vector.java b/prison-core/src/main/java/tech/mcprison/prison/util/Vector.java index 1ed0850a8..b9695b6f1 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/util/Vector.java +++ b/prison-core/src/main/java/tech/mcprison/prison/util/Vector.java @@ -617,7 +617,8 @@ public int getBlockZ() { * to account for floating point errors. The epsilon can be retrieved * with epsilon. */ - @Override public boolean equals(Object obj) { + @Override + public boolean equals(Object obj) { if (!(obj instanceof Vector)) { return false; } @@ -633,7 +634,8 @@ public int getBlockZ() { * * @return hash code */ - @Override public int hashCode() { + @Override + public int hashCode() { int hash = 7; hash = 79 * hash + (int) (Double.doubleToLongBits(this.x) ^ (Double.doubleToLongBits(this.x) @@ -650,7 +652,8 @@ public int getBlockZ() { * * @return vector */ - @Override public Vector clone() { + @Override + public Vector clone() { try { return (Vector) super.clone(); } catch (CloneNotSupportedException e) { @@ -661,26 +664,19 @@ public int getBlockZ() { /** * Returns this vector's components as x,y,z. */ - @Override public String toString() { + @Override + public String toString() { - DecimalFormat dFmt = new DecimalFormat( "##0.0000" ); - - String msg = String.format( - "x: %8s y: %8s z: %8s", - dFmt.format( getX() ), - dFmt.format( getY() ), - dFmt.format( getZ() ) - ); - - return msg; - -// StringBuilder sb = new StringBuilder(); -// sb.append( "x: " ).append( dFmt.format( getX() )).append( " " ) -// .append( "y: " ).append( dFmt.format( getY() )).append( " " ) -// .append( "z: " ).append( dFmt.format( getZ() )); -// -// return sb.toString(); -// return x + "," + y + "," + z; + DecimalFormat dFmt = new DecimalFormat( "##0.0000" ); + + String msg = String.format( + "x: %8s y: %8s z: %8s", + dFmt.format( getX() ), + dFmt.format( getY() ), + dFmt.format( getZ() ) + ); + + return msg; } /** From e164e065fe9eba121b8272a19cc1317dc1a7e244 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 6 Mar 2026 13:00:57 -0500 Subject: [PATCH 307/323] Design documents: Starting to create some of the design and planning documents that will be needed in the next few phrases of Prison. --- build.gradle | 131 +++++++++++++++++++++++++++++++++ docs/changelog_v3.3.x.md | 3 + zipDocs/ARCHITECTURE.md | 60 +++++++++++++++ zipDocs/DEPENDENCIES.md | 77 +++++++++++++++++++ zipDocs/PHASE_0_GOALS.md | 25 +++++++ zipDocs/SYSTEM_INSTRUCTIONS.md | 14 ++++ 6 files changed, 310 insertions(+) create mode 100644 zipDocs/ARCHITECTURE.md create mode 100644 zipDocs/DEPENDENCIES.md create mode 100644 zipDocs/PHASE_0_GOALS.md create mode 100644 zipDocs/SYSTEM_INSTRUCTIONS.md diff --git a/build.gradle b/build.gradle index eca3fcf16..11cb16991 100644 --- a/build.gradle +++ b/build.gradle @@ -167,6 +167,137 @@ wrapper { distributionType = Wrapper.DistributionType.ALL } +tasks.register('zipSource', Zip) { + group = 'prison' + description = 'Creates a versioned ZIP of source, resources, and all Gradle/AI metadata.' + + archiveBaseName = "Prison-Context" + archiveVersion = project.version + destinationDirectory = file("$rootDir/zip_snapshots") + + // 1. Root Orchestration Files + from(rootDir) { + include 'build.gradle' + include 'settings.gradle' + include 'gradle.properties' + include 'gradle/libs.versions.toml' + } + + // 2. The "Brain" Folder (Your AI metadata) + from("$rootDir/zipDocs") { + into('metadata') + } + + // 3. Sub-project Source, Resources, and their specific build.gradle + subprojects.each { sub -> + from(sub.projectDir) { + include 'src/main/java/**' + include 'src/main/resources/**' + include 'build.gradle' // Each module's specific build file + + into(sub.name) + } + } + + // Exclusions to keep the "Millionaire" tokens focused + exclude '**/build/**' + exclude '**/.gradle/**' + exclude '**/.settings/**' + exclude '**/bin/**' + exclude '**/out/**' +} + + +tasks.register('concatSource') { + group = 'prison' + description = 'Concatenates source, resources, and metadata into a single AI-friendly text file.' + + // Set the output directory and filename + def outputDir = file("$rootDir/zip_snapshots") + def outputFile = new File(outputDir, "Prison-Context-${project.version}.txt") + + // The actual work must happen in the execution phase (doLast) + doLast { + outputDir.mkdirs() + + // Clear the file if it already exists from a previous run + if (outputFile.exists()) { + outputFile.text = '' + } else { + outputFile.createNewFile() + } + + println "Generating AI context file at: ${outputFile.absolutePath}" + + // Helper closure to process a file tree and append to the text file + def processTree = { FileTree tree -> + tree.matching { + // Your standard exclusions + exclude '**/build/**' + exclude '**/.gradle/**' + exclude '**/.settings/**' + exclude '**/bin/**' + exclude '**/out/**' + // Added safeguards: prevent sneaky binary files in resources from turning to gibberish + exclude '**/*.png', '**/*.jpg', '**/*.jpeg', '**/*.gif', '**/*.ico', '**/*.jar', '**/*.zip' + }.each { File f -> + if (f.isFile()) { + // Calculate the relative path from the root directory + def relativePath = rootDir.toPath().relativize(f.toPath()).toString() + + // Normalize separators so Windows backslashes become standard forward slashes + relativePath = relativePath.replace('\\', '/') + + // Append the header and file contents + outputFile.append("================================================================\n") + outputFile.append("File: ${relativePath}\n") + outputFile.append("================================================================\n") + outputFile.append(f.text + "\n\n") + } + } + } + + // 0. The Prime Directives (Force these to the absolute top) + // The "Brain" Folder + def brainFilesSI = fileTree(dir: "$rootDir/zipDocs", + includes: ['SYSTEM_INSTRUCTIONS.md']) + processTree(brainFilesSI) + + def brainFiles = fileTree(dir: "$rootDir/zipDocs", + excludes: ['SYSTEM_INSTRUCTIONS.md']) + processTree(brainFiles) + + + // 1. Root Orchestration Files + def rootFiles = fileTree(dir: rootDir, includes: [ + 'build.gradle', + 'settings.gradle', + 'gradle.properties', + 'gradle/libs.versions.toml' + ]) + processTree(rootFiles) + + // 2. Sub-project Source, Resources, and specific build scripts + // Define the sub-projects you want to skip + def excludedProjects = ['prison-spigot-alt', 'prison-worldguard7'] + + subprojects.each { sub -> + // Only process the sub-project if its name is NOT in the excluded list + if (!excludedProjects.contains(sub.name)) { + def subFiles = fileTree(dir: sub.projectDir, includes: [ + 'src/main/java/**', + 'src/main/resources/**', + 'build.gradle' + ]) + processTree(subFiles) + } + } + + println "Successfully concatenated Millionaire tokens into ${outputFile.name}" + } +} + + def getCurrentTimestamp() { SimpleDateFormat df = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss") diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 37b0da3d0..c738fcf9b 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.19j 2026-03-06 +* **Design documents: Starting to create some of the design and planning documents that will be needed in the next few phrases of Prison.** + + * **Prison Cleanup: prison-core: Removed obsolete and unneeded comments and fix indentation where needed.** First part. diff --git a/zipDocs/ARCHITECTURE.md b/zipDocs/ARCHITECTURE.md new file mode 100644 index 000000000..de5943c8b --- /dev/null +++ b/zipDocs/ARCHITECTURE.md @@ -0,0 +1,60 @@ +# Prison Project Architecture + +## Overview +Prison is a high-performance Minecraft prison management suite consisting of ~91k lines of Java. It is designed for scale, handling massive world edits (80k+ blocks) and high-frequency transactions with zero server lag. Prison manages the players, their ranks and related leveling, along with the building and management of mines. The players can mine blocks, which earns them money and experience, which allows them to rankup. + +## Module Responsibilities +* **prison-core:** The "brain." Contains business logic, player data models, and currency caching. + * **STRICT RULE:** No Spigot/Bukkit API dependencies allowed here. + +* **prison-mines:** Feature-specific modules that build upon the core and API. + * **STRICT RULE:** No Spigot/Bukkit API dependencies allowed here. + +* **prison-misc:** These are source code stubs that are used only for compiling Prison source code, since we do not have access to these various plugin's API jars. These don't require any functionality, they just need to provide class and method signatures. + * **STRICT RULE:** The Sigot/Bukkit API dependencies can be used in this module. + +* **prison-ranks:** Provides player rank logic and leveling. Feature-specific modules that build upon the core and API. + * **STRICT RULE:** No Spigot/Bukkit API dependencies allowed here. + +* **prison-sellall:** Provides the ability to sell their inventory based upon shop item lists and prices. This also handles autosell capabilities that allows the mined blocks to be sold instantly without going in to the player's inventory. + * **STRICT RULE:** No Spigot/Bukkit API dependencies allowed here. + +* **prison-spigot:** The implementation layer. Handles block-breaking, explosions, and all `org.bukkit` related interactions. + * **STRICT RULE:** The Sigot/Bukkit API dependencies can be used in this module. + +* **prison-spigot-alt:** Ignore. This was an experiment to force a slightly different spigot build. + +* **prison-mines-legacy:** Ignore. This is obsolete and outdated code that is kept for no good reason. + +* **prison-sponge:** Ignore. This is an obsolete support for the sponge flavor minecraft. It is seriously lacking all of the same classes that prison-spigot currently has, so it won't be able easily be updated. + +* **prison-worldguard6:** Not sure if this is actually used yet. This was going to provide hooks to support WorldGuard v6 API calls so prison can perform more complex operations during a mine reset by basically in bedding scripts in the mine reset instructions. + * **STRICT RULE:** The Sigot/Bukkit API dependencies can be used in this module. + +* **prison-worldguard7:** Not sure if this is actually used yet. This was going to provide hooks to support WorldGuard v6 API calls so prison can perform more complex operations during a mine reset by basically in bedding scripts in the mine reset instructions. + * **STRICT RULE:** The Sigot/Bukkit API dependencies can be used in this module. + + +## Critical Design Patterns +* **Self-Aware Batching:** Our block-state updates (explosions/resets) use a time-sliced execution model. They yield the main thread after X ms to prevent tick lag. + +* **Currency Caching:** We use a `HashMap` buffer for all economy transactions. Payments are flushed to the provider (Vault/Economy) in batches, not per block break. + +* **Data Flow:** All data moves from `prison-spigot` (events) -> `prison-core` (logic/cache) -> Database. + +* **Prison Command Handler:** Prison has a very advanced command handler that is used with every prison command. It provides for command context and help when the user's need help, which is the base command followed by `help`. The help lists all parameters, details about the command, and even links to documentation. Commands can be controlled through permissons to restrict players from using and seeing admin commands. The Prison commands are heigherarchial where root command has children, such as `mines`, `ranks`, and even `prison`. Issuing a root command will show all direct children. The command handler also supports auto complete on the commands, but not the parameters. The Commands are defined within the source code through the use of various annotations. To find out more about a given command within Prison, inspecting the command parameters will provide a very rich set of information on usage and behaviors. + +* **Auto Features:** Auto Features is an enum based set of nested configuration parameters that controls everything related to how Prison behaves with BlockBreakEvents, and other supported plugin's block breaking events such as explosions. There are many settings that controls auto pickup, smelting, fortune, and secondary drops. These settings start off as nested enums, but are persisted in the server's plugins/Prison directory upon startup so all of the settings can be customized. + +* **Placeholders:** Placeholders are a dynamic set of tags that can be used in chat, in messages, and other plugins to refer to the player, ranks, mines, and other Prison related features. Prison uses the bukkit chat event to handle chat related placeholders, but also hooks in to PlaceholderAPI plugin to handle placeholders that are embedded within other plugins. Each module has many placeholders, and some are dynamically generated upon server startup. On a normal server, when taking in to consideration of all of the ranks, prestige ranks, and mines, there can be thousands of different placeholders that prison will handle and resolve. The core foundation of all placeholders is based upon an enumeration that defines all placeholders. This ensures that the internal usage of placeholders is strongly typed at compile time. Many placeholders extends the placeholder's name to represent a dynamic set of items. For example, an enumeration `prison_mines_name` is extended by adding a mine name to it: `prison_mines_name_a` or `prison_mines_name_k`. All placeholders have abbreviations that can be much shorter, such as for these mine names: `prison_mn_a` and `prison_mn_k`. There are about 307 placeholder base types, and when extended to represent mines, ranks, prestiges, etc, there can be thousands of potential placeholders. Placeholders are classified by category such as: Player, ladders, ranks, playerranks, statsranks, statsplayers, statsmine, mines, mineplayers, playerblocks, statsmines, and custom. Prison also supports custom placeholders where an admin can define a placeholder name, then assign as much text to it as they want, including other prison prison placeholders and placeholder from other plugins. Therefore a single custom placeholder can replace many individual placeholders which can make it easier to setup other plugins such as holigraphic displays. Prison has an advanced placeholder caching system that can speed up the response times, and reduce lag, especially if another plugin is spamming prison placeholders. Prison placeholders also support placeholder attributes, which allows for dynamic control over the formatting of placeholders. Example would be with numeric placeholders, you can use a placeholder attribute to control the formatting of that number, such as thousands seperators, decimal positions, colors, etc. There are classes of placeholders that are status bars, and through placeholder attributes you can control the colors of the bar, what characters are used for the bars, and the size of the bar. So there is a ton of control over all of the placeholders within prison. + +* **Debug Mode:** Prison has in place a pretty extensive debug mode that can dynamically generate log entries that can track and explain what is happening within Prison most of the time. There is a global setting to enable it within config.yml, or it can be toggled on or off with `prison debug`. There are advanced settings to even target specific players and for x-number of messages. This is very helpful when admins report problems with their servers. + +* **Prison support:** Prison has the ability to gather all settings and it's states, and export them to a secure third party website so the Prison support staff can review the server's settings. + + + +## Tech Stack +* **Language:** Java 8 (Current) -> Targeting Java 21/25 for V4.0. +* **Build System:** Gradle (Multi-module). +* **Target Environment:** Spigot/Paper 1.8.8 through 1.21. \ No newline at end of file diff --git a/zipDocs/DEPENDENCIES.md b/zipDocs/DEPENDENCIES.md new file mode 100644 index 000000000..55a29b3b8 --- /dev/null +++ b/zipDocs/DEPENDENCIES.md @@ -0,0 +1,77 @@ +Project: Prison + +Current Target: Java 8 / Legacy Spigot + +Migration Target: Java 25 / Bukkit API v1.21.10 (v4.0) +1. Root Build (build.gradle) + +These are the orchestrating plugins governing the entire build process. + + Shadow Plugin + + Current: com.github.johnrengelman.shadow:8.1.1 + + Migration Flag: Version 8.1.1 supports Java 17 well, but you may need to bump to the latest 8.3.x branch to ensure smooth compilation and shading when moving your Eclipse project facets to Java 25. + +2. prison-core + +The pure logic and data management layer. + + Google GSON + + Current: com.google.code.gson:gson (Version dictated by Spigot or explicit declaration) + + Migration Flag: Ensure this is explicitly bumped to 2.10.1 or higher in v4.0 to properly handle Java record serialization if we refactor your data models. + + JUnit (Testing) + + Current: junit:junit:4.12 + + Migration Flag: MAJOR BUMP REQUIRED. JUnit 4 is entirely obsolete for modern testing. Phase 0 must include migrating the test suite to JUnit 5 (Jupiter) 5.10+. + +3. prison-spigot & prison-spigot-alt + +The Bukkit/Spigot implementation layers handling the block processing and economy hooks. + + Spigot / Bukkit API + + Current: Legacy 1.8.x - 1.12.x APIs. + + Migration Flag: MAJOR BUMP REQUIRED. Must be updated to target the Bukkit v1.21.10 release. This will break your block-state manipulation logic due to the removal of legacy block IDs (e.g., Material.WOOL with byte data) in favor of the modern BlockData API. The yielding 80k block processor will need its block modification calls completely rewritten. + + Vault API + + Current: net.milkbowl.vault:VaultAPI (Likely 1.7.x) + + Migration Flag: Safe to keep, but ensure it is compiled against the modern API standard. + +4. prison-worldguard6 + +Legacy region protection hooks. + + WorldGuard API (v6) + + Current: com.sk89q:worldguard:6.1.1-SNAPSHOT (or similar 6.x) + + Migration Flag: DEPRECATION WARNING. WorldGuard 6 is completely incompatible with modern Minecraft. For the v4.0 update, this entire sub-project should be archived or deleted. + +5. prison-worldguard7 + +Modern region protection hooks. + + WorldGuard Core & Bukkit + + Current: com.sk89q.worldguard.worldguard-libs:core:7.0.4 + + Migration Flag: BUMP REQUIRED. Version 7.0.4 will not support the Bukkit v1.21.10 API. You must bump this to WorldGuard 7.0.9 or higher, which introduces new adapters for modern Spigot versions. + +6. prison-mines, prison-ranks, prison-sellall + +Feature modules relying on the core and API. + + Dependencies: Primarily internal project dependencies (project(':prison-core'), project(':prison-api')). + + Migration Flag: No external library bumps needed, but these will inherit all the breaking changes from the Spigot v1.21.10 and Java 25 upgrades applied in the core and implementation modules. + + + \ No newline at end of file diff --git a/zipDocs/PHASE_0_GOALS.md b/zipDocs/PHASE_0_GOALS.md new file mode 100644 index 000000000..20fe2d820 --- /dev/null +++ b/zipDocs/PHASE_0_GOALS.md @@ -0,0 +1,25 @@ +# Phase 0: The "Rehydration" & Purge + +## Primary Objective +Prepare the 91k-line legacy codebase for a massive V4.0 refactor. We are in a "Look but don't touch" state for features, focusing purely on stability and cleanup. + +## Current Tasks +1. **The Great Purge:** Identify and remove all commented-out code blocks, unused imports, and dead methods. +2. **Hotspot Audit:** Identify "God Classes" (classes over 2,000 lines) that need to be broken down in Phase 1. +3. **Dependency Cleanup:** Verify `libs.versions.toml` and align all modules to the same library versions. +4. **Testing Prep:** Identify the 5 most "fragile" methods (like the 80k block explosion logic) to be the first targets for Unit Tests. + + +## Optional Tasks that should be completed before wrapping up V3.x +1. **Sellall & Autosell:** These have been problematic and error prone. A lot of work has been done to them and they are much improved with functionality and stability, but there are still some weaknesses with them. We should review what should be done before v4.0. Autosell can sometimes be difficult to enable and is usually tied back to a conflicting configuration setting. +2. **Backpacks:** The first attempt at adding backpacks failed with a lot of lag. They have been "disabled" and I would like to fix the backpack model and get them working. Might be able to utilize the PlayerCache for persisting the backpack data. +3. **Player Objects:** The player objects within Prison is has been refactored with the number of player types being reduced. There could still be problems that should be ironed out and maybe create some unit tests too. +4. **MineBombs:** These have been some new features added to mine bombs and they don't always work well and can glitch at times. Should review MineBombs before v3.x is finalized. + + +## AI Constraints (Rules for Gemini) +* **DO NOT** suggest new features or enchantments yet. +* **DO** point out code smells, high cyclomatic complexity, or missing @Override tags. +* **DO** prioritize performance. If a suggestion might cause lag in a 100-player environment, flag it. +* **STRICT:** Always maintain compatibility with the "Yielding" block-processor logic. + diff --git a/zipDocs/SYSTEM_INSTRUCTIONS.md b/zipDocs/SYSTEM_INSTRUCTIONS.md new file mode 100644 index 000000000..c64b696ca --- /dev/null +++ b/zipDocs/SYSTEM_INSTRUCTIONS.md @@ -0,0 +1,14 @@ +=== SYSTEM INSTRUCTIONS === +This document contains the concatenated source code for a Gradle-based Bukkit plugin. +Files are separated by headers in the format: + ================================================================ + File: [relative/path] + ================================================================ + +ACTION REQUIRED: Read and map this project structure in your head. Do not write code, suggest refactors, or summarize the project. Simply reply with: 'Codebase loaded and mapped.' and provide a brief list of the top-level modules. + +=========================== + +~~Reminder to the person submitting this task:~~ +~~Attached is my project snapshot. Please execute the System Instructions located at the very top of the file.~~ + From bd070ab9a487a387f3d71c6340836db3166bfdeb Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 6 Mar 2026 13:02:43 -0500 Subject: [PATCH 308/323] config.yml: change the default setting on adding new players on startup. This is a major problem on large servers. --- docs/changelog_v3.3.x.md | 3 +++ prison-spigot/src/main/resources/config.yml | 10 +++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index c738fcf9b..b84317d39 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.19j 2026-03-06 +* **config.yml: change the default setting on adding new players on startup. This is a major problem on large servers.** + + * **Design documents: Starting to create some of the design and planning documents that will be needed in the next few phrases of Prison.** diff --git a/prison-spigot/src/main/resources/config.yml b/prison-spigot/src/main/resources/config.yml index 84fc36502..c582aa43c 100644 --- a/prison-spigot/src/main/resources/config.yml +++ b/prison-spigot/src/main/resources/config.yml @@ -112,7 +112,7 @@ prestige: # added to prison upon demand. It's been reported that adding new players can take a few # seconds (2 to 5 seconds) per player, which has not been confirmed. But if true, then # existing servers switching over to Prison could take a long time to setup all players -# at startup. So this setting may make sense in those conditions. +# at startup. So then disabling this setting may make sense in those conditions. # NOTE: Its not possible to test all situations where new players are bypassed when starting # Prison. Therefore disabling this setting is at your own risk. But if any issues are # encountered, then PLEASE contact support on our discord server ASAP and we will @@ -133,12 +133,12 @@ prestige: # 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 +# you notice potential server delays, trying increasing the delays. You can use # `/timings` to confirm where the lag is occuring. ranks: startup: - add-new-players-on-startup: true + add-new-players-on-startup: false gui-default-include-rankup-button: true gui-prestiges-include-rankup-button: true gui-others-include-rankup-button: true @@ -172,7 +172,7 @@ ranks: # automatically. Once converted, the files cannot be reverted back to the old names. prison-ranks: startup: - add-new-players-on-startup: true + add-new-players-on-startup: false use-friendly-user-file-names: false @@ -257,7 +257,7 @@ prison-block-compatibility-report: false -# NEW: Placeholder progress bar. +# Placeholder progress bar. # Can control how many segments are generated. The more segments that # are displayed the better reactive it will appear to the players. # Also what is used for the postive and negative parts of the status bar, From 333b38631f8f518d52a14cac28d8361e7d04031e Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 6 Mar 2026 14:52:47 -0500 Subject: [PATCH 309/323] Prison Cleanup: prison-core: Removed obsolete and unneeded comments and fix indentation where needed. Second part. --- .gitignore | 1 + docs/changelog_v3.3.x.md | 3 + .../events/player/PlayerChatEvent.java | 6 +- .../events/player/PlayerDropItemEvent.java | 6 +- .../events/player/PlayerSuffocationEvent.java | 2 +- .../player/PrisonPlayerInteractEvent.java | 25 +- .../prison/internal/item/ItemFlag.java | 9 +- .../mcprison/prison/jackson/JacksonYaml.java | 162 +---- .../prison/localization/LocaleManager.java | 582 +++++++++--------- .../prison/localization/Localizable.java | 157 +++-- .../tech/mcprison/prison/modules/Module.java | 14 - .../prison/modules/ModuleElement.java | 1 - .../prison/modules/ModuleManager.java | 125 ++-- .../mcprison/prison/modules/ModuleStatus.java | 26 +- .../prison/output/BulletedListComponent.java | 10 +- .../prison/output/ButtonComponent.java | 2 +- .../mcprison/prison/output/ChatDisplay.java | 70 +-- .../prison/output/DisplayComponent.java | 12 - .../prison/output/FancyMessageComponent.java | 6 +- .../tech/mcprison/prison/output/Output.java | 209 +++---- .../prison/placeholders/PlaceHolderKey.java | 197 ------ .../PlaceholderAttributeNumberFormat.java | 3 - .../PlaceholderAttributeTime.java | 9 - .../placeholders/PlaceholderIdentifier.java | 20 - .../placeholders/PlaceholderManager.java | 468 ++++---------- .../placeholders/PlaceholderManagerUtils.java | 16 +- .../placeholders/PlaceholderResults.java | 214 ++++--- .../placeholders/PlaceholderStatsData.java | 12 - .../prison/placeholders/Placeholders.java | 6 - .../placeholders/PlaceholdersStats.java | 1 - .../prison/placeholders/PlaceholdersUtil.java | 102 +-- .../PrisonCustomPlaceholders.java | 124 ++-- 32 files changed, 902 insertions(+), 1698 deletions(-) diff --git a/.gitignore b/.gitignore index f8bdf1c19..559203ed9 100644 --- a/.gitignore +++ b/.gitignore @@ -139,3 +139,4 @@ gradle-app.setting build.gradle.deploy prison-spigot/lib/old/ prison-spigot/lib/disabled/ +zip_snapshots/ diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index b84317d39..19e22e779 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.19j 2026-03-06 +* **Prison Cleanup: prison-core: Removed obsolete and unneeded comments and fix indentation where needed.** Second part. + + * **config.yml: change the default setting on adding new players on startup. This is a major problem on large servers.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/events/player/PlayerChatEvent.java b/prison-core/src/main/java/tech/mcprison/prison/internal/events/player/PlayerChatEvent.java index 571559337..a3bb27c0d 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/events/player/PlayerChatEvent.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/events/player/PlayerChatEvent.java @@ -60,11 +60,13 @@ public void setFormat(String format) { this.format = format; } - @Override public boolean isCanceled() { + @Override + public boolean isCanceled() { return canceled; } - @Override public void setCanceled(boolean canceled) { + @Override + public void setCanceled(boolean canceled) { this.canceled = canceled; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/events/player/PlayerDropItemEvent.java b/prison-core/src/main/java/tech/mcprison/prison/internal/events/player/PlayerDropItemEvent.java index 92146fef0..be5a2e465 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/events/player/PlayerDropItemEvent.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/events/player/PlayerDropItemEvent.java @@ -47,11 +47,13 @@ public ItemStack getItemStack() { return itemStack; } - @Override public boolean isCanceled() { + @Override + public boolean isCanceled() { return canceled; } - @Override public void setCanceled(boolean canceled) { + @Override + public void setCanceled(boolean canceled) { this.canceled = canceled; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/events/player/PlayerSuffocationEvent.java b/prison-core/src/main/java/tech/mcprison/prison/internal/events/player/PlayerSuffocationEvent.java index 441f92748..2829a4139 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/events/player/PlayerSuffocationEvent.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/events/player/PlayerSuffocationEvent.java @@ -10,7 +10,7 @@ public class PlayerSuffocationEvent private boolean canceled = false; public PlayerSuffocationEvent( Player player ) { - this.player = player; + this.player = player; } public Player getPlayer() { diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/events/player/PrisonPlayerInteractEvent.java b/prison-core/src/main/java/tech/mcprison/prison/internal/events/player/PrisonPlayerInteractEvent.java index 15fe44b74..526eb7940 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/events/player/PrisonPlayerInteractEvent.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/events/player/PrisonPlayerInteractEvent.java @@ -41,20 +41,19 @@ public class PrisonPlayerInteractEvent implements Cancelable { public enum Action { LEFT_CLICK_BLOCK, RIGHT_CLICK_BLOCK; - public static Action fromString( String value ) { - Action results = null; - - if ( value != null ) { - for ( Action action : values() ) - { + public static Action fromString( String value ) { + Action results = null; + + if ( value != null ) { + for ( Action action : values() ) { if ( action.name().equalsIgnoreCase( value.trim() ) ) { results = action; } } - } - - return results; - } + } + + return results; + } } public PrisonPlayerInteractEvent(Player player, ItemStack itemInHand, Action action, @@ -81,11 +80,13 @@ public Location getClicked() { return clicked; } - @Override public boolean isCanceled() { + @Override + public boolean isCanceled() { return canceled; } - @Override public void setCanceled(boolean canceled) { + @Override + public void setCanceled(boolean canceled) { this.canceled = canceled; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/item/ItemFlag.java b/prison-core/src/main/java/tech/mcprison/prison/internal/item/ItemFlag.java index 806d3fab7..4545cc855 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/item/ItemFlag.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/item/ItemFlag.java @@ -2,9 +2,16 @@ /** * @author Faizaan A. Datoo + * + * @deprecated Not used. */ public enum ItemFlag { - HIDE_ENCHANTS, HIDE_ATTRIBUTES, HIDE_UNBREAKABLE, HIDE_DESTROYS, HIDE_PLACED_ON, HIDE_POTION_EFFECTS +// HIDE_ENCHANTS, +// HIDE_ATTRIBUTES, +// HIDE_UNBREAKABLE, +// HIDE_DESTROYS, +// HIDE_PLACED_ON, +// HIDE_POTION_EFFECTS } diff --git a/prison-core/src/main/java/tech/mcprison/prison/jackson/JacksonYaml.java b/prison-core/src/main/java/tech/mcprison/prison/jackson/JacksonYaml.java index 45feaa17e..a9bc1aaee 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/jackson/JacksonYaml.java +++ b/prison-core/src/main/java/tech/mcprison/prison/jackson/JacksonYaml.java @@ -34,6 +34,8 @@ *
  • com.fasterxml.jackson.databind.node.ObjectNode (a Map)
  • * * + * @deprecated Not used. Empty. + * */ public class JacksonYaml { @@ -42,163 +44,7 @@ public JacksonYaml() { } -// /** -// *

    This function will read a yaml file, which loads as a hierarchical -// * map. Then it will flatten the hierarchical map and return it. -// *

    -// * -// * -// * @param file -// */ -// public Map loadYamlConfigFile( File file ) { -// Map map = null; -// -// ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); -// -// // If using something like a custom date formatter, etc: -// mapper.findAndRegisterModules(); -// -// -// try { -// JsonNode tree = mapper.readTree( file ); -// -// map = flattenJson( tree ); -// -//// for (Map.Entry kv : map.entrySet()) { -//// System.out.println(kv.getKey() + ": " + -//// kv.getValue().asText() + " [" + -//// kv.getValue().getClass() + "]"); -//// } -// } -// catch ( IOException e ) { -// Output.get().logError( String.format( "JacksonYaml.loadYamlConfigFile: " + -// "Failure: file= %s :: %s ", file.getAbsoluteFile(), e.getMessage() )); -// } -// -// return map; -// } -// -// -// -// private Map flattenJson(JsonNode input) { -// Map map = new LinkedHashMap<>(); -// flattenJson(input, null, map); -// return map; -// } -// -// private void flattenJson(JsonNode node, String parent, Map map) { -// if (node instanceof ValueNode) { -// map.put(parent, (ValueNode)node); -// } -// else { -// String prefix = parent == null ? "" : parent + "."; -// if (node instanceof ArrayNode) { -// ArrayNode arrayNode = (ArrayNode)node; -// for(int i = 0; i < arrayNode.size(); i++) { -// flattenJson(arrayNode.get(i), prefix + i, map); -// } -// } -// else if (node instanceof ObjectNode) { -// ObjectNode objectNode = (ObjectNode) node; -// for (Iterator> it = objectNode.fields(); it.hasNext(); ) { -// Map.Entry field = it.next(); -// flattenJson(field.getValue(), prefix + field.getKey(), map); -// } -// } -// else { -// Output.get().logWarn( String.format( "JacksonYaml.flattenJson: " + -// "Warning: Unknown node type. node= %s ", node.getClass())); -// -// } -// } -// } -// -// -// -// /** -// *

    This function will write a flat map to a yaml file after it -// * expands it to an hierarchical map, expanding the key values on -// * their periods. -// *

    -// * -// * @param file Target file to save to -// * @param map A flat map of all the configs -// */ -// public void writeYamlConfigFile( File file, Map map ) { -// -// String filenameTemp = file.getName() + ".tmp.yml"; -// File fileTemp = new File( file.getParentFile(), filenameTemp ); -// -// ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); -// -// // If using something like a custom date formatter, etc: -// mapper.findAndRegisterModules(); -// -// try { -// Map mapExpanded = expandMap( map ); -// -// // Write to the temp file: -// mapper.writeValue( fileTemp, mapExpanded ); -// -// // Delete the original file if it exists: -// if ( file.exists() ) { -// file.delete(); -// } -// -// // Rename the temp file to the actual file: -// fileTemp.renameTo( file ); -// } -// catch ( IOException e ) { -// Output.get().logError( String.format( "JacksonYaml.writeYamlConfigFile: " + -// "Failure: file= %s :: %s ", file.getAbsoluteFile(), e.getMessage() )); -// } -// } -// -// /** -// *

    This takes a flat map and expands the keys, breaking on the periods, -// * and builds a multi-level hierarchy. -// *

    -// * -// * @param map Flat map -// * @return Hierarchical map -// */ -// private Map expandMap( Map map ) { -// Map m = new LinkedHashMap<>(); -// -// for ( Entry node : map.entrySet() ) { -// -// String key = node.getKey(); -// -// if ( key != null ) { -// -// ValueNode value = node.getValue(); -// -// String[] keyz = key.split( "\\." ); -// -// // There are multiple depths and we must place the value at the -// // leaf nodes. getChildExpandedMap traverses all the children -// // to get to the leaf node, making the nodes if needed. -// Map child = getChildExpandedMap(m, keyz, 0); -// -// child.put( keyz[keyz.length-1], value ); -// } -// } -// -// return m; -// } -// -// @SuppressWarnings( "unchecked" ) -// private Map getChildExpandedMap( Map map, String[] keyz, int pos ) { -// if ( pos < keyz.length - 1 ) { -// String key = keyz[pos]; -// if ( !map.containsKey( key ) ) { -// map.put( key, new LinkedHashMap<>() ); -// } -// return getChildExpandedMap( (Map) map.get( key ), keyz, pos + 1); -// } -// -// return map; -// } - + // NOTE: The commented out source was purged. This appears to be a dead class. + // See git history for what was purged. } 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 c8c6f1181..96d5d7c2b 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 @@ -159,9 +159,9 @@ public LocaleManager(PluginEntity module) { public void reload() { - // Reset configs: - configs.clear(); - + // Reset configs: + configs.clear(); + // Always get the config's default-language settings to ensure we are always // accessing the correct files. @@ -193,38 +193,38 @@ public static List getRegisteredInstances() @Override public String toString() { - StringBuilder sb = new StringBuilder(); - - sb.append( "LocalManager: " ).append( module.getName() ) - .append( " Internal Path: " ).append( internalPath ) - .append( " Local Folder:" ).append( getLocalFolder().getAbsolutePath() ); - - return sb.toString(); + StringBuilder sb = new StringBuilder(); + + sb.append( "LocalManager: " ).append( module.getName() ) + .append( " Internal Path: " ).append( internalPath ) + .append( " Local Folder:" ).append( getLocalFolder().getAbsolutePath() ); + + return sb.toString(); } public File getLocalDataFolder() { - // Setup the local folders: - File dataFolder = fixPrisonCoreLanguagePath( getOwningPlugin().getModuleDataFolder() ); - File localeDirectory = new File(dataFolder, LOCALE_FOLDER); - - // if the folder does not exist, try to create it: - if ( !localeDirectory.exists() ) { - localeDirectory.mkdirs(); - - // Now copy all of the default language files that are in the prison jar to this new directory. - // This will make it a lot easier for admins to modify the language files. - extractShippedLocales( localeDirectory ); - - } - if ( !localeDirectory.isDirectory() ) { - Output.get().logWarn( - "The Locale Folder is not a directory. [" + - localeDirectory.getAbsolutePath() + "] Plugin: " + - getOwningPlugin() + - " Not able to load custom locales"); - } - - return localeDirectory; + // Setup the local folders: + File dataFolder = fixPrisonCoreLanguagePath( getOwningPlugin().getModuleDataFolder() ); + File localeDirectory = new File(dataFolder, LOCALE_FOLDER); + + // if the folder does not exist, try to create it: + if ( !localeDirectory.exists() ) { + localeDirectory.mkdirs(); + + // Now copy all of the default language files that are in the prison jar to this new directory. + // This will make it a lot easier for admins to modify the language files. + extractShippedLocales( localeDirectory ); + + } + if ( !localeDirectory.isDirectory() ) { + Output.get().logWarn( + "The Locale Folder is not a directory. [" + + localeDirectory.getAbsolutePath() + "] Plugin: " + + getOwningPlugin() + + " Not able to load custom locales"); + } + + return localeDirectory; } protected class PropertyFileFilter @@ -246,22 +246,22 @@ public boolean accept( File dir, String name ) private void refreshLocalLocales() { - // Setup the local folders: - File localeFolder = getLocalDataFolder(); - - // Get a Map of all properties files in the selected directory: - TreeMap localFilesByName = new TreeMap<>(); - File[] localFiles = localeFolder.listFiles( new PropertyFileFilter() ); - - for ( File file : localFiles ) { - LocalManagerPropertyFileData pfd = new LocalManagerPropertyFileData( file ); - localFilesByName.put( pfd.getLocalPropertiesName(), pfd ); - - checkLocalPropertiesStatus( pfd ); + // Setup the local folders: + File localeFolder = getLocalDataFolder(); + + // Get a Map of all properties files in the selected directory: + TreeMap localFilesByName = new TreeMap<>(); + File[] localFiles = localeFolder.listFiles( new PropertyFileFilter() ); + + for ( File file : localFiles ) { + LocalManagerPropertyFileData pfd = new LocalManagerPropertyFileData( file ); + localFilesByName.put( pfd.getLocalPropertiesName(), pfd ); + + checkLocalPropertiesStatus( pfd ); } - // Prison's module properties files in the Prison jar that need to be scanned: + // Prison's module properties files in the Prison jar that need to be scanned: CodeSource cs = getOwningPlugin().getClass().getProtectionDomain().getCodeSource(); if (cs != null) { @@ -271,87 +271,87 @@ private void refreshLocalLocales() { ZipEntry entry; try ( - ZipInputStream zip = new ZipInputStream(jar.openStream()); + ZipInputStream zip = new ZipInputStream(jar.openStream()); ) { - while ( (entry = zip.getNextEntry()) != null) { - String entryName = entry.getName(); - - if (entryName.startsWith(internalPath) && entryName.endsWith(".properties")) { - - String[] arr = entryName.split("/"); - String jarResourceName = arr[arr.length - 1]; - - LocalManagerPropertyFileData pfd = localFilesByName.get( jarResourceName ); - - BufferedInputStream inStream = new BufferedInputStream( zip ); - - if ( pfd != null ) { - // Need to check to see if there the local needs to be updated: - - // Read the whole properties file since it may need to be used more than once - String propertiesData = readInputStream( inStream ); - - - - checkJarPropertiesStatus( pfd, propertiesData, jarResourceName ); - - - if ( pfd.replaceLocalWithJar() ) { - // Replace the local with what's in the jar: - - // Archive the existing file: - archiveOldPropertiesFile( pfd.getLocalPropFile() ); - - File newFile = new File( localeFolder, jarResourceName ); - - - - Files.copy( new ByteArrayInputStream( - propertiesData.getBytes( StandardCharsets.UTF_8 ) ), newFile.toPath() ); - - Output.get().logInfo( "### LocalManager refreshLocalLocales(): Replace Local " + - "Jar. " + pfd.toString() + " Replaced."); - - } - else { - // Do not replace: -// Output.get().logInfo( "### LocalManager refreshLocalLocales(): Keep existing " + -// "local jar. " + pfd.toString() ); - } - - } - else { - // The current Zip Entry does not exist in the local directory. - // Need to extract it. - - File newFile = new File( localeFolder, jarResourceName ); - - if ( newFile.exists() ) { - // Not really sure why the pfd would fail find a resource, but the File exists, - // so archive it since there must be an issue with it. - archiveOldPropertiesFile( newFile ); - } - - Files.copy( inStream, newFile.toPath() ); - - Output.get().logInfo( "### LocalManager refreshLocalLocales(): Local did not exist. " + - "Jar copied to local. " ); - } - } - else { - - } - // Need to close the entry to position to the next entry: - zip.closeEntry(); - - } + while ( (entry = zip.getNextEntry()) != null) { + String entryName = entry.getName(); + + if (entryName.startsWith(internalPath) && entryName.endsWith(".properties")) { + + String[] arr = entryName.split("/"); + String jarResourceName = arr[arr.length - 1]; + + LocalManagerPropertyFileData pfd = localFilesByName.get( jarResourceName ); + + BufferedInputStream inStream = new BufferedInputStream( zip ); + + if ( pfd != null ) { + // Need to check to see if there the local needs to be updated: + + // Read the whole properties file since it may need to be used more than once + String propertiesData = readInputStream( inStream ); + + + + checkJarPropertiesStatus( pfd, propertiesData, jarResourceName ); + + + if ( pfd.replaceLocalWithJar() ) { + // Replace the local with what's in the jar: + + // Archive the existing file: + archiveOldPropertiesFile( pfd.getLocalPropFile() ); + + File newFile = new File( localeFolder, jarResourceName ); + + + + Files.copy( new ByteArrayInputStream( + propertiesData.getBytes( StandardCharsets.UTF_8 ) ), newFile.toPath() ); + + Output.get().logInfo( "### LocalManager refreshLocalLocales(): Replace Local " + + "Jar. " + pfd.toString() + " Replaced."); + + } + else { + // Do not replace: + // Output.get().logInfo( "### LocalManager refreshLocalLocales(): Keep existing " + + // "local jar. " + pfd.toString() ); + } + + } + else { + // The current Zip Entry does not exist in the local directory. + // Need to extract it. + + File newFile = new File( localeFolder, jarResourceName ); + + if ( newFile.exists() ) { + // Not really sure why the pfd would fail find a resource, but the File exists, + // so archive it since there must be an issue with it. + archiveOldPropertiesFile( newFile ); + } + + Files.copy( inStream, newFile.toPath() ); + + Output.get().logInfo( "### LocalManager refreshLocalLocales(): Local did not exist. " + + "Jar copied to local. " ); + } + } + else { + + } + // Need to close the entry to position to the next entry: + zip.closeEntry(); + + } } } catch ( Exception e ) { - e.printStackTrace(); + e.printStackTrace(); } } @@ -391,13 +391,13 @@ private String readInputStream( BufferedInputStream inStream ) private void archiveOldPropertiesFile( File localPropFile ) { - String name = localPropFile.getName(); - - String newName = "_archived_" + name + "_" + getDateTime() + ".txt"; - - File targetName = new File( localPropFile.getParentFile(), newName ); - - localPropFile.renameTo( targetName ); + String name = localPropFile.getName(); + + String newName = "_archived_" + name + "_" + getDateTime() + ".txt"; + + File targetName = new File( localPropFile.getParentFile(), newName ); + + localPropFile.renameTo( targetName ); } private String getDateTime() { @@ -412,7 +412,6 @@ private void checkLocalPropertiesStatus( LocalManagerPropertyFileData pfd ) try ( FileReader fr = new FileReader( pfd.getLocalPropFile() ); -// FileReader fr = new FileReader( pfd.getLocalPropFile(), StandardCharsets.UTF_8 ); // Java 11 ) { prop.load( fr ); @@ -439,132 +438,132 @@ private void checkLocalPropertiesStatus( LocalManagerPropertyFileData pfd ) private void checkJarPropertiesStatus( LocalManagerPropertyFileData pfd, String propertiesData, String jarPath ) { - Properties prop = new Properties(); - - try { - - prop.load( new StringReader( propertiesData ) ); - - boolean hasVersion = prop.containsKey( "messages__version" ); - String version = prop.getProperty( "messages__version" ); - - boolean hasAutoRefresh = prop.containsKey( "messages__auto_refresh" ); - String autoRefresh = prop.getProperty( "messages__auto_refresh" ); - - if ( hasVersion && version != null && !version.trim().isEmpty() ) { - pfd.setJarVersion( version ); - } - pfd.setJarHasAutoReplace( hasAutoRefresh ); - pfd.setJarAutoReplace( autoRefresh != null && "true".equalsIgnoreCase( autoRefresh ) ); - } - catch ( IOException e ) { - Output.get().logWarn( "Unable to open and read a property file within the jar file. " + - "[" + jarPath + "]", e ); - } + Properties prop = new Properties(); + + try { + + prop.load( new StringReader( propertiesData ) ); + + boolean hasVersion = prop.containsKey( "messages__version" ); + String version = prop.getProperty( "messages__version" ); + + boolean hasAutoRefresh = prop.containsKey( "messages__auto_refresh" ); + String autoRefresh = prop.getProperty( "messages__auto_refresh" ); + + if ( hasVersion && version != null && !version.trim().isEmpty() ) { + pfd.setJarVersion( version ); + } + pfd.setJarHasAutoReplace( hasAutoRefresh ); + pfd.setJarAutoReplace( autoRefresh != null && "true".equalsIgnoreCase( autoRefresh ) ); + } + catch ( IOException e ) { + Output.get().logWarn( "Unable to open and read a property file within the jar file. " + + "[" + jarPath + "]", e ); + } } private void loadCustomLocales() { // Setup the local folders: - File localeFolder = getLocalDataFolder(); - - File[] contents = localeFolder.listFiles( new PropertyFileFilter() ); - - if (contents != null) { - for (File locale : contents) { - if (!locale.isDirectory()) { - try ( - InputStream is = new FileInputStream(locale); - ) { - - loadLocale(locale.getName().replace(".properties", ""), is, false); - } - catch (IOException ex) { - Output.get().logWarn( - "Failed to load custom locale " + locale.getName() + - " for plugin " + getOwningPlugin() + " (" + - ex.getMessage() + ")"); - } - } - else { - Output.get().logWarn("Found subfolder " + locale.getName() + - " within locale folder " + LOCALE_FOLDER + - " in data folder for plugin " + getOwningPlugin() + - " - not loading"); - } - } - - - // Get the English properties, and use that to ensure entries exist for all of the other - // languages... if not, then copy over the english value. - Properties enUS = configs.get( DEFAULT_LOCALE ); - if ( enUS != null ) { - boolean forceDefault = false; - - // If the config.yml default lang does not exist in this module, copy enUS to - // be used in it's place: - if ( !configs.containsKey( defaultLocale ) ) { - configs.put( defaultLocale, enUS ); - - // log it - Prison.get().getLocaleLoadInfo().add( String.format( - "&3Module: &7%s &3Locale: &7%s &3Warning: Locale specific file does not exist for this " + - "module so defaulting to &7%s.properties&3.", - module.getName(), defaultLocale, DEFAULT_LOCALE ) ); - forceDefault = true; - } - - Set keys = configs.keySet(); - for ( String key : keys ) - { - if ( !key.equalsIgnoreCase( DEFAULT_LOCALE ) ) { - Properties otherLang = configs.get( key ); - if ( otherLang != null ) { - - int fallbackCount = 0; - - - - for ( String enUSKey : enUS.stringPropertyNames() ) - { - String propValueOther = otherLang.getProperty( enUSKey ); - - if ( propValueOther == null || propValueOther.trim().length() == 0 - ) { - - // Add the english value since it is missing: - otherLang.put( enUSKey, enUS.getProperty( enUSKey ) ); - fallbackCount++; - + File localeFolder = getLocalDataFolder(); + + File[] contents = localeFolder.listFiles( new PropertyFileFilter() ); + + if (contents != null) { + for (File locale : contents) { + if (!locale.isDirectory()) { + try ( + InputStream is = new FileInputStream(locale); + ) { + + loadLocale(locale.getName().replace(".properties", ""), is, false); + } + catch (IOException ex) { + Output.get().logWarn( + "Failed to load custom locale " + locale.getName() + + " for plugin " + getOwningPlugin() + " (" + + ex.getMessage() + ")"); + } + } + else { + Output.get().logWarn("Found subfolder " + locale.getName() + + " within locale folder " + LOCALE_FOLDER + + " in data folder for plugin " + getOwningPlugin() + + " - not loading"); + } + } + + + // Get the English properties, and use that to ensure entries exist for all of the other + // languages... if not, then copy over the english value. + Properties enUS = configs.get( DEFAULT_LOCALE ); + if ( enUS != null ) { + boolean forceDefault = false; + + // If the config.yml default lang does not exist in this module, copy enUS to + // be used in it's place: + if ( !configs.containsKey( defaultLocale ) ) { + configs.put( defaultLocale, enUS ); + + // log it + Prison.get().getLocaleLoadInfo().add( String.format( + "&3Module: &7%s &3Locale: &7%s &3Warning: Locale specific file does not exist for this " + + "module so defaulting to &7%s.properties&3.", + module.getName(), defaultLocale, DEFAULT_LOCALE ) ); + forceDefault = true; + } + + Set keys = configs.keySet(); + for ( String key : keys ) + { + if ( !key.equalsIgnoreCase( DEFAULT_LOCALE ) ) { + Properties otherLang = configs.get( key ); + if ( otherLang != null ) { + + int fallbackCount = 0; + + + + for ( String enUSKey : enUS.stringPropertyNames() ) + { + String propValueOther = otherLang.getProperty( enUSKey ); + + if ( propValueOther == null || propValueOther.trim().length() == 0 + ) { + + // Add the english value since it is missing: + otherLang.put( enUSKey, enUS.getProperty( enUSKey ) ); + fallbackCount++; + + } } - } - - if ( defaultLocale.equalsIgnoreCase( key ) && !forceDefault ) { - - if ( fallbackCount > 0 ) { - // log it - Prison.get().getLocaleLoadInfo().add( String.format( - "&3Module: &7%s &3Locale: &7%s &3Warning: Locale had &7%d &3missing entries " + - "and will fallback to settings from &7%s.properties&3.", - module.getName(), defaultLocale, fallbackCount, DEFAULT_LOCALE ) ); - - } - else { - Prison.get().getLocaleLoadInfo().add( String.format( - "&3Module: &7%s &3Locale language file: &7%s.properties", - module.getName(), defaultLocale ) ); - - - } - } - - } - } - } - - } - } + + if ( defaultLocale.equalsIgnoreCase( key ) && !forceDefault ) { + + if ( fallbackCount > 0 ) { + // log it + Prison.get().getLocaleLoadInfo().add( String.format( + "&3Module: &7%s &3Locale: &7%s &3Warning: Locale had &7%d &3missing entries " + + "and will fallback to settings from &7%s.properties&3.", + module.getName(), defaultLocale, fallbackCount, DEFAULT_LOCALE ) ); + + } + else { + Prison.get().getLocaleLoadInfo().add( String.format( + "&3Module: &7%s &3Locale language file: &7%s.properties", + module.getName(), defaultLocale ) ); + + + } + } + + } + } + } + + } + } } /** @@ -589,7 +588,7 @@ private File fixPrisonCoreLanguagePath( File targetPath ) { if ( !targetPath.getAbsolutePath().startsWith( ModuleManager.getModuleRootDefault().getAbsolutePath() ) ) { targetPath = Module.setupModuleDataFolder( Prison.PSEDUO_MODLE_NAME ); - } + } return targetPath; } @@ -603,7 +602,7 @@ private File fixPrisonCoreLanguagePath( File targetPath ) { */ private void extractShippedLocales( File targetPath ) { - targetPath = fixPrisonCoreLanguagePath( targetPath ); + targetPath = fixPrisonCoreLanguagePath( targetPath ); CodeSource cs = getOwningPlugin().getClass().getProtectionDomain().getCodeSource(); if (cs != null) { @@ -649,15 +648,6 @@ private void extractShippedLocales( File targetPath ) { } -// private void copyStreams(InputStream inStream, OutputStream outStream) -// throws IOException { -// byte[] buf = new byte[8192]; -// int length; -// while ((length = inStream.read(buf)) > 0) { -// outStream.write(buf, 0, length); -// } -// } - private void loadShippedLocales() { CodeSource cs = getOwningPlugin().getClass().getProtectionDomain().getCodeSource(); @@ -671,15 +661,15 @@ private void loadShippedLocales() { ZipInputStream zip = new ZipInputStream(jar.openStream()); ) { - while ((entry = zip.getNextEntry()) != null) { - String entryName = entry.getName(); - if (entryName.startsWith(internalPath) && entryName - .endsWith(".properties")) { - String[] arr = entryName.split("/"); - String localeName = arr[arr.length - 1].replace(".properties", ""); - loadLocale(localeName, zip, true); - } - } + while ((entry = zip.getNextEntry()) != null) { + String entryName = entry.getName(); + if (entryName.startsWith(internalPath) && entryName + .endsWith(".properties")) { + String[] arr = entryName.split("/"); + String localeName = arr[arr.length - 1].replace(".properties", ""); + loadLocale(localeName, zip, true); + } + } } } catch (IOException ex) { @@ -697,32 +687,28 @@ private void loadShippedLocales() { private void loadLocale(String name, InputStream is, boolean printStackTrace) { try { - - Properties temp = new Properties(); - -// temp.load(is); - - // The InputStream is part of a zipEntry so it cannot be closed, or it will close the zip stream - BufferedReader br = new BufferedReader( new InputStreamReader( is, Charset.forName("UTF-8") )); - String line = br.readLine(); - - while ( line != null ) { - if ( !line.startsWith( "#" ) && line.contains( "=" ) ) { - - 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 ); - } - - line = br.readLine(); - } - - + + Properties temp = new Properties(); + + + // The InputStream is part of a zipEntry so it cannot be closed, or it will close the zip stream + BufferedReader br = new BufferedReader( new InputStreamReader( is, Charset.forName("UTF-8") )); + String line = br.readLine(); + + while ( line != null ) { + if ( !line.startsWith( "#" ) && line.contains( "=" ) ) { + + String[] keyValue = line.split( "\\=" ); + String value = (keyValue.length > 1 ? keyValue[1] : ""); // StringEscapeUtils.escapeJava( keyValue[1] ); + + + temp.put( keyValue[0], value ); + } + + line = br.readLine(); + } + + Properties config; if (configs.containsKey(name)) { config = configs.get(name); @@ -763,12 +749,12 @@ public PluginEntity getOwningPlugin() { * @since 1.0 */ public String getDefaultLocale() { - if ( defaultLocale == null ) { - defaultLocale = Prison.get().getPlatform().getConfigString( "default-language", "en_US" ); - if ( defaultLocale == null ) { - defaultLocale = "en_US"; - } - } + if ( defaultLocale == null ) { + defaultLocale = Prison.get().getPlatform().getConfigString( "default-language", "en_US" ); + if ( defaultLocale == null ) { + defaultLocale = "en_US"; + } + } return defaultLocale; } 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 9b32423e0..73d4bc8f8 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 @@ -124,8 +124,8 @@ public boolean isFailSilently() { * @return */ public Localizable setFailSilently() { - this.failSilently = true; - return this; + this.failSilently = true; + return this; } /** @@ -135,8 +135,8 @@ public Localizable setFailSilently() { * @return */ public Localizable setFailNormally() { - this.failSilently = false; - return this; + this.failSilently = false; + return this; } /** @@ -157,17 +157,17 @@ public Localizable setFailNormally() { * @since 1.0 */ public Localizable withReplacements(String... replacements) { - if ( replacements == null ) { - replacements = new String[1]; - replacements[0] = ""; - } - else { - for ( int i = 0; i < replacements.length; i++ ) { - if ( replacements[i] == null ) { - replacements[i] = ""; - } - } - } + if ( replacements == null ) { + replacements = new String[1]; + replacements[0] = ""; + } + else { + for ( int i = 0; i < replacements.length; i++ ) { + if ( replacements[i] == null ) { + replacements[i] = ""; + } + } + } this.replacements = Arrays.copyOf(replacements, replacements.length); this.locReplacements = null; return this; @@ -351,14 +351,14 @@ public String localize() { * @since 1.0 */ public String localizeFor(CommandSender sender) { - String results = - sender instanceof Player ? - localizeIn(getParent().getLocale((Player) sender)) : - localize(); - - results = applySecondaryPlaceholders( sender, results ); - - return results; + String results = + sender instanceof Player ? + localizeIn(getParent().getLocale((Player) sender)) : + localize(); + + results = applySecondaryPlaceholders( sender, results ); + + return results; } /** @@ -376,21 +376,21 @@ public String localizeFor(CommandSender sender) { * @since 1.0 */ public void sendTo(CommandSender sender, LogLevel level) { - String message = localizeFor(sender); - if ( message != null && !message.isEmpty() ) { - - try { - Output.get().sendMessage(sender, message, level); - } - catch (Exception e) { - Output.get().logRaw( - "Tried to send a formatted mmessage to a player but it ended in " - + "failure. Was the original message edited and an extra parameter added? " - + "raw message: [" + - message - + "]"); - } - } + String message = localizeFor(sender); + if ( message != null && !message.isEmpty() ) { + + try { + Output.get().sendMessage(sender, message, level); + } + catch (Exception e) { + Output.get().logRaw( + "Tried to send a formatted mmessage to a player but it ended in " + + "failure. Was the original message edited and an extra parameter added? " + + "raw message: [" + + message + + "]"); + } + } } /** @@ -406,23 +406,23 @@ public void sendTo(CommandSender sender, LogLevel level) { * @param sender The {@link CommandSender} to send this {@link Localizable} to */ public void sendTo(CommandSender sender ) { - PlaceholderStringCoverter placeholderConverter = null; - sendTo( sender, placeholderConverter ); - } - public void sendTo(CommandSender sender, PlaceholderStringCoverter placeholderConverter ) { - - String message = localize(); - if ( message != null && !message.isEmpty() ) { - - if ( placeholderConverter != null ) { - message = placeholderConverter.convertStringPlaceholders(message); - } -// message = applySecondaryPlaceholders( -// (playerStats != null ? playerStats : sender ), -// message ); - - sendTo(sender, LogLevel.PLAIN); - } + PlaceholderStringCoverter placeholderConverter = null; + sendTo( sender, placeholderConverter ); + } + public void sendTo(CommandSender sender, PlaceholderStringCoverter placeholderConverter ) { + + String message = localize(); + if ( message != null && !message.isEmpty() ) { + + if ( placeholderConverter != null ) { + message = placeholderConverter.convertStringPlaceholders(message); + } + // message = applySecondaryPlaceholders( + // (playerStats != null ? playerStats : sender ), + // message ); + + sendTo(sender, LogLevel.PLAIN); + } } /** @@ -432,19 +432,20 @@ public void sendTo(CommandSender sender, PlaceholderStringCoverter placeholderCo * @since 1.0 */ public void broadcast() { - PlaceholderStringCoverter placeholderConverter = null; - broadcast( placeholderConverter ); + PlaceholderStringCoverter placeholderConverter = null; + broadcast( placeholderConverter ); } + public void broadcast( PlaceholderStringCoverter placeholderConverter ) { - - String message = localize(); - if ( message != null && !message.isEmpty() ) { - - for (Player player : Prison.get().getPlatform().getOnlinePlayers()) { - sendTo(player, placeholderConverter); - } - Output.get().logInfo( message ); - } + + String message = localize(); + if ( message != null && !message.isEmpty() ) { + + for (Player player : Prison.get().getPlatform().getOnlinePlayers()) { + sendTo(player, placeholderConverter); + } + Output.get().logInfo( message ); + } } /** @@ -455,16 +456,16 @@ public void broadcast( PlaceholderStringCoverter placeholderConverter ) { * @since 1.0 */ public void broadcast(World... worlds) { - String message = localize(); - if ( message != null && !message.isEmpty() ) { - - for (World w : worlds) { - for (Player player : w.getPlayers()) { - sendTo(player); - } - } - Output.get().logInfo( message ); - } + String message = localize(); + if ( message != null && !message.isEmpty() ) { + + for (World w : worlds) { + for (Player player : w.getPlayers()) { + sendTo(player); + } + } + Output.get().logInfo( message ); + } } /** @@ -478,10 +479,6 @@ private String fromNullableString(String nullable) { return nullable != null ? nullable : ""; } - // Use LogLevel instead since they are the same: -// public enum Level { -// PLAIN, INFO, WARN, ERROR -// } /** diff --git a/prison-core/src/main/java/tech/mcprison/prison/modules/Module.java b/prison-core/src/main/java/tech/mcprison/prison/modules/Module.java index 18cb42098..87e534110 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/modules/Module.java +++ b/prison-core/src/main/java/tech/mcprison/prison/modules/Module.java @@ -32,10 +32,6 @@ */ public abstract class Module implements PluginEntity { - /* - * Fields & Constants - */ - private String name, version; private File moduleDataFolder; @@ -43,10 +39,6 @@ public abstract class Module implements PluginEntity { private ModuleStatus status; private ErrorManager errorManager; - /* - * Constructor - */ - /** * Initialize your module. * @@ -93,9 +85,6 @@ public static File setupModuleDataFolder( String name ) { * @return */ abstract public String getBaseCommands(); - /* - * Methods, to be overridden - */ /** * Called when the module is to be enabled. @@ -126,9 +115,6 @@ protected void fail(String reason) { getStatus().toFailed(reason); } - /* - * Getters & Setters - */ public String getName() { return name; diff --git a/prison-core/src/main/java/tech/mcprison/prison/modules/ModuleElement.java b/prison-core/src/main/java/tech/mcprison/prison/modules/ModuleElement.java index 965c64cf2..448b93095 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/modules/ModuleElement.java +++ b/prison-core/src/main/java/tech/mcprison/prison/modules/ModuleElement.java @@ -14,7 +14,6 @@ */ public interface ModuleElement { - // private transient final ModuleElementType elementType; public ModuleElementType getModuleElementType(); public int getId(); 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 0cc4ce7e7..65c8d67cc 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 @@ -73,20 +73,20 @@ public static File getModuleRootDefault() { */ public void registerModule(Module module) { - if ( module != null ) { - - // If module already exists, remove it so it can be added: - if ( getModule(module.getName()) != null ) { - removeModule( module.getName() ); - } - - if ( getModule(module.getName()) == null ) { - // Module does not exist, so add it: - modules.add(module); - enableModule(module); -// return; // Already added - } - } + if ( module != null ) { + + // If module already exists, remove it so it can be added: + if ( getModule(module.getName()) != null ) { + removeModule( module.getName() ); + } + + if ( getModule(module.getName()) == null ) { + // Module does not exist, so add it: + modules.add(module); + enableModule(module); + // return; // Already added + } + } } private void validateVersion(Module module) { @@ -138,7 +138,6 @@ public void unregisterModule(Module module) { disableModule(module); getModules().remove(module); -// getModule(module.getName()).ifPresent(modules::remove); } /** @@ -168,19 +167,16 @@ public void unregisterAll() { * Returns the {@link Module} with the specified name. */ public Module getModule(String name) { - Module results = null; - - for (Module module : getModules() ) { - - if ( module.getName().equalsIgnoreCase(name) ) { - results = module; - break; - } + Module results = null; + + for (Module module : getModules() ) { + + if ( module.getName().equalsIgnoreCase(name) ) { + results = module; + break; + } } - return results; - -// return modules.stream().filter(module -> module.getName().equalsIgnoreCase(name)) -// .findFirst(); + return results; } /** @@ -190,36 +186,33 @@ public Module getModule(String name) { * @return */ public boolean removeModule( String name ) { - Module results = null; - - for (Module module : getModules() ) { - - if ( module.getName().equalsIgnoreCase(name) ) { - results = module; - break; - } + Module results = null; + + for (Module module : getModules() ) { + + if ( module.getName().equalsIgnoreCase(name) ) { + results = module; + break; + } } - - return results == null ? false : getModules().remove( results ); + + return results == null ? false : getModules().remove( results ); } /** * Returns the {@link Module} with the specified package name. */ public Module getModuleByPackageName(String name) { - Module results = null; - - for (Module module : getModules() ) { - - if ( module.getPackageName().equalsIgnoreCase(name) ) { - results = module; - break; - } + Module results = null; + + for (Module module : getModules() ) { + + if ( module.getPackageName().equalsIgnoreCase(name) ) { + results = module; + break; + } } - return results; - -// return modules.stream().filter(module -> module.getPackageName().equalsIgnoreCase(name)) -// .findFirst(); + return results; } /** @@ -237,40 +230,6 @@ public File getModuleRoot() { return moduleRoot; } -// /** -// * Returns the status of a module (enabled or error message), in the form of a color-coded string. -// * This is meant to show to users. -// * -// * @deprecated Use {@link Module#getStatus()} instead. -// */ -// @Deprecated public String getStatus(String moduleName) { -// Optional moduleOptional = getModule(moduleName); -// return moduleOptional.map(module -> module.getStatus().getMessage()).orElse(null); -// } - -// /** -// * Set the status of a module. -// * -// * @param moduleName The name of the module. -// * @param newStatus The module's status. May include color codes, amp-prefixed. -// * @deprecated Use {@link Module#getStatus()} instead. -// */ -// @Deprecated public void setStatus(String moduleName, String newStatus) { -// Optional moduleOptional = getModule(moduleName); -// if (!moduleOptional.isPresent()) { -// return; -// } -// Module module = moduleOptional.get(); -// -// if (newStatus.toLowerCase().contains("enabled")) { -// module.getStatus().toEnabled(); -// } else if (newStatus.toLowerCase().contains("disabled")) { -// module.getStatus().toDisabled(); -// } else { -// module.getStatus().toFailed(newStatus); -// } -// -// } public boolean isModuleActive(String moduleName) { boolean results = false; diff --git a/prison-core/src/main/java/tech/mcprison/prison/modules/ModuleStatus.java b/prison-core/src/main/java/tech/mcprison/prison/modules/ModuleStatus.java index 9033e5b1d..6e336ee8e 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/modules/ModuleStatus.java +++ b/prison-core/src/main/java/tech/mcprison/prison/modules/ModuleStatus.java @@ -26,20 +26,12 @@ */ public class ModuleStatus { - /* - * Enums - */ - public enum Status { ENABLED, DISABLED, FAILED } private Status status; - /* - * Fields & Constants - */ - private String message; /** @@ -51,10 +43,6 @@ public void toEnabled() { setMessage("&aEnabled"); } - /* - * Methods - */ - /** * Quickly set a module to the {@link Status#DISABLED} status, and set the message to "Disabled" * in red (c). @@ -93,10 +81,6 @@ public String getStatusText() { } - /* - * Getters & Setters - */ - public void setStatus(Status status) { this.status = status; } @@ -110,11 +94,11 @@ public void setMessage(String message) { } public void addMessage(String message) { - if ( this.message == null ) { - setMessage(message); - } else { - setMessage( getMessage() + ". " + message); - } + if ( this.message == null ) { + setMessage(message); + } else { + setMessage( getMessage() + ". " + message); + } } diff --git a/prison-core/src/main/java/tech/mcprison/prison/output/BulletedListComponent.java b/prison-core/src/main/java/tech/mcprison/prison/output/BulletedListComponent.java index c81163d94..dbdc92ccc 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/output/BulletedListComponent.java +++ b/prison-core/src/main/java/tech/mcprison/prison/output/BulletedListComponent.java @@ -40,13 +40,15 @@ public class BulletedListComponent extends DisplayComponent { this.messages = messages; } - @Override public String text() { + @Override + public String text() { List messageStrs = new ArrayList<>(messages.size()); messages.forEach(message -> messageStrs.add(message.toOldMessageFormat())); return Text.implode(messageStrs, "\n"); } - @Override public void send(CommandSender sender) { + @Override + public void send(CommandSender sender) { messages.forEach(message -> message.send(sender)); } @@ -59,8 +61,8 @@ public BulletedListBuilder() { } public BulletedListBuilder add(FancyMessage message) { - bullets.add(message); - return this; + bullets.add(message); + return this; } public BulletedListBuilder add(RowComponent row) { diff --git a/prison-core/src/main/java/tech/mcprison/prison/output/ButtonComponent.java b/prison-core/src/main/java/tech/mcprison/prison/output/ButtonComponent.java index 858819b6a..4697b7c4e 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/output/ButtonComponent.java +++ b/prison-core/src/main/java/tech/mcprison/prison/output/ButtonComponent.java @@ -72,7 +72,7 @@ public void send(CommandSender sender) { } public FancyMessage getFancyMessage() { - return button; + return button; } /** 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 306300843..e3dbe32cb 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 @@ -32,28 +32,16 @@ */ public class ChatDisplay { - /* - * Fields & Constants - */ - private String title; private LinkedList displayComponents; private boolean showTitle = true; - /* - * Constructor - */ - public ChatDisplay(String title) { this.title = Text.titleize(title); this.displayComponents = new LinkedList<>(); } - /* - * Methods - */ - public ChatDisplay addComponent(DisplayComponent component) { component.setDisplay(this); displayComponents.add(component); @@ -71,19 +59,19 @@ public ChatDisplay addEmptyLine() { } public void send(CommandSender sender) { - if ( isShowTitle() ) { - sender.sendMessage(title); - } - + if ( isShowTitle() ) { + sender.sendMessage(title); + } + for (DisplayComponent component : displayComponents) { component.send(sender); } } public void toLog(LogLevel logLevel) { - if ( isShowTitle() ) { - Output.get().log( title, logLevel ); - } + if ( isShowTitle() ) { + Output.get().log( title, logLevel ); + } for (DisplayComponent component : displayComponents) { Output.get().log( component.text(), logLevel ); @@ -91,9 +79,9 @@ public void toLog(LogLevel logLevel) { } public void sendtoOutputLogInfo() { - if ( isShowTitle() ) { - Output.get().logInfo( title ); - } + if ( isShowTitle() ) { + Output.get().logInfo( title ); + } for (DisplayComponent component : displayComponents) { Output.get().logInfo( component.text() ); @@ -101,11 +89,11 @@ public void sendtoOutputLogInfo() { } public StringBuilder toStringBuilder() { - StringBuilder sb = new StringBuilder(); - - if ( isShowTitle() ) { - sb.append( title ).append( "\n" ); - } + StringBuilder sb = new StringBuilder(); + + if ( isShowTitle() ) { + sb.append( title ).append( "\n" ); + } for (DisplayComponent component : displayComponents) { sb.append( component.text() ).append( "\n" ); @@ -115,17 +103,17 @@ public StringBuilder toStringBuilder() { } public StringBuilder toStringBuilderEscaped() { - StringBuilder sb = new StringBuilder(); - - if ( isShowTitle() ) { - sb.append( title ).append( "\\n" ); - } - - for (DisplayComponent component : displayComponents) { - sb.append( component.text() ).append( "\\n" ); - } - - return sb; + StringBuilder sb = new StringBuilder(); + + if ( isShowTitle() ) { + sb.append( title ).append( "\\n" ); + } + + for (DisplayComponent component : displayComponents) { + sb.append( component.text() ).append( "\\n" ); + } + + return sb; } public void addChatDisplay( ChatDisplay cDisp ) @@ -133,9 +121,9 @@ public void addChatDisplay( ChatDisplay cDisp ) addComponent(new TextComponent(cDisp.getTitle())); - for (DisplayComponent component : cDisp.getDisplayComponents() ) { - addComponent( component ); - } + for (DisplayComponent component : cDisp.getDisplayComponents() ) { + addComponent( component ); + } } protected String getTitle() { diff --git a/prison-core/src/main/java/tech/mcprison/prison/output/DisplayComponent.java b/prison-core/src/main/java/tech/mcprison/prison/output/DisplayComponent.java index 1e790027b..88f2ba3ec 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/output/DisplayComponent.java +++ b/prison-core/src/main/java/tech/mcprison/prison/output/DisplayComponent.java @@ -30,16 +30,8 @@ */ public abstract class DisplayComponent { - /* - * Fields & Constants - */ - protected ChatDisplay display; - /* - * Methods - */ - /** * Returns the text that is being appended to the {@link ChatDisplay}. * This should return the raw JSON if {@link tech.mcprison.prison.chat.FancyMessage} is involved. @@ -57,10 +49,6 @@ public abstract class DisplayComponent { */ public abstract void send(CommandSender sender); - /* - * Getters & Setters - */ - void setDisplay(ChatDisplay display) { this.display = display; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/output/FancyMessageComponent.java b/prison-core/src/main/java/tech/mcprison/prison/output/FancyMessageComponent.java index c8769183b..e8485e556 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/output/FancyMessageComponent.java +++ b/prison-core/src/main/java/tech/mcprison/prison/output/FancyMessageComponent.java @@ -42,11 +42,13 @@ public FancyMessage getMessage() { return message; } - @Override public String text() { + @Override + public String text() { return message.toOldMessageFormat(); } - @Override public void send(CommandSender sender) { + @Override + public void send(CommandSender sender) { message.send(sender); } 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 845fad982..58aa3bb7c 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 @@ -42,7 +42,6 @@ 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; @@ -144,12 +143,12 @@ private Output() { public static Output get() { if (instance == null) { - synchronized ( Output.class ) { - if (instance == null) { - - new Output(); - - } + synchronized ( Output.class ) { + if (instance == null) { + + new Output(); + + } } } return instance; @@ -189,29 +188,29 @@ private String getLogPrefix( LogLevel level) { } private String getLogColorCode( LogLevel level) { - String colorCode = null; - - switch ( level ) - { - case INFO: - colorCode = colorCodeInfo; - break; - case WARNING: - colorCode = colorCodeWarning; - break; - case ERROR: - colorCode = colorCodeError; - break; - case DEBUG: - colorCode = colorCodeDebug; - break; - - case PLAIN: - default: - colorCode = ""; - break; - } - return colorCode; + String colorCode = null; + + switch ( level ) + { + case INFO: + colorCode = colorCodeInfo; + break; + case WARNING: + colorCode = colorCodeWarning; + break; + case ERROR: + colorCode = colorCodeError; + break; + case DEBUG: + colorCode = colorCodeDebug; + break; + + case PLAIN: + default: + colorCode = ""; + break; + } + return colorCode; } public String format(String message, LogLevel level, Object... args) { @@ -261,89 +260,85 @@ public static String decodePercentEncoding( String message ) { * Log a message with a specified {@link LogLevel} */ public void log(String message, LogLevel level, Object... args) { - if ( message == null || message.trim().isEmpty() ) { - // do not send an empty message... do nothing... - } - else if ( Prison.get() == null || Prison.get().getPlatform() == null ) { - String errorMessage = coreOutputErrorStartupFailureMsg(); - if ( errorMessage == null || errorMessage.trim().isEmpty() ) { - // NOTE: The following must remain as is. This is a fallback for if there - // are major failures in prison. At least it can prefix the messages so they - // can be identified along with the reasons. - errorMessage = "Prison: (Sending to System.err due to Output.log Logger failure):"; - } - - StringBuilder sb = new StringBuilder(); - for ( Object arg : args ) { - sb.append( "[" ).append( arg ).append( "] " ); - } - - System.err.println( errorMessage + " message: [" + message + - "] params: " + sb.toString() ); - } - else { - try { - - String msg = args == null || args.length == 0 ? - message : - String.format(message, args); - - msg = decodePercentEncoding( msg ); -// if ( msg.contains( PERCENT_ENCODING ) ) { -// msg = msg.replace( PERCENT_ENCODING, PERCENT_DECODING ); -// } - - String msgRaw = String.format(msg, args); - boolean includePrefix = true; - for (String msgSplit : msgRaw.split( LINE_SPLITING )) { - - Prison.get().getPlatform().log( - (includePrefix ? (prefixTemplatePrison + " ") : "") + - getLogColorCode(level) + - msgSplit); - includePrefix = false; - } - - } - catch ( MissingFormatArgumentException e ) - { - StringBuilder sb = new StringBuilder(); + if ( message == null || message.trim().isEmpty() ) { + // do not send an empty message... do nothing... + } + else if ( Prison.get() == null || Prison.get().getPlatform() == null ) { + String errorMessage = coreOutputErrorStartupFailureMsg(); + if ( errorMessage == null || errorMessage.trim().isEmpty() ) { + // NOTE: The following must remain as is. This is a fallback for if there + // are major failures in prison. At least it can prefix the messages so they + // can be identified along with the reasons. + errorMessage = "Prison: (Sending to System.err due to Output.log Logger failure):"; + } + StringBuilder sb = new StringBuilder(); for ( Object arg : args ) { sb.append( "[" ).append( arg ).append( "] " ); } - String errorMessage = coreOutputErrorIncorrectNumberOfParametersMsg( - level.name(), e.getMessage(), message, sb.toString() ); - - Prison.get().getPlatform().logCore( - prefixTemplatePrison + " " + - getLogColorCode(LogLevel.ERROR) + - errorMessage ); - } - catch ( UnknownFormatConversionException | - FormatFlagsConversionMismatchException e) - { - StringBuilder sb = new StringBuilder(); - - for ( Object arg : args ) { - sb.append( "[" ).append( arg ).append( "] " ); + System.err.println( errorMessage + " message: [" + message + + "] params: " + sb.toString() ); + } + else { + try { + + String msg = args == null || args.length == 0 ? + message : + String.format(message, args); + + msg = decodePercentEncoding( msg ); + + String msgRaw = String.format(msg, args); + boolean includePrefix = true; + for (String msgSplit : msgRaw.split( LINE_SPLITING )) { + + Prison.get().getPlatform().log( + (includePrefix ? (prefixTemplatePrison + " ") : "") + + getLogColorCode(level) + + msgSplit); + includePrefix = false; + } + } - - String errorMessage = "Error with Java format usage (eg %s): " + - " LogLevel: " + level.name() + - " message: [" + message + "] params: [" + sb.toString() + "]" + - " error: [" + e.getMessage() + "] " + - " Escape with backslash or double percent [\\b \\n \\f \\r \\t \\\\ %%]"; - - Prison.get().getPlatform().logCore( - prefixTemplatePrison + " " + - getLogColorCode(LogLevel.ERROR) + - errorMessage ); - - //e.printStackTrace(); - } - } + catch ( MissingFormatArgumentException e ) + { + StringBuilder sb = new StringBuilder(); + + for ( Object arg : args ) { + sb.append( "[" ).append( arg ).append( "] " ); + } + + String errorMessage = coreOutputErrorIncorrectNumberOfParametersMsg( + level.name(), e.getMessage(), message, sb.toString() ); + + Prison.get().getPlatform().logCore( + prefixTemplatePrison + " " + + getLogColorCode(LogLevel.ERROR) + + errorMessage ); + } + catch ( UnknownFormatConversionException | + FormatFlagsConversionMismatchException e) + { + StringBuilder sb = new StringBuilder(); + + for ( Object arg : args ) { + sb.append( "[" ).append( arg ).append( "] " ); + } + + String errorMessage = "Error with Java format usage (eg %s): " + + " LogLevel: " + level.name() + + " message: [" + message + "] params: [" + sb.toString() + "]" + + " error: [" + e.getMessage() + "] " + + " Escape with backslash or double percent [\\b \\n \\f \\r \\t \\\\ %%]"; + + Prison.get().getPlatform().logCore( + prefixTemplatePrison + " " + + getLogColorCode(LogLevel.ERROR) + + errorMessage ); + + } + } } /** diff --git a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceHolderKey.java b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceHolderKey.java index d0bdfeb25..5ab237de9 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceHolderKey.java +++ b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceHolderKey.java @@ -35,203 +35,6 @@ public PlaceHolderKey( String key, PrisonPlaceHolders placeholder, String data, this.data = data; } -// /** -// *

    This function will take a full text String and apply the placeholder that -// * this PlaceHolderKey represents and tries to match it to the provided text. If it -// * is found within the text, then this function will return the identifier, which is -// * full text, including any placeholder attributes, but without the escape characters. -// *

    -// * -// * @param text -// * @return -// */ -// public PlaceholderResults getIdentifier( String text ) { -// PlaceholderResults results = new PlaceholderResults(this, text); -// -// -// String textLowercase = text.toLowerCase(); -// String key = getKey().toLowerCase(); -// -// -// // For placeholders with sequence numbers, such as _nnn_, will need to search -// // for 1 to 3 digits and replace the number in the "text" with _nnn_ and also -// // need to store that numeric value in the PlaceholderResults object. -// if ( getPlaceholder().hasSequence() ) { -// -// Matcher matcher = PLACEHOLDER_SEQUENCE_PATTERN.matcher( textLowercase ); -// if ( matcher.find() ) { -// -// //String group0 = matcher.group( 0 ); -// String group1 = matcher.group( 1 ); -// String group2 = matcher.group( 2 ); -// -// textLowercase = textLowercase.replace( group1, "_nnn_" ); -// -//// Output.get().logInfo( "### PlaceHolderKey: seq pattern detected: " + placeholder.name() + -//// " group0= " + group0 + " group1= " + group1 + " group2= " + group2 + " replacedText: " + textLowercase ); -// -// results.setNumericSequencePattern( group1 ); -// -// // a value of -1 indicates it was not able to be parsed: -// int parsed = -1; -// -// try { -// parsed = Integer.parseInt( group2 ); -// } -// catch ( NumberFormatException e ) { -// // Not a number so ignore... but based upon matcher.find() it should be... Hmm... -// } -// -// results.setNumericSequence( parsed ); -// -// -// // DO something more: -// -// } -// } -// -// -// // If the text is an exact match to the key (no escape characters): -// if ( textLowercase.equalsIgnoreCase( key ) ) { -// -// results.setIdentifier( textLowercase ); -// results.setPlaceholder( this ); -// -// } -// else { -// -// checkIdentifier( key, text, textLowercase, "{", "}", results ); -// -// if ( textLowercase.equalsIgnoreCase( key ) || -// textLowercase.contains( key ) || -// checkIdentifier( key, text, textLowercase, "{", "}", results ) || -// checkIdentifier( key, text, textLowercase, "%", "%", results ) -// ) { -// -// -// -// // Nothing to do, since it was already done within this if statement. -// -// -//// // Performing all the String searching and indexing can be expensive, especially -//// // since there can be thousands of PlaceHolderKeys on a server. So to provide -//// // a quick proof to see if additional, more complex calculations should be -//// // performed, we'll just see if the text input contains a hit on the key: -//// -//// // Rank in to an issue with placeholders: prison_mbm_minename and prison_mbm_pm, -//// // because the mine P has a placeholder prison_mbm_p which gets hit for the -//// // prison_mbm_pm. So to zero in on the correct placeholder, but bracket the end -//// // of the placeholder with either } or :: to ensure the correct association. -//// String test1 = "{" + key + "}"; -//// String test2 = "{" + key + -//// PlaceholderManager.PRISON_PLACEHOLDER_ATTRIBUTE_SEPARATOR; -//// -//// if ( textLowercase.contains( test1 ) || textLowercase.contains( test2 ) ) { -//// -//// // The key1 and key2 helps ensure that the full placeholder, -//// // including the attribute, is replaced: -//// String key1 = "{" + key; -//// String key2 = "}"; -//// -//// int idx = textLowercase.indexOf( key1 ); -//// int idx2 = ( idx == -1 ? -1 : textLowercase.indexOf( key2, idx + key1.length() - 1 ) ); -//// if ( idx > -1 && idx2 > -1 ) { -//// -//// String identifier = text.substring( idx + 1, idx2 ); -//// results.setIdentifier( identifier ); -////// results = results.replace("{" + identifier + "}", -////// pm.getTranslatePlayerPlaceHolder( playerUuid, playerName, identifier ) ); -//// } -//// } -// -// } -// } -// -// -// return results; -// } - - -// private boolean checkIdentifier( String key, String text, String textLowercase, -// String escLeft, String escRight, PlaceholderResults results ) { -// boolean foundIdentifier = false; -// -// // Performing all the String searching and indexing can be expensive, especially -// // since there can be thousands of PlaceHolderKeys on a server. So to provide -// // a quick proof to see if additional, more complex calculations should be -// // performed, we'll just see if the text input contains a hit on the key: -// -// // Rank in to an issue with placeholders: prison_mbm_minename and prison_mbm_pm, -// // because the mine P has a placeholder prison_mbm_p which gets hit for the -// // prison_mbm_pm. So to zero in on the correct placeholder, but bracket the end -// // of the placeholder with either } or :: to ensure the correct association. -// String test1 = escLeft + key + escRight; -// String test2 = escLeft + key + -// PlaceholderManager.PRISON_PLACEHOLDER_ATTRIBUTE_SEPARATOR; -// -// int adjustment = 0; -// // If the text contains a sequence, then calculate the adjustment position based upon -// // the length of '_nnn_' compared to the original value. -// // These adjustments will align properly with 'text'. -// if ( results.getNumericSequence() >= 0 && results.getNumericSequencePattern() != null ) { -// adjustment = 5 - results.getNumericSequencePattern().length(); -// } -// -// // Warning this is not case insensitive in the results: -// if ( textLowercase.contains( test1 ) ) { -// -// int idx = textLowercase.indexOf( test1 ); -// int idxStart = idx + 1; -// -// -// int idxEnd = idx + test1.length() - 1 - adjustment; -// String identifier = text.substring( idxStart, idxEnd); -// -// results.setIdentifier( identifier, escLeft, escRight ); -// results.setPlaceholder( this ); -// -//// results.setIdentifier( key, escLeft, escRight ); -// foundIdentifier = true; -// } -// else if ( text.contains( test2 ) ) { -// -// // The key1 and key2 helps ensure that the full placeholder, -// // including the attribute, is replaced: -// String key1 = test2; -// String key2 = escRight; -// -// int idx = text.indexOf( key1 ); -// int idx2 = ( idx == -1 ? -1 : text.indexOf( key2, idx + key1.length() - 1 ) ) - adjustment; -// if ( idx > -1 && idx2 > -1 ) { -// -// String identifier = text.substring( idx + 1, idx2 ); -// -// results.setIdentifier( identifier, escLeft, escRight ); -// results.setPlaceholder( this ); -// -// foundIdentifier = true; -//// results = results.replace("{" + identifier + "}", -//// pm.getTranslatePlayerPlaceHolder( playerUuid, playerName, identifier ) ); -// } -// } -//// else if ( textLowercase.contains( key ) ) { -//// -//// int idx = textLowercase.indexOf( key ); -//// int idxStart = idx + 1; -//// -//// -//// int idxEnd = idx + key.length() - 1 - adjustment; -//// String identifier = text.substring( idxStart, idxEnd); -//// -//// results.setIdentifier( identifier, "", "" ); -//// results.setPlaceholder( this ); -//// -////// results.setIdentifier( key, escLeft, escRight ); -//// foundIdentifier = true; -//// } -// -// return foundIdentifier; -// } @Override public String toString() { 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 023e5e733..6d19db18d 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 @@ -229,9 +229,6 @@ public String format( Double value ) { break; } -// if ( results.contains( "^|^" ) ) { -// //results = results.replace( "^|^", "&" ); -// } } catch (Exception e ) { 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 index 7afcdfe6c..7edb38e48 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderAttributeTime.java +++ b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderAttributeTime.java @@ -74,15 +74,6 @@ public class PlaceholderAttributeTime 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. 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 8da017fef..6b9898ec6 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 @@ -180,26 +180,6 @@ public void setPlayer( UUID playerUuid, String playerName ) { player = Prison.get().getPlatform().getRankPlayer( playerUuid, playerName ); -// if ( playerUuid != null ) { -// player = Prison.get().getPlatform().getPlayer( playerUuid ).orElse( null ); -// } -// -// if ( player == null && playerName != null ) { -// -// player = Prison.get().getPlatform().getPlayer( playerName ).orElse( null ); -// } -// -// if ( player == null && playerUuid != null ) { -// -// player = Prison.get().getPlatform().getOfflinePlayer( playerUuid ).orElse( null ); -// } -// -// if ( player == null && playerName != null ) { -// -// player = Prison.get().getPlatform().getOfflinePlayer( playerName ).orElse( null ); -// } - - if ( player != null ) { setPlayer(player); } 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 64c1b2072..461e7d367 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 @@ -31,137 +31,136 @@ public class PlaceholderManager { public static Pattern PLACEHOLDER_ESCAPE_CHARACTER_RIGHT_PATTERN = Pattern.compile( "(\\p{Punct}$)" ); -// private PlaceholderProgressBarConfig progressBarConfig; public enum placeholderFlagType { - supress, - sequence, - normal + supress, + sequence, + normal } public enum PlaceholderFlags { - // PlayerManager - PLAYER, - LADDERS, - - - // RankManager - RANKS, - RANKPLAYERS, - STATSRANKS( true ), - STATSPLAYERS( true ), - - - // MineManager - MINES, - MINEPLAYERS, - PLAYERBLOCKS, - STATSMINES( true ), - - // A custom prison placeholder is one that starts with `prison__` and it cannot have any - // placeholder attributes. Basically, it's a substitution of the custom placeholder - // with whatever has been paired to it within the config.yml file. The mappings can - // be as long as needed and contain any other combination of other placeholders. - CUSTOM, - - SUPRESS, - ALIAS, - ONLY_DEFAULT_OR_PRESTIGES - ; - - private final boolean sequence; - - @SuppressWarnings("unused") - private final String desc; - - private PlaceholderFlags() { - this.sequence = false; - this.desc = null; - } - private PlaceholderFlags( boolean hasSequence ) { - this.sequence = hasSequence; - this.desc = null; - } + // PlayerManager + PLAYER, + LADDERS, + + + // RankManager + RANKS, + RANKPLAYERS, + STATSRANKS( true ), + STATSPLAYERS( true ), + + + // MineManager + MINES, + MINEPLAYERS, + PLAYERBLOCKS, + STATSMINES( true ), + + // A custom prison placeholder is one that starts with `prison__` and it cannot have any + // placeholder attributes. Basically, it's a substitution of the custom placeholder + // with whatever has been paired to it within the config.yml file. The mappings can + // be as long as needed and contain any other combination of other placeholders. + CUSTOM, + + SUPRESS, + ALIAS, + ONLY_DEFAULT_OR_PRESTIGES + ; - /** - *

    This identifies if a placeholder type contains a sequence as - * part of its placeholder name. For example a sequence would be - * identified as '_nnn_' where 'n' represents a positive number and - * can be 1 digit in length or more. Three 'n's are used to represent - * this numeric sequence, but does not require it to be three digits - * in length. The number may also be left-padded with zeros; as long - * as it parses successfully with Integer.parse(). - *

    - * - * @return - */ - public boolean hasSequence() { - return sequence; - } + private final boolean sequence; + + @SuppressWarnings("unused") + private final String desc; + + private PlaceholderFlags() { + this.sequence = false; + this.desc = null; + } + private PlaceholderFlags( boolean hasSequence ) { + this.sequence = hasSequence; + this.desc = null; + } + + /** + *

    This identifies if a placeholder type contains a sequence as + * part of its placeholder name. For example a sequence would be + * identified as '_nnn_' where 'n' represents a positive number and + * can be 1 digit in length or more. Three 'n's are used to represent + * this numeric sequence, but does not require it to be three digits + * in length. The number may also be left-padded with zeros; as long + * as it parses successfully with Integer.parse(). + *

    + * + * @return + */ + public boolean hasSequence() { + return sequence; + } } public enum PlaceholderAttributePrefixes { - nFormat, - bar, - text, - time; - - public static PlaceholderAttributePrefixes fromString( String value ) { - PlaceholderAttributePrefixes pap = null; - - if ( value != null ) { - for ( PlaceholderAttributePrefixes attrPrefix : values() ) { - if ( attrPrefix.name().equalsIgnoreCase( value ) ) { - pap = attrPrefix; - } - } - } - - return pap; - } + nFormat, + bar, + text, + time; + + public static PlaceholderAttributePrefixes fromString( String value ) { + PlaceholderAttributePrefixes pap = null; + + if ( value != null ) { + for ( PlaceholderAttributePrefixes attrPrefix : values() ) { + if ( attrPrefix.name().equalsIgnoreCase( value ) ) { + pap = attrPrefix; + } + } + } + + return pap; + } } public enum NumberTransformationUnitTypes { - none, - kmg, - kmbt, - binary; - - public static NumberTransformationUnitTypes fromString( String value ) { - NumberTransformationUnitTypes pap = none; - - if ( value != null ) { - for ( NumberTransformationUnitTypes nTrans : values() ) { - if ( nTrans.name().equalsIgnoreCase( value ) ) { - pap = nTrans; - } - } - } + none, + kmg, + kmbt, + binary; + + public static NumberTransformationUnitTypes fromString( String value ) { + NumberTransformationUnitTypes pap = none; + + if ( value != null ) { + for ( NumberTransformationUnitTypes nTrans : values() ) { + if ( nTrans.name().equalsIgnoreCase( value ) ) { + pap = nTrans; + } + } + } - return pap; - } + return pap; + } } 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; - } + 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; + } } /** @@ -972,80 +971,6 @@ private static String getAllChatTexts( boolean omitSuppressable) { } - -// /** -// *

    This will extract attributes from dynamic placeholders and will return. -// *

    -// * -// *

    Planning on using : as separators. :: for identifying each attribute, and then -// * within each attribute : will separate the individual fields and values. -// * For example it a number format attribute could look like this: -// *

    -// * -// *
    ::nFormat:0.00{unit}
    for no spaces. -// *
    ::nFormat:#,##0.0+{unit}
    for spaces since + will be converted to spaces. -// * -// * @param placeholder -// * @return -// */ -// public PlaceholderAttribute extractPlaceholderExtractAttribute( String placeholder ) { -// PlaceholderAttribute attribute = null; -// -// if ( placeholder != null ) { -// String[] attributes = placeholder.split( PRISON_PLACEHOLDER_ATTRIBUTE_SEPARATOR ); -// -// // attributes[0] will be the placeholder, so ignore: -// if ( attributes != null && attributes.length > 1 ) { -// for ( int i = 1; i < attributes.length ; i++ ) { -// String rawAttribute = attributes[i]; -// -// if ( rawAttribute != null ) { -// attribute = attributeFactory( rawAttribute ); -// break; -// } -// } -// } -// } -// -// return attribute; -// } - - -// private PlaceholderAttribute attributeFactory( String rawAttribute ) { -// PlaceholderAttribute attribute = null; -// -// if ( rawAttribute != null && !rawAttribute.isEmpty() ) { -// ArrayList parts = new ArrayList<>(); -// parts.addAll( Arrays.asList( rawAttribute.split( PRISON_PLACEHOLDER_ATTRIBUTE_FIELD_SEPARATOR )) ); -// -// if ( parts.size() > 1 ) { -// PlaceholderAttributePrefixes pap = PlaceholderAttributePrefixes.fromString( parts.get( 0 ) ); -// -// switch ( pap ) -// { -// case nFormat: -// attribute = new PlaceholderAttributeNumberFormat( parts, rawAttribute ); -// break; -// -// case bar: -// attribute = new PlaceholderAttributeBar( parts, getProgressBarConfig(), rawAttribute ); -// break; -// -// case text: -// attribute = new PlaceholderAttributeText( parts, rawAttribute ); -// break; -// -// default: -// break; -// } -// -// } -// -// } -// -// return attribute; -// } - public String extractPlaceholderString( String identifier ) { String results = null; @@ -1063,171 +988,4 @@ public String extractPlaceholderString( String identifier ) { return results; } -// public void reloadPlaceholderBarConfig() { -// setProgressBarConfig( loadPlaceholderBarConfig() ); -// } -// -// public PlaceholderProgressBarConfig loadPlaceholderBarConfig() { -// PlaceholderProgressBarConfig config = null; -// -// String barSegmentsStr = Prison.get().getPlatform().getConfigString( -// "placeholder.bar-segments" ); -// String barPositiveColor = Prison.get().getPlatform().getConfigString( -// "placeholder.bar-positive-color" ); -// String barPositiveSegment = Prison.get().getPlatform().getConfigString( -// "placeholder.bar-positive-segment" ); -// String barNegativeColor = Prison.get().getPlatform().getConfigString( -// "placeholder.bar-negative-color" ); -// String barNegativeSegment = Prison.get().getPlatform().getConfigString( -// "placeholder.bar-negative-segment" ); -// -// -// // All 5 must not be null: -// if ( barSegmentsStr != null && barPositiveColor != null && barPositiveSegment != null && -// barNegativeColor != null && barNegativeSegment != null ) { -// -// int barSegments = 20; -// -// try { -// barSegments = Integer.parseInt( barSegmentsStr ); -// } -// catch ( NumberFormatException e ) { -// Output.get().logWarn( -// "IntegrationManager.loadPlaceholderBarConfigs(): Failure to convert the" + -// "/plugins/Prison/config.yml prison-placeholder-configs.progress-bar.bar-segments " + -// "to a valid integer. Defaulting to a value of 20 " + -// "[" + barSegmentsStr + "] " + e.getMessage() ); -// -// } -// -// config = new PlaceholderProgressBarConfig( barSegments, -// barPositiveColor, barPositiveSegment, -// barNegativeColor, barNegativeSegment ); -// } -// -// if ( config == null ) { -// // go with default values because the config.yml is not up to date with -// // the default values -// -// config = new PlaceholderProgressBarConfig( -// 20, "&2", "#", "&4", "=" -//// 20, "&2", "â–Š", "&4", "â–’" -// ); -// -// Output.get().logInfo( "The /plugins/Prison/config.yml does not contain the " + -// "default values for the Placeholder Progress Bar." ); -// Output.get().logInfo( "Default values are " + -// "being used. To customize the bar, rename the config.yml and it will be " + -// "regenerated and then edit to restore prior values."); -// -// } -// -// return config; -// } -// -// public PlaceholderProgressBarConfig getProgressBarConfig() { -// if ( progressBarConfig == null ) { -// progressBarConfig = loadPlaceholderBarConfig(); -// } -// return progressBarConfig; -// } -// public void setProgressBarConfig( PlaceholderProgressBarConfig progressBarConfig ) { -// this.progressBarConfig = progressBarConfig; -// } -// -// /** -// *

    This function uses the settings within the config.yml to construct a progress -// * bar. It takes two numeric values and constructs it upon those parameters. -// * The parameter

    value
    is the value that changes, and is the value that -// * sets where the bar changes. The parameter
    valueTotal
    is the max value -// * of where the
    value
    is increasing to. -// *

    -// * -// *

    The lowest range is always zero and

    value
    will be set to zero if -// * it is negative. If
    value
    is greater than
    valueTotal
    -// * then it will be set to that value. The valid range for this function is only 0 percent -// * to 100 percent. -// *

    -// * -// *

    If the progress bar is moving in the wrong direction, then set the parameter -// *

    reverse
    to true and then the
    value
    will be inverted by subtracting -// * its value from
    valueTotal
    . -// *

    -// * -// * @param value A value that is changing. Will be set to zero if negative. Will be -// * set to valueTotal if greater than that amount. -// * @param valueTotal The target value that is non-changing. -// * @param reverse Changes the growth direction of the progress bar. -// * @param attribute -// * @return -// */ -// public String getProgressBar( double value, double valueTotal, boolean reverse, -// PlaceholderAttribute attribute ) { -// StringBuilder sb = new StringBuilder(); -// -// // value cannot be greater than valueTotal: -// if ( value > valueTotal ) { -// value = valueTotal; -// } -// else if ( value < 0 ) { -// value = 0; -// } -// -// // If reverse, then the new value is subtracted from valueTotal: -// if ( reverse ) { -// value = valueTotal - value; -// } -// -// double percent = valueTotal == 0 ? 100d : value / valueTotal * 100.0; -// -// PlaceholderAttributeBar barAttribute = attribute == null || -// !(attribute instanceof PlaceholderAttributeBar) ? null : -// (PlaceholderAttributeBar) attribute; -// -//// Output.get().logInfo( "### @@@ ### getProgressBar: barAttribute: " + -//// ( barAttribute != null ? "true" : "false")); -// -// PlaceholderProgressBarConfig barConfig = -// barAttribute != null ? barAttribute.getBarConfig() : -// getProgressBarConfig(); -// -// String lastColorCode = null; -// int segments = barConfig.getSegments(); -// for ( int i = 0; i < segments; i++ ) { -// double pct = i / ((double)barConfig.getSegments()) * 100.0; -// -// // If the calculated percent is less than the threshold and as long as it's not the last -// // segment, then show a positive. If it's the last segment an it's still less than -// // the percent, then show a negative no matter what to indicate it's not yet there. -// if ( pct < percent && (percent == 100d || percent < 100d && i < segments - 1)) { -// if ( lastColorCode == null || -// !barConfig.getPositiveColor().equalsIgnoreCase( lastColorCode )) { -// sb.append( barConfig.getPositiveColor() ); -// lastColorCode = barConfig.getPositiveColor(); -// } -// sb.append( barConfig.getPositiveSegment() ); -// } -// else { -// if ( lastColorCode == null || -// !barConfig.getNegativeColor().equalsIgnoreCase( lastColorCode )) { -// sb.append( barConfig.getNegativeColor() ); -// lastColorCode = barConfig.getNegativeColor(); -// } -// sb.append( barConfig.getNegativeSegment() ); -// -// } -// } -// -// -// if ( barConfig.isReverse() ) { -// sb.reverse(); -// } -// -// -// return sb.toString(); -// } - - - - } 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 e48f2f327..1d219b5cb 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 @@ -266,9 +266,9 @@ else if ( value < 0 ) { // Output.get().logInfo( "### @@@ ### getProgressBar: barAttribute: " + // ( barAttribute != null ? "true" : "false")); - PlaceholderProgressBarConfig barConfig = - attributeBar != null ? attributeBar.getBarConfig() : - getProgressBarConfig(); + PlaceholderProgressBarConfig barConfig = + attributeBar != null ? attributeBar.getBarConfig() : + getProgressBarConfig(); String lastColorCode = null; int segments = barConfig.getSegments(); @@ -303,7 +303,7 @@ else if ( value < 0 ) { } - return sb.toString(); + return sb.toString(); } protected void convertPlaceholderSequence( PlaceholderIdentifier pIdentifier ) { @@ -319,8 +319,8 @@ protected void convertPlaceholderSequence( PlaceholderIdentifier pIdentifier ) { pIdentifier.setIdentifier( pIdentifier.getIdentifier().replace( group1, "_nnn_" ) ); -// Output.get().logInfo( "### PlaceHolderKey: seq pattern detected: " + placeholder.name() + -// " group0= " + group0 + " group1= " + group1 + " group2= " + group2 + " replacedText: " + textLowercase ); +// Output.get().logInfo( "### PlaceHolderKey: seq pattern detected: " + placeholder.name() + +// " group0= " + group0 + " group1= " + group1 + " group2= " + group2 + " replacedText: " + textLowercase ); pIdentifier.setSequencePattern( group1 ); @@ -394,12 +394,8 @@ else if ( !pIdentifier.getIdentifierRaw().startsWith( "_" ) ) { int len = pIdentifier.getIdentifierRaw().length(); pIdentifier.setIdentifierRaw( pIdentifier.getIdentifierRaw().substring(0, len - group0Right.length() ) ); } - } - } - } - } diff --git a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderResults.java b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderResults.java index c6cf0ae9c..0af5ca7f1 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderResults.java +++ b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderResults.java @@ -14,118 +14,114 @@ @Deprecated public class PlaceholderResults { - private String identifier; - - private PlaceHolderKey placeholder; - private String escapeLeft; - private String esccapeRight; - - private String numericSequencePattern; - private int numericSequence = -1; - + // NOTE: This class is no longer used and all the code has been commented out before being purged. - - private String text; - -// public PlaceholderResults( PlaceHolderKey placeholder ) { +// private String identifier; +// +// private PlaceHolderKey placeholder; +// private String escapeLeft; +// private String esccapeRight; +// +// private String numericSequencePattern; +// private int numericSequence = -1; +// +// +// +// private String text; +// +// public PlaceholderResults( PlaceHolderKey placeholder, String text ) { // super(); // // this.placeholder = placeholder; -// this.text = null; -// } - public PlaceholderResults( PlaceHolderKey placeholder, String text ) { - super(); - - this.placeholder = placeholder; - - - this.text = text; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - - if ( getPlaceholder() != null ) { - sb.append( getPlaceholder().getPlaceholder().name() ) - .append( " " ) - .append( getEscapeLeft() == null ? "" : getEscapeLeft() ) - .append( getEsccapeRight() == null ? "" : getEsccapeRight() ) - .append( " " ) - .append( getIdentifier() == null ? "" : getIdentifier() ); - - } - else { - sb.append( "-- no match --" ); - } - - return sb.toString(); - } - - public boolean hasResults() { - return getIdentifier() != null && getPlaceholder() != null; - } - - public void setIdentifier( String identifier, String escapeLeft, String esccapeRight ) { - setIdentifier( identifier ); - - setEscapeLeft( escapeLeft ); - setEsccapeRight( esccapeRight ); - } - - - public String getEscapedIdentifier() { - return getEscapeLeft() + getIdentifier() + getEsccapeRight(); - } - - - public PlaceHolderKey getPlaceholder() { - return placeholder; - } - public void setPlaceholder( PlaceHolderKey placeholder ) { - this.placeholder = placeholder; - } - - public String getText() { - return text; - } - public void setText(String text) { - this.text = text; - } - - public String getIdentifier() { - return identifier; - } - public void setIdentifier( String identifier ) { - this.identifier = identifier; - } - - public String getNumericSequencePattern() { - return numericSequencePattern; - } - public void setNumericSequencePattern( String numericSequencePattern ) { - this.numericSequencePattern = numericSequencePattern; - } - - public int getNumericSequence() { - return numericSequence; - } - public void setNumericSequence( int numericSequence ) { - this.numericSequence = numericSequence; - } - - public String getEscapeLeft() { - return escapeLeft; - } - public void setEscapeLeft( String escapeLeft ) { - this.escapeLeft = escapeLeft; - } - - public String getEsccapeRight() { - return esccapeRight; - } - public void setEsccapeRight( String esccapeRight ) { - this.esccapeRight = esccapeRight; - } +// +// +// this.text = text; +// } +// +// @Override +// public String toString() { +// StringBuilder sb = new StringBuilder(); +// +// if ( getPlaceholder() != null ) { +// sb.append( getPlaceholder().getPlaceholder().name() ) +// .append( " " ) +// .append( getEscapeLeft() == null ? "" : getEscapeLeft() ) +// .append( getEsccapeRight() == null ? "" : getEsccapeRight() ) +// .append( " " ) +// .append( getIdentifier() == null ? "" : getIdentifier() ); +// +// } +// else { +// sb.append( "-- no match --" ); +// } +// +// return sb.toString(); +// } +// +// public boolean hasResults() { +// return getIdentifier() != null && getPlaceholder() != null; +// } +// +// public void setIdentifier( String identifier, String escapeLeft, String esccapeRight ) { +// setIdentifier( identifier ); +// +// setEscapeLeft( escapeLeft ); +// setEsccapeRight( esccapeRight ); +// } +// +// +// public String getEscapedIdentifier() { +// return getEscapeLeft() + getIdentifier() + getEsccapeRight(); +// } +// +// +// public PlaceHolderKey getPlaceholder() { +// return placeholder; +// } +// public void setPlaceholder( PlaceHolderKey placeholder ) { +// this.placeholder = placeholder; +// } +// +// public String getText() { +// return text; +// } +// public void setText(String text) { +// this.text = text; +// } +// +// public String getIdentifier() { +// return identifier; +// } +// public void setIdentifier( String identifier ) { +// this.identifier = identifier; +// } +// +// public String getNumericSequencePattern() { +// return numericSequencePattern; +// } +// public void setNumericSequencePattern( String numericSequencePattern ) { +// this.numericSequencePattern = numericSequencePattern; +// } +// +// public int getNumericSequence() { +// return numericSequence; +// } +// public void setNumericSequence( int numericSequence ) { +// this.numericSequence = numericSequence; +// } +// +// public String getEscapeLeft() { +// return escapeLeft; +// } +// public void setEscapeLeft( String escapeLeft ) { +// this.escapeLeft = escapeLeft; +// } +// +// public String getEsccapeRight() { +// return esccapeRight; +// } +// public void setEsccapeRight( String esccapeRight ) { +// this.esccapeRight = esccapeRight; +// } } diff --git a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderStatsData.java b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderStatsData.java index 9524708b0..710e7c07b 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderStatsData.java +++ b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderStatsData.java @@ -5,7 +5,6 @@ public class PlaceholderStatsData { private String placeholderId; private PlaceHolderKey placeholderKey; -// private PrisonPlaceHolders placeholder; private int hits = 0; private int failHits = 0; @@ -149,16 +148,10 @@ public void setPlaceholderKey(PlaceHolderKey placeholderKey) { public int getHits() { return hits; } -// private void setHits(int hits) { -// this.hits = hits; -// } public int getFailHits() { return failHits; } -// private void setFailHits(int failHits) { -// this.failHits = failHits; -// } public long getTotalDurationNanos() { return totalDurationNanos; @@ -167,13 +160,8 @@ public void setTotalDurationNanos(long totalDurationNanos) { this.totalDurationNanos = totalDurationNanos; } - public boolean isFailedMatch() { return failedMatch; } -// private void setFailedMatch(boolean failedMatch) { -// this.failedMatch = failedMatch; -// } - } diff --git a/prison-core/src/main/java/tech/mcprison/prison/placeholders/Placeholders.java b/prison-core/src/main/java/tech/mcprison/prison/placeholders/Placeholders.java index dc970203a..f322d4f9c 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/placeholders/Placeholders.java +++ b/prison-core/src/main/java/tech/mcprison/prison/placeholders/Placeholders.java @@ -9,9 +9,6 @@ public interface Placeholders { -// public void initializePlaceholderManagers(); - - public Map getPlaceholderDetailCounts(); @@ -24,9 +21,6 @@ public interface Placeholders { public String placeholderTranslate(UUID playerUuid, String playerName, String identifier); -// pu-blic String placeholderTranslateText( String text); - - public String placeholderTranslateText( UUID playerUuid, String playerName, String text); 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 56ad91a77..136e1caad 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 @@ -73,7 +73,6 @@ public PlaceholderStatsData getStats( PlaceholderIdentifier pId ) { // Else create a new cache entry: results = new PlaceholderStatsData( key ); -// getPlaceholders().put( key, results ); // Store this new stats object in the cache. If there is a placeholder fail, then // this will help prevent going through all of the calculations for future 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 101ebca6e..8250b9993 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 @@ -89,44 +89,6 @@ public static String formattedTime( double timeSec ) { return formattedTime; -// StringBuilder sb = new StringBuilder(); -// -// long days = (long)(timeSec / TIME_DAY); -// timeSec -= (days * TIME_DAY); -// if ( days > 0 ) { -// sb.append( days ); -// // y,m,w,d,h,m,s -// sb.append( prefixesTimeUnits.get(3) ).append( " " ); -//// sb.append( "d " ); -// } -// -// long hours = (long)(timeSec / TIME_HOUR); -// timeSec -= (hours * TIME_HOUR); -// if ( sb.length() > 0 || hours > 0 ) { -// sb.append( hours ); -// // y,m,w,d,h,m,s -// sb.append( prefixesTimeUnits.get(4) ).append( " " ); -//// sb.append( "h " ); -// } -// -// long mins = (long)(timeSec / TIME_MINUTE); -// timeSec -= (mins * TIME_MINUTE); -// if ( sb.length() > 0 || mins > 0 ) { -// sb.append( mins ); -// // y,m,w,d,h,m,s -// sb.append( prefixesTimeUnits.get(5) ).append( " " ); -//// sb.append( "m " ); -// } -// -// double secs = (double)(timeSec / TIME_SECOND); -// timeSec -= (secs * TIME_SECOND); -// DecimalFormat dFmt = Prison.get().getDecimalFormat("#0"); -// sb.append( dFmt.format( secs )); -// // y,m,w,d,h,m,s -// sb.append( prefixesTimeUnits.get(6) ).append( " " ); -//// sb.append( "s " ); -// -// return sb.toString(); } /** @@ -147,11 +109,11 @@ public static String formattedMetricSISize( double amount ) { } public static String formattedMetricSISize( double amount, DecimalFormat dFmt, String spaces ) { - StringBuilder unit = new StringBuilder(); - - amount = divBy1000( amount, unit, " kMGTPEZY" ); - - String results = dFmt.format( amount ) + spaces + unit.toString(); + StringBuilder unit = new StringBuilder(); + + amount = divBy1000( amount, unit, " kMGTPEZY" ); + + String results = dFmt.format( amount ) + spaces + unit.toString(); return results.trim(); } @@ -167,16 +129,16 @@ public static String formattedKmbtSISize( double amount, DecimalFormat dFmt, Str } private static double divBy1000( double amount, StringBuilder unit, String units ) { - if ( amount < 1000.0 || units.length() == 1 ) { - unit.append( units.subSequence( 0, 1 ) ); - } - else { - // Div amount by 1000.0 and remove the first character of the units: - amount /= 1000.0; - units = units.substring( 1 ); - amount = divBy1000( amount, unit, units ); - } - return amount; + if ( amount < 1000.0 || units.length() == 1 ) { + unit.append( units.subSequence( 0, 1 ) ); + } + else { + // Div amount by 1000.0 and remove the first character of the units: + amount /= 1000.0; + units = units.substring( 1 ); + amount = divBy1000( amount, unit, units ); + } + return amount; } @@ -187,28 +149,28 @@ public static String formattedPrefixBinarySize( double amount ) { } public static String formattedIPrefixBinarySize( double amount, DecimalFormat dFmt, String spaces ) { - StringBuilder unit = new StringBuilder(); - - amount = divBy1024( amount, unit, 0 ); - - String results = dFmt.format( amount ) + spaces + unit.toString(); + StringBuilder unit = new StringBuilder(); + + amount = divBy1024( amount, unit, 0 ); + + String results = dFmt.format( amount ) + spaces + unit.toString(); return results.trim(); } private static double divBy1024( double amount, StringBuilder unit, int prefixesBinaryPos ) { - if ( prefixesBinary.size() == 0) { - // no prefixesBinary units have been defined, so exit returning the original amount: - } - else if ( amount < 1024.0 || prefixesBinary.size() == (prefixesBinaryPos + 1)) { - unit.append( prefixesBinary.get( prefixesBinaryPos ) ); - } - else { - // Div amount by 1000.0 and then recursively call this function while adding one to pos: - amount /= 1024.0; - amount = divBy1024( amount, unit, prefixesBinaryPos + 1 ); - } - return amount; + if ( prefixesBinary.size() == 0) { + // no prefixesBinary units have been defined, so exit returning the original amount: + } + else if ( amount < 1024.0 || prefixesBinary.size() == (prefixesBinaryPos + 1)) { + unit.append( prefixesBinary.get( prefixesBinaryPos ) ); + } + else { + // Div amount by 1000.0 and then recursively call this function while adding one to pos: + amount /= 1024.0; + amount = divBy1024( amount, unit, prefixesBinaryPos + 1 ); + } + return amount; } } diff --git a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PrisonCustomPlaceholders.java b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PrisonCustomPlaceholders.java index b4216dca1..c12168b26 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PrisonCustomPlaceholders.java +++ b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PrisonCustomPlaceholders.java @@ -43,30 +43,30 @@ public String getTranslateCustomPlaceHolder( PlaceholderIdentifier identifier ) public String getTranslateCustomPlaceHolder( UUID playerUuid, String playerName, String identifier ) { - String results = null; - - if ( playerUuid != null ) { - - List placeHolderKeys = getTranslatedPlaceHolderKeys(); - - - PlaceholderIdentifier phIdentifier = new PlaceholderIdentifier( identifier ); - phIdentifier.setPlayer(playerUuid, playerName); - - - for ( PlaceHolderKey placeHolderKey : placeHolderKeys ) { - - if ( phIdentifier.checkPlaceholderKey(placeHolderKey) ) { - - results = placeHolderKey.getData(); - - break; - } - - } - } - - return results; + String results = null; + + if ( playerUuid != null ) { + + List placeHolderKeys = getTranslatedPlaceHolderKeys(); + + + PlaceholderIdentifier phIdentifier = new PlaceholderIdentifier( identifier ); + phIdentifier.setPlayer(playerUuid, playerName); + + + for ( PlaceHolderKey placeHolderKey : placeHolderKeys ) { + + if ( phIdentifier.checkPlaceholderKey(placeHolderKey) ) { + + results = placeHolderKey.getData(); + + break; + } + + } + } + + return results; } /** @@ -95,48 +95,40 @@ public String getTranslateCustomPlaceHolder( UUID playerUuid, String playerName, public List getTranslatedPlaceHolderKeys() { if ( translatedPlaceHolderKeys == null ) { - translatedPlaceHolderKeys = new ArrayList<>(); - -// FileConfiguration config = SpigotPrison.getInstance().getConfig(); - - Platform pf = Prison.get().getPlatform(); - - if ( pf.isConfigSection(CUSTOM_PLACEHOLDER_CONFIG_PATH) ) { - - - - PrisonPlaceHolders customPlaceholder = PrisonPlaceHolders.custom_placeholder__; - - - List keys = pf.getConfigHashKeys(CUSTOM_PLACEHOLDER_CONFIG_PATH); - -// ConfigurationSection cpConfigs = config.getConfigurationSection(CUSTOM_PLACEHOLDER_CONFIG_PATH); -// -// Set keys = cpConfigs.getKeys( false ); - - for (String key : keys) { - - String keyPath = CUSTOM_PLACEHOLDER_CONFIG_PATH + "." + key; - - String custExpandedPlaceholderKey = keyPath + ".placeholder"; - String custExpandedPapiExpansionKey = keyPath + ".papi_expansion"; - String custExpandedDescriptionKey = keyPath + ".description"; - - String cePlaceholder = pf.getConfigString( custExpandedPlaceholderKey ); - boolean cePapiExpansion = pf.getConfigBooleanFalse( custExpandedPapiExpansionKey ); - String ceDescription = pf.getConfigString( custExpandedDescriptionKey ); - - String customPlaceholderStr = - cePlaceholder != null ? - cePlaceholder : pf.getConfigString( keyPath ); - - PlaceHolderKey placeholder = new PlaceHolderKey(key, customPlaceholder, customPlaceholderStr ); - placeholder.setPapiExpansion( cePapiExpansion ); - placeholder.setDescription( ceDescription ); - - translatedPlaceHolderKeys.add(placeholder); - } - } + translatedPlaceHolderKeys = new ArrayList<>(); + + Platform pf = Prison.get().getPlatform(); + + if ( pf.isConfigSection(CUSTOM_PLACEHOLDER_CONFIG_PATH) ) { + + PrisonPlaceHolders customPlaceholder = PrisonPlaceHolders.custom_placeholder__; + + List keys = pf.getConfigHashKeys(CUSTOM_PLACEHOLDER_CONFIG_PATH); + + + for (String key : keys) { + + String keyPath = CUSTOM_PLACEHOLDER_CONFIG_PATH + "." + key; + + String custExpandedPlaceholderKey = keyPath + ".placeholder"; + String custExpandedPapiExpansionKey = keyPath + ".papi_expansion"; + String custExpandedDescriptionKey = keyPath + ".description"; + + String cePlaceholder = pf.getConfigString( custExpandedPlaceholderKey ); + boolean cePapiExpansion = pf.getConfigBooleanFalse( custExpandedPapiExpansionKey ); + String ceDescription = pf.getConfigString( custExpandedDescriptionKey ); + + String customPlaceholderStr = + cePlaceholder != null ? + cePlaceholder : pf.getConfigString( keyPath ); + + PlaceHolderKey placeholder = new PlaceHolderKey(key, customPlaceholder, customPlaceholderStr ); + placeholder.setPapiExpansion( cePapiExpansion ); + placeholder.setDescription( ceDescription ); + + translatedPlaceHolderKeys.add(placeholder); + } + } } return translatedPlaceHolderKeys; } From ed31ae56862d4936ed9456c560b507a8617043db Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 6 Mar 2026 17:36:34 -0500 Subject: [PATCH 310/323] Prison Cleanup: prison-core: Removed obsolete and unneeded comments and fix indentation where needed. Third part. --- docs/changelog_v3.3.x.md | 3 + .../tech/mcprison/prison/commands/Arg.java | 4 +- .../prison/commands/ArgumentHandler.java | 3 +- .../prison/commands/BaseCommands.java | 85 -- .../prison/commands/CommandArgument.java | 3 +- .../prison/commands/CommandHandler.java | 755 ++++++++---------- .../prison/commands/CommandPagedData.java | 12 +- .../tech/mcprison/prison/commands/Flags.java | 4 +- .../prison/commands/PluginCommand.java | 28 +- .../prison/commands/RegisteredCommand.java | 281 +++---- .../prison/commands/TabCompleaterData.java | 23 +- .../mcprison/prison/commands/Wildcard.java | 4 +- .../handlers/BlockArgumentHandler.java | 51 +- .../handlers/DoubleArgumentHandler.java | 7 +- .../handlers/DoubleClassArgumentHandler.java | 36 +- .../handlers/IntegerArgumentHandler.java | 7 +- .../handlers/IntegerClassArgumentandler.java | 40 +- .../handlers/LongArgumentHandler.java | 7 +- .../handlers/LongClassArgumentHandler.java | 30 +- .../handlers/NumberArgumentHandler.java | 5 +- .../handlers/PlayerArgumentHandler.java | 3 +- .../handlers/StringArgumentHandler.java | 9 +- .../handlers/WorldArgumentHandler.java | 3 +- .../prison/discord/DiscordWebhook.java | 3 - .../prison/discord/PrisonDiscordWebhook.java | 4 +- .../prison/discord/PrisonPasteChat.java | 2 - .../prison/discord/PrisonSupportFiles.java | 34 +- .../discord/PrisonSupportLinkageData.java | 46 +- .../mcprison/prison/file/FileCollection.java | 158 ++-- .../mcprison/prison/file/FileDatabase.java | 79 +- .../tech/mcprison/prison/file/FileIO.java | 181 ++--- .../mcprison/prison/file/FileStorage.java | 84 +- .../prison/file/FileVirtualDelete.java | 46 +- .../tech/mcprison/prison/file/YamlFileIO.java | 29 - .../integration/CustomBlockIntegration.java | 1 - .../integration/IntegrationManager.java | 207 ++--- .../mcprison/prison/internal/ArmorStand.java | 6 - .../prison/internal/CommandSender.java | 19 - .../tech/mcprison/prison/internal/Entity.java | 1 - .../mcprison/prison/internal/EulerAngle.java | 2 - .../mcprison/prison/internal/ItemStack.java | 76 +- .../tech/mcprison/prison/internal/World.java | 2 - .../mcprison/prison/internal/block/Block.java | 15 - .../prison/internal/block/BlockFace.java | 16 +- .../prison/internal/block/BlockState.java | 10 +- .../mcprison/prison/internal/block/Door.java | 15 +- .../internal/block/MineTargetBlockKey.java | 7 - .../internal/block/MineTargetPrisonBlock.java | 9 - .../prison/internal/block/PrisonBlock.java | 50 -- .../internal/block/PrisonBlockStatusData.java | 28 - .../internal/block/PrisonBlockTypes.java | 6 - .../events/block/BlockBreakEvent.java | 9 +- .../events/block/BlockPlaceEvent.java | 11 +- .../internal/events/inventory/BrewEvent.java | 2 - .../events/inventory/CraftItemEvent.java | 2 - .../events/inventory/FurnaceBurnEvent.java | 2 - .../events/inventory/FurnaceExtractEvent.java | 5 - .../events/inventory/FurnaceSmeltEvent.java | 2 - .../events/inventory/InventoryClickEvent.java | 2 - .../events/inventory/InventoryCloseEvent.java | 2 - .../inventory/InventoryCreativeEvent.java | 2 - .../events/inventory/InventoryDragEvent.java | 2 - .../inventory/InventoryInteractEvent.java | 8 +- .../inventory/InventoryMoveItemEvent.java | 2 - .../events/inventory/InventoryOpenEvent.java | 2 - .../events/inventory/PrepareAnvilEvent.java | 2 - .../inventory/PrepareItemCraftEvent.java | 2 - 67 files changed, 1002 insertions(+), 1594 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 19e22e779..73facc9d9 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.19j 2026-03-06 +* **Prison Cleanup: prison-core: Removed obsolete and unneeded comments and fix indentation where needed.** Third part. + + * **Prison Cleanup: prison-core: Removed obsolete and unneeded comments and fix indentation where needed.** Second part. diff --git a/prison-core/src/main/java/tech/mcprison/prison/commands/Arg.java b/prison-core/src/main/java/tech/mcprison/prison/commands/Arg.java index f88b91747..1c6e7950a 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/commands/Arg.java +++ b/prison-core/src/main/java/tech/mcprison/prison/commands/Arg.java @@ -23,7 +23,9 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.PARAMETER) public @interface Arg { +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.PARAMETER) +public @interface Arg { /** * The default argument to process if the argument is not defined by the user. To make it a diff --git a/prison-core/src/main/java/tech/mcprison/prison/commands/ArgumentHandler.java b/prison-core/src/main/java/tech/mcprison/prison/commands/ArgumentHandler.java index b663ebad3..0e23e3c0e 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/commands/ArgumentHandler.java +++ b/prison-core/src/main/java/tech/mcprison/prison/commands/ArgumentHandler.java @@ -153,7 +153,8 @@ public final void setMessage(String node, String def) { messageNodes.put(node, def); } - @Override public String toString() { + @Override + public String toString() { StringBuilder sb = new StringBuilder(); sb.append("ArgumentHandler -> " + getClass().getName() + "\n"); sb.append("Set messages: \n"); diff --git a/prison-core/src/main/java/tech/mcprison/prison/commands/BaseCommands.java b/prison-core/src/main/java/tech/mcprison/prison/commands/BaseCommands.java index 4f88645a1..bfde19e4d 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/commands/BaseCommands.java +++ b/prison-core/src/main/java/tech/mcprison/prison/commands/BaseCommands.java @@ -23,11 +23,6 @@ public void setCmdGroup( String cmdGroup ) { } -// public Player getPlayer( CommandSender sender ) { -// Optional player = Prison.get().getPlatform().getPlayer( sender.getName() ); -// return player.isPresent() ? player.get() : null; -// } - /** *

    Gets a player by name. If the player is not online, then try to get them from * the offline player list. If not one is found, then return a null. @@ -49,9 +44,6 @@ public Player getPlayerByName( // CommandSender sender, return getPlayerByName( // sender, playerName, null ); } -// public Player getPlayer( CommandSender sender ) { -// return getPlayer( sender, null, null ); -// } /** *

    This function should only return a Player based upon either the player's name @@ -76,57 +68,8 @@ public Player getPlayerByName( // CommandSender sender, String playerName, UUID uuid ) { Player result = null; -// boolean console = sender == null ? true : "CONSOLE".equalsIgnoreCase( sender.getName() ); -// -// if ( !console ) { -// playerName = sender.getName(); -// } - result = Prison.get().getPlatform().getRankPlayer( uuid, playerName ); - -// if ( playerName != null ) { -// Optional opt = Prison.get().getPlatform().getPlayer( playerName ); -// -// result = opt.orElse( null ); -// -//// if ( !opt.isPresent() ) { -//// opt = Prison.get().getPlatform().getOfflinePlayer( playerName ); -//// } -//// if ( opt.isPresent() ) { -//// result = opt.get(); -//// } -// } -// if ( result == null && uuid != null ) { -// -//// result = Prison.get().getPlatform().getRankPlayer( uuid, playerName ); -// -//// Optional opt = Prison.get().getPlatform().getOfflinePlayer( uuid ); -//// if ( opt.isPresent() ) { -//// result = opt.get(); -//// } -// } - - -// playerName = playerName != null && !playerName.trim().isEmpty() ? -// playerName : sender != null ? sender.getName() : null; -// -// //Output.get().logInfo("RanksCommands.getPlayer :: playerName = " + playerName ); -// -// // Do not try to get the player name if -// if ( playerName != null ) { -// Optional opt = Prison.get().getPlatform().getPlayer( playerName ); -// if ( !opt.isPresent() ) { -// opt = Prison.get().getPlatform().getOfflinePlayer( playerName ); -// } -// if ( !opt.isPresent() ) { -// opt = Prison.get().getPlatform().getOfflinePlayer( uuid ); -// } -// if ( opt.isPresent() ) { -// result = opt.get(); -// } -// -// } return result; } @@ -136,8 +79,6 @@ public Player getOnlinePlayer( CommandSender sender, String playerName ) { playerName = playerName != null && !playerName.trim().isEmpty() ? playerName : sender != null ? sender.getName() : null; - //Output.get().logInfo("RanksCommands.getPlayer :: playerName = " + playerName ); - if ( playerName != null ) { Optional opt = Prison.get().getPlatform().getPlayer( playerName ); @@ -149,30 +90,4 @@ public Player getOnlinePlayer( CommandSender sender, String playerName ) { return result; } - -// public double getPlayerBalance( Player player ) { -// -// EconomyIntegration economy = PrisonAPI.getIntegrationManager().getEconomy(); -// -// return economy.getBalance( player ); -// } -// -// public double getPlayerBalance( Player player, String currency ) { -// -// -// EconomyCurrencyIntegration currencyEcon = PrisonAPI.getIntegrationManager() -// .getEconomyForCurrency( currency ); -// if ( currencyEcon == null ) { -// // ERROR: currency is not supported -// Output.get().logInfo( "The currency %s is not supported. Therefore there is no blance.", -// currency ); -// return 0; -// } -// else { -// return currencyEcon.getBalance( player, currency ); -// } -// -// } - - } diff --git a/prison-core/src/main/java/tech/mcprison/prison/commands/CommandArgument.java b/prison-core/src/main/java/tech/mcprison/prison/commands/CommandArgument.java index 27bafd4dc..bf5db9652 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/commands/CommandArgument.java +++ b/prison-core/src/main/java/tech/mcprison/prison/commands/CommandArgument.java @@ -52,7 +52,8 @@ public CommandArgument(String name, String description, String def, String verif this.argumentClass = argumentClass; } - @Override public Object execute(CommandSender sender, Arguments args) throws CommandError { + @Override + public Object execute(CommandSender sender, Arguments args) throws CommandError { String arg; if (!args.hasNext()) { if (def.equals(" ")) { diff --git a/prison-core/src/main/java/tech/mcprison/prison/commands/CommandHandler.java b/prison-core/src/main/java/tech/mcprison/prison/commands/CommandHandler.java index 511349648..35ca3bcc1 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/commands/CommandHandler.java +++ b/prison-core/src/main/java/tech/mcprison/prison/commands/CommandHandler.java @@ -55,8 +55,6 @@ public class CommandHandler { private String rootCommmand; private String commandFallback; -// public static final String COMMAND_PRIMARY_ROOT_COMMAND = "prison"; -// public static final String COMMAND_FALLBACK_PREFIX = "prison"; public static final String COMMAND_HELP_TEXT = "help"; @@ -71,12 +69,8 @@ public class CommandHandler { private Map rootCommands = new HashMap<>(); -// private List commands = new ArrayList<>(); - - private TabCompleaterData tabCompleaterData; -// private String helpSuffix = "help"; public CommandHandler() { this.plugin = Prison.get(); @@ -106,13 +100,9 @@ public CommandHandler() { Output.get().logInfo( "&3Root command: &7/%s &3fallback-prefix: &7%s", rootCommmand, commandFallback ); -// Output.get().logInfo( "&3Root command: &7/%s &3fallback-prefix: &7%s", -// DefaultSettings.COMMAND_PRIMARY_ROOT_COMMAND, DefaultSettings.COMMAND_FALLBACK_PREFIX ); } - - public String getRootCommmand() { return rootCommmand; } @@ -122,8 +112,6 @@ public String getCommandFallback() { } - - private PermissionHandler permissionHandler = (sender, permissions) -> { for (String perm : permissions) { if (!sender.hasPermission(perm)) { @@ -134,6 +122,7 @@ public String getCommandFallback() { }; private HelpHandler helpHandler = new HelpHandler() { + private String formatArgument(CommandArgument argument) { String def = argument.getDefault(); if (def.equals(" ")) { @@ -157,30 +146,30 @@ private String formatArgument(CommandArgument argument) { @Override public ChatDisplay getHelpMessage(CommandSender sender, RegisteredCommand command) { - if ( !hasCommandAccess(sender, command, command.getLabel(), new String[0] ) ) { - return null; - } - + if ( !hasCommandAccess(sender, command, command.getLabel(), new String[0] ) ) { + return null; + } + ChatDisplay chatDisplay = new ChatDisplay( String.format( "Cmd: &7%s", getUsageNoParameters(command)) ); if (command.isSet() && command.getDescription() != null && !command.getDescription().isEmpty()) { - chatDisplay.addText(ChatColor.DARK_AQUA + command.getDescription()); + chatDisplay.addText(ChatColor.DARK_AQUA + command.getDescription()); } chatDisplay.addText(getUsage(command)); if (command.isSet()) { for (CommandArgument argument : command.getArguments()) { - chatDisplay.addText(formatArgument(argument)); + chatDisplay.addText(formatArgument(argument)); } if (command.getWildcard() != null) { - chatDisplay.addText(formatArgument(command.getWildcard())); + chatDisplay.addText(formatArgument(command.getWildcard())); } List flags = command.getFlags(); if (flags.size() > 0) { - chatDisplay.addText(ChatColor.DARK_AQUA + "Flags:"); + chatDisplay.addText(ChatColor.DARK_AQUA + "Flags:"); for (Flag flag : flags) { StringBuilder args = new StringBuilder(); for (FlagArgument argument : flag.getArguments()) { @@ -188,88 +177,79 @@ public ChatDisplay getHelpMessage(CommandSender sender, RegisteredCommand comman } chatDisplay.addText("-" + flag.getIdentifier() + ChatColor.AQUA + args.toString()); for (FlagArgument argument : flag.getArguments()) { - chatDisplay.addText(formatArgument(argument)); + chatDisplay.addText(formatArgument(argument)); } } } if ( command.getPermissions() != null && command.getPermissions().length > 0 || command.getAltPermissions() != null && command.getAltPermissions().length > 0 ) { - StringBuilder sb = new StringBuilder(); - - if ( command.getPermissions() != null && command.getPermissions().length > 0 ) { - for ( String perm : command.getPermissions() ) { - if ( sb.length() > 0 ) { - sb.append( " " ); - } - sb.append( perm ); - } - } - if ( command.getAltPermissions() != null && command.getAltPermissions().length > 0 ) { - for ( String altPerm : command.getAltPermissions() ) { - if ( sb.length() > 0 ) { - sb.append( " " ); - } - sb.append( altPerm ); - } - } - - if ( sb.length() > 0 ) { - chatDisplay.addText(ChatColor.DARK_AQUA + "Permissions:"); - - sb.insert( 0, ChatColor.AQUA ); - sb.insert( 0, " " ); - chatDisplay.addText( sb.toString() ); - } + StringBuilder sb = new StringBuilder(); + + if ( command.getPermissions() != null && command.getPermissions().length > 0 ) { + for ( String perm : command.getPermissions() ) { + if ( sb.length() > 0 ) { + sb.append( " " ); + } + sb.append( perm ); + } + } + if ( command.getAltPermissions() != null && command.getAltPermissions().length > 0 ) { + for ( String altPerm : command.getAltPermissions() ) { + if ( sb.length() > 0 ) { + sb.append( " " ); + } + sb.append( altPerm ); + } + } + + if ( sb.length() > 0 ) { + chatDisplay.addText(ChatColor.DARK_AQUA + "Permissions:"); + + sb.insert( 0, ChatColor.AQUA ); + sb.insert( 0, " " ); + chatDisplay.addText( sb.toString() ); + } } if ( command.getAliases() != null && command.getAliases().length > 0 ) { - StringBuilder sb = new StringBuilder(); - - if ( command.getAliases() != null && command.getAliases().length > 0 ) { - for ( String perm : command.getAliases() ) { - if ( sb.length() > 0 ) { - sb.append( " " ); - } - sb.append( ChatColor.DARK_BLUE ).append( "[" ) - .append( ChatColor.AQUA ).append( perm ) - .append( ChatColor.DARK_BLUE ).append( "]" ); - } - } - - if ( sb.length() > 0 ) { - chatDisplay.addText(ChatColor.DARK_AQUA + "Aliases:"); - - sb.insert( 0, " " ); - chatDisplay.addText( sb.toString() ); - } + StringBuilder sb = new StringBuilder(); + + if ( command.getAliases() != null && command.getAliases().length > 0 ) { + for ( String perm : command.getAliases() ) { + if ( sb.length() > 0 ) { + sb.append( " " ); + } + sb.append( ChatColor.DARK_BLUE ).append( "[" ) + .append( ChatColor.AQUA ).append( perm ) + .append( ChatColor.DARK_BLUE ).append( "]" ); + } + } + + if ( sb.length() > 0 ) { + chatDisplay.addText(ChatColor.DARK_AQUA + "Aliases:"); + + sb.insert( 0, " " ); + chatDisplay.addText( sb.toString() ); + } } if ( command.getDocURLs() != null && command.getDocURLs().length > 0 ) { - chatDisplay.addText(ChatColor.DARK_AQUA + "Documentation:"); - - for ( String docURL : command.getDocURLs() ) { - RowComponent row = new RowComponent(); - - row.addTextComponent( " " ); - FancyMessage fMessage = new FancyMessage( docURL ).link( docURL ) - .tooltip( "Click to open link" ); - row.addFancy( fMessage ); - - chatDisplay.addComponent( row ); - - - -// StringBuilder sb = new StringBuilder(); -// -// sb.append( " " ).append( ChatColor.DARK_BLUE ).append( "[" ) -// .append( ChatColor.AQUA ).append( docURL ) -// .append( ChatColor.DARK_BLUE ).append( "]" ); -// -// chatDisplay.addText( sb.toString() ); - } + chatDisplay.addText(ChatColor.DARK_AQUA + "Documentation:"); + + for ( String docURL : command.getDocURLs() ) { + RowComponent row = new RowComponent(); + + row.addTextComponent( " " ); + FancyMessage fMessage = new FancyMessage( docURL ).link( docURL ) + .tooltip( "Click to open link" ); + row.addFancy( fMessage ); + + chatDisplay.addComponent( row ); + + } } } @@ -281,73 +261,65 @@ public ChatDisplay getHelpMessage(CommandSender sender, RegisteredCommand comman TreeSet subCommandSet = new TreeSet<>(); for (RegisteredCommand scommand : subcommands) { - String sLabel = scommand.getCompleteLabel(); - - if ( hasCommandAccess(sender, scommand, sLabel, new String[0] ) ) { - - String subCmd = scommand.getUsage(); - - int subCmdSubCnt = scommand.getSuffixes().size(); - String subCommands = (subCmdSubCnt == 0 ? "" : - ChatColor.DARK_AQUA + "(" + subCmdSubCnt + " Subcommands)"); - - String isAlias = scommand.isAlias() ? ChatColor.DARK_AQUA + " Alias" : ""; - - subCommandSet.add( - String.format( "%s %s %s", subCmd, subCommands, isAlias )); - } + String sLabel = scommand.getCompleteLabel(); + + if ( hasCommandAccess(sender, scommand, sLabel, new String[0] ) ) { + + String subCmd = scommand.getUsage(); + + int subCmdSubCnt = scommand.getSuffixes().size(); + String subCommands = (subCmdSubCnt == 0 ? "" : + ChatColor.DARK_AQUA + "(" + subCmdSubCnt + " Subcommands)"); + + String isAlias = scommand.isAlias() ? ChatColor.DARK_AQUA + " Alias" : ""; + + subCommandSet.add( + String.format( "%s %s %s", subCmd, subCommands, isAlias )); + } } // Only if there are entries to show, then include the header and the details if ( subCommandSet.size() > 0 ) { - chatDisplay.addText(ChatColor.DARK_AQUA + "Subcommands:"); - - for (String subCmd : subCommandSet) { - chatDisplay.addText(subCmd); - } + chatDisplay.addText(ChatColor.DARK_AQUA + "Subcommands:"); + + for (String subCmd : subCommandSet) { + chatDisplay.addText(subCmd); + } } } if ( command.getLabel().equalsIgnoreCase( getRootCommmand() ) && rootCommands.size() > 1 ) { -// if ( command.getLabel().equalsIgnoreCase( DefaultSettings.COMMAND_PRIMARY_ROOT_COMMAND ) && -// rootCommands.size() > 1 ) { - ArrayList rootCommandsMessages = buildHelpRootCommands(); - if ( rootCommandsMessages.size() > 1 ) { - for ( String rootCmd : rootCommandsMessages ) - { - chatDisplay.addText( rootCmd ); + ArrayList rootCommandsMessages = buildHelpRootCommands(); + if ( rootCommandsMessages.size() > 1 ) { + for ( String rootCmd : rootCommandsMessages ) { + chatDisplay.addText( rootCmd ); } - - } - - ArrayList aliasesMessages = buildHelpAliases(); - if ( aliasesMessages.size() > 1 ) { - for ( String alias : aliasesMessages ) - { - chatDisplay.addText( alias ); + + } + + ArrayList aliasesMessages = buildHelpAliases(); + if ( aliasesMessages.size() > 1 ) { + for ( String alias : aliasesMessages ) { + chatDisplay.addText( alias ); } - - } - - ArrayList excludedWorlds = buildExcludedWorlds(); - if ( excludedWorlds.size() > 1 ) { - for ( String excludedWorld : excludedWorlds ) - { - chatDisplay.addText( excludedWorld ); - } - - } - - + + } + + ArrayList excludedWorlds = buildExcludedWorlds(); + if ( excludedWorlds.size() > 1 ) { + for ( String excludedWorld : excludedWorlds ) { + chatDisplay.addText( excludedWorld ); + } + + } } return chatDisplay; -// return message.toArray(new String[0]); } private ArrayList buildExcludedWorlds() { @@ -393,42 +365,27 @@ private ArrayList buildHelpRootCommands() { // Force a sorting by use of a TreeSet. Collections.sort() would not work. TreeSet rootCommandSet = new TreeSet<>(); - // Try adding in all other root commands: + // Try adding in all other root commands: Set rootKeys = getRootCommands().keySet(); - for ( PluginCommand rootKey : rootKeys ) { - StringBuilder sbAliases = new StringBuilder(); - - // Do not list aliases: - if ( !(rootKey.getRegisteredCommand().isAlias() && rootKey.getRegisteredCommand().getParentOfAlias() != null) ) { -// String isAlias = rootKey.getRegisteredCommand().isAlias() ? ChatColor.DARK_AQUA + " Alias" : ""; - -// if ( rootKey.getRegisteredCommand().getRegisteredAliases().size() > 0 ) { -// for ( RegisteredCommand alias : rootKey.getRegisteredCommand().getRegisteredAliases() ) { -// -// sbAliases.append( ChatColor.DARK_BLUE ).append( "[" ).append( ChatColor.AQUA ).append( "/" ) -// .append( getRootCommandRegisteredLabel(alias) ) -// .append( ChatColor.DARK_BLUE ).append( "] " ); -// } -// sbAliases.insert( 0, -// new StringBuilder().append( ChatColor.DARK_AQUA ). -// append( "Aliases: " ).append( ChatColor.AQUA )); -// } - String rootCmd = - String.format( "%s %s", - rootKey.getUsage(), sbAliases.toString() ); + for ( PluginCommand rootKey : rootKeys ) { + StringBuilder sbAliases = new StringBuilder(); - rootCommandSet.add( rootCmd ); - } - - - } + // Do not list aliases: + if ( !(rootKey.getRegisteredCommand().isAlias() && rootKey.getRegisteredCommand().getParentOfAlias() != null) ) { + String rootCmd = + String.format( "%s %s", + rootKey.getUsage(), sbAliases.toString() ); + + rootCommandSet.add( rootCmd ); + } + } - for (String rootCmd : rootCommandSet) { - message.add(rootCmd); - } - - return message; + for (String rootCmd : rootCommandSet) { + message.add(rootCmd); + } + + return message; } /** @@ -447,20 +404,9 @@ private ArrayList buildHelpAliases() { for ( RegisteredCommand regCmd : getAllRegisteredCommands() ) { buildHelpAliasMessage( regCmd, aliasesSet ); -// plugin.logDebug( "### CommandHandler.buildHelpAliases ### test: %s ", regCmd.toString() ); } -// // Try adding in all other root commands: -// Set rootKeys = getRootCommands().keySet(); -// for ( PluginCommand rootKey : rootKeys ) { -// -// plugin.logDebug( "### CommandHandler.buildHelpAliases ### rootCommands: %s ", rootKey.toString() ); -// RegisteredCommand registeredCommand = rootKey.getRegisteredCommand(); -// -// buildHelpAliases( registeredCommand, aliasesSet ); -// } - // Sorted results, add to the List: for (String rootCmd : aliasesSet) { message.add(rootCmd); @@ -469,17 +415,6 @@ private ArrayList buildHelpAliases() { return message; } -// private void buildHelpAliases( RegisteredCommand registeredCommand, TreeSet aliasesSet ) { -// buildHelpAliasMessage( registeredCommand, aliasesSet ); -// -// plugin.logDebug( "### CommandHandler.buildHelpAliases ### : %s ", registeredCommand.toString() ); -// -// for ( RegisteredCommand suffixRegCmd : registeredCommand.getSuffixes() ) { -// -// buildHelpAliases( suffixRegCmd, aliasesSet ); -// } -// -// } private void buildHelpAliasMessage( RegisteredCommand registeredCommand, TreeSet aliasesSet ) { if ( registeredCommand.isAlias() && registeredCommand.getParentOfAlias() != null) { @@ -511,14 +446,14 @@ private void buildHelpAliasMessage( RegisteredCommand registeredCommand, TreeSet * @return */ private String getRootCommandRegisteredLabel(RegisteredCommand command ) { - String commandLabel = command.getLabel(); - if ( command instanceof RootCommand ) { - RootCommand rootCommand = (RootCommand) command; - if ( rootCommand.getBukkitCommand().getLabelRegistered() != null ) { - commandLabel = rootCommand.getBukkitCommand().getLabelRegistered(); - } - } - return commandLabel; + String commandLabel = command.getLabel(); + if ( command instanceof RootCommand ) { + RootCommand rootCommand = (RootCommand) command; + if ( rootCommand.getBukkitCommand().getLabelRegistered() != null ) { + commandLabel = rootCommand.getBukkitCommand().getLabelRegistered(); + } + } + return commandLabel; } @Override @@ -618,46 +553,43 @@ public void registerArgumentHandler(Class clazz, } public Object getRegisteredCommandClass( @SuppressWarnings( "rawtypes" ) Class commandClass ) { - Object results = null; - - String key = commandClass.getSimpleName(); - if ( key != null && getRegisteredCommands().containsKey( key ) ) { - results = getRegisteredCommands().get( key ); - } - - return results; + Object results = null; + + String key = commandClass.getSimpleName(); + if ( key != null && getRegisteredCommands().containsKey( key ) ) { + results = getRegisteredCommands().get( key ); + } + + return results; } public void registerCommands(Object methodInstance) { - // Keep a reference to the registered command object so it can be - // accessed in the future if needed for other uses. - getRegisteredCommands().put( methodInstance.getClass().getSimpleName(), methodInstance ); - - for (Method method : methodInstance.getClass().getDeclaredMethods()) { - Command commandAnno = method.getAnnotation(Command.class); - if (commandAnno == null) { - continue; - } - - RegisteredCommand mainCommand = commandRegisterConfig( method, commandAnno, methodInstance ); - - - String[] aliases = addConfigAliases( commandAnno.identifier(), commandAnno.aliases() ); - - if ( aliases.length > 0 ) { -// if ( commandAnno.aliases() != null && commandAnno.aliases().length > 0 ) { - - - for ( String alias : aliases ) -// for ( String alias : commandAnno.aliases() ) - { - RegisteredCommand aliasCommand = commandRegisterConfig( method, commandAnno, methodInstance, alias ); - - // Add the alias to the primary RegisteredCommand to track it's own aliases: - mainCommand.getRegisteredAliases().add( aliasCommand ); - aliasCommand.setParentOfAlias( mainCommand ); - } + // Keep a reference to the registered command object so it can be + // accessed in the future if needed for other uses. + getRegisteredCommands().put( methodInstance.getClass().getSimpleName(), methodInstance ); + + for (Method method : methodInstance.getClass().getDeclaredMethods()) { + Command commandAnno = method.getAnnotation(Command.class); + if (commandAnno == null) { + continue; + } + + RegisteredCommand mainCommand = commandRegisterConfig( method, commandAnno, methodInstance ); + + + String[] aliases = addConfigAliases( commandAnno.identifier(), commandAnno.aliases() ); + + if ( aliases.length > 0 ) { + + + for ( String alias : aliases ) { + RegisteredCommand aliasCommand = commandRegisterConfig( method, commandAnno, methodInstance, alias ); + + // Add the alias to the primary RegisteredCommand to track it's own aliases: + mainCommand.getRegisteredAliases().add( aliasCommand ); + aliasCommand.setParentOfAlias( mainCommand ); + } } @@ -665,7 +597,7 @@ public void registerCommands(Object methodInstance) { } private RegisteredCommand commandRegisterConfig( Method method, Command commandAnno, Object methodInstance ) { - return commandRegisterConfig( method, commandAnno, methodInstance, null ); + return commandRegisterConfig( method, commandAnno, methodInstance, null ); } private RegisteredCommand commandRegisterConfig( Method method, Command commandAnno, @@ -686,30 +618,25 @@ private RegisteredCommand commandRegisterConfig( Method method, Command commandA if ( rootPluginCommand == null ) { - String[] aliases = addConfigAliases( commandAnno.identifier(), commandAnno.aliases() ); - rootPluginCommand = new PluginCommand(label, - commandAnno.description(), - "/" + label, - aliases ); -// rootPluginCommand = new PluginCommand(label, -// commandAnno.description(), -// "/" + label, -// commandAnno.aliases() ); - plugin.getPlatform().registerCommand(rootPluginCommand); + String[] aliases = addConfigAliases( commandAnno.identifier(), commandAnno.aliases() ); + rootPluginCommand = new PluginCommand(label, + commandAnno.description(), + "/" + label, + aliases ); + plugin.getPlatform().registerCommand(rootPluginCommand); } // If getRootCommands() does not contain the rootPCommand then add it: if ( !getRootCommands().containsKey( rootPluginCommand ) ) { - RootCommand rootRegisteredCommand = new RootCommand( rootPluginCommand, this ); - rootRegisteredCommand.setAlias( alias != null ); - - // Must add all new RegisteredCommand objects to both getAllRegisteredCommands() and - // getTabCompleterData(). - getAllRegisteredCommands().add( rootRegisteredCommand ); - getTabCompleaterData().add( rootRegisteredCommand ); - - getRootCommands().put( rootPluginCommand, rootRegisteredCommand ); + RootCommand rootRegisteredCommand = new RootCommand( rootPluginCommand, this ); + rootRegisteredCommand.setAlias( alias != null ); + + // Must add all new RegisteredCommand objects to both getAllRegisteredCommands() and + getAllRegisteredCommands().add( rootRegisteredCommand ); + getTabCompleaterData().add( rootRegisteredCommand ); + + getRootCommands().put( rootPluginCommand, rootRegisteredCommand ); } RegisteredCommand mainCommand = getRootCommands().get( rootPluginCommand ); @@ -739,11 +666,11 @@ private RegisteredCommand commandRegisterConfig( Method method, Command commandA rootPluginCommand.setRegisteredCommand( mainCommand ); - // Validate that the first parameter, if it exists, is actually a CommandSender: - if ( method.getParameterCount() > 0 ) { - - // The first parameter "should" always be CommandSender or there will be difficult - // to trace failures at runtime: + // Validate that the first parameter, if it exists, is actually a CommandSender: + if ( method.getParameterCount() > 0 ) { + + // The first parameter "should" always be CommandSender or there will be difficult + // to trace failures at runtime: Class cmdSender = method.getParameterTypes()[0]; if ( !cmdSender.getSimpleName().equalsIgnoreCase( "CommandSender") ) { @@ -757,59 +684,59 @@ private RegisteredCommand commandRegisterConfig( Method method, Command commandA cmdSender.getSimpleName() )); } - - } - - mainCommand.set(methodInstance, method); + + } + + mainCommand.set(methodInstance, method); return mainCommand; } public static String remapRootCmdIdentifiers(String identifier) { - if ( identifier != null ) { - - int idx = identifier.indexOf( " " ); - String root = idx == -1 ? identifier : identifier.substring( 0, idx ); - - String key = "prisonCommandHandler.command-roots." + root; - - String newRoot = Prison.get().getPlatform().getConfigString( key ); - - if ( newRoot != null && !root.equals(newRoot) ) { - - identifier = newRoot + - (idx == -1 ? "" : identifier.substring(idx)); - } - } + if ( identifier != null ) { + + int idx = identifier.indexOf( " " ); + String root = idx == -1 ? identifier : identifier.substring( 0, idx ); + + String key = "prisonCommandHandler.command-roots." + root; + + String newRoot = Prison.get().getPlatform().getConfigString( key ); + + if ( newRoot != null && !root.equals(newRoot) ) { + + identifier = newRoot + + (idx == -1 ? "" : identifier.substring(idx)); + } + } return identifier; } public static String[] addConfigAliases( String label, String[] aliases ) { - String[] results = aliases; - - String configKey = "prisonCommandHandler.aliases." + label.replace( " ", "." ); - - List ca = Prison.get().getPlatform().getConfigStringArray( configKey ); - if ( ca != null && ca.size() > 0 && ca.get( 0 ) instanceof String ) { - - List configAliases = new ArrayList<>(); - - for ( String alias : aliases ) { - configAliases.add( alias ); - } - - for ( Object aliasObj : ca ) { - if ( aliasObj instanceof String ) { - configAliases.add( aliasObj.toString() ); + String[] results = aliases; + + String configKey = "prisonCommandHandler.aliases." + label.replace( " ", "." ); + + List ca = Prison.get().getPlatform().getConfigStringArray( configKey ); + if ( ca != null && ca.size() > 0 && ca.get( 0 ) instanceof String ) { + + List configAliases = new ArrayList<>(); + + for ( String alias : aliases ) { + configAliases.add( alias ); } - } - - results = configAliases.toArray( new String[0] ); - - } + + for ( Object aliasObj : ca ) { + if ( aliasObj instanceof String ) { + configAliases.add( aliasObj.toString() ); + } + } + + results = configAliases.toArray( new String[0] ); + + } return results; } @@ -825,73 +752,72 @@ public static String[] addConfigAliases( String label, String[] aliases ) public boolean hasCommandAccess( CommandSender sender, RegisteredCommand rootCommand, String label, String[] args ) { - CommandAccessResults results = new CommandAccessResults( sender ); - - hasCommandAccess( sender, rootCommand, label, args, results ); - - if ( results.isAccess() ) { - results.setAccessPermitted(); - } + CommandAccessResults results = new CommandAccessResults( sender ); + + hasCommandAccess( sender, rootCommand, label, args, results ); + + if ( results.isAccess() ) { + results.setAccessPermitted(); + } + + if ( !results.isAccess() ) { + // Debug logging if prison is in debug mode: + results.debugAccess(); + } - if ( !results.isAccess() ) { - // Debug logging if prison is in debug mode: - results.debugAccess(); - } - - return results.isAccess(); + return results.isAccess(); } private void hasCommandAccess( CommandSender sender, RegisteredCommand rootCommand, String label, String[] args, CommandAccessResults results ) { -// boolean results = true; - if ( !sender.isOp() ) { - - boolean hasAccess = rootCommand.testPermission(sender); - - if ( !hasAccess ) { - results.setAccess( false ); - } - else { - - String exRAKey = "prisonCommandHandler.exclude-non-ops.exclude-related-aliases"; - boolean excludeRelatedAliases = getConfigBoolean( exRAKey ); - - String sLabelAlias = !excludeRelatedAliases || rootCommand.getParentOfAlias() == null ? - null : rootCommand.getParentOfAlias().getCompleteLabel(); - - - commandAccessPermChecks( sender, rootCommand, label, results ); - - if ( results.isAccess() && sLabelAlias != null ) { - - commandAccessPermChecks( sender, rootCommand.getParentOfAlias(), sLabelAlias, results ); - } - } - - - } + if ( !sender.isOp() ) { + + boolean hasAccess = rootCommand.testPermission(sender); + + if ( !hasAccess ) { + results.setAccess( false ); + } + else { + + String exRAKey = "prisonCommandHandler.exclude-non-ops.exclude-related-aliases"; + boolean excludeRelatedAliases = getConfigBoolean( exRAKey ); + + String sLabelAlias = !excludeRelatedAliases || rootCommand.getParentOfAlias() == null ? + null : rootCommand.getParentOfAlias().getCompleteLabel(); + + + commandAccessPermChecks( sender, rootCommand, label, results ); + + if ( results.isAccess() && sLabelAlias != null ) { + + commandAccessPermChecks( sender, rootCommand.getParentOfAlias(), sLabelAlias, results ); + } + } + + + } - // If we get to this point, and the result is true (the player has access the - // specified command so far), and there are more args, we need to next - // take the args[0] and append it to the label, and then test it again. - // This needs to continue until the generated command is rejected, or - // it passes it's clean and the player has full access to the command(s). - if ( results.isAccess() && args.length > 0 ) { - String newSuffix = args[0]; - String newLabel = label + " " + newSuffix; - String[] newArgs = Arrays.copyOfRange( args, 1, args.length ); - - RegisteredCommand newSuffixCommand = rootCommand.getSuffixCommand( newSuffix ); - - if ( newSuffixCommand != null ) { - - hasCommandAccess( sender, newSuffixCommand, - newLabel, newArgs, results ); - } - } + // If we get to this point, and the result is true (the player has access the + // specified command so far), and there are more args, we need to next + // take the args[0] and append it to the label, and then test it again. + // This needs to continue until the generated command is rejected, or + // it passes it's clean and the player has full access to the command(s). + if ( results.isAccess() && args.length > 0 ) { + String newSuffix = args[0]; + String newLabel = label + " " + newSuffix; + String[] newArgs = Arrays.copyOfRange( args, 1, args.length ); + + RegisteredCommand newSuffixCommand = rootCommand.getSuffixCommand( newSuffix ); + + if ( newSuffixCommand != null ) { + + hasCommandAccess( sender, newSuffixCommand, + newLabel, newArgs, results ); + } + } } @@ -953,10 +879,10 @@ private void commandAccessPermChecks(CommandSender sender, RegisteredCommand roo } private boolean getConfigBoolean( String configKey ) { - return Prison.get().getPlatform().getConfigBooleanFalse( configKey ); + return Prison.get().getPlatform().getConfigBooleanFalse( configKey ); } private List getConfigStringArray( String configKey ) { - return Prison.get().getPlatform().getConfigStringArray( configKey ); + return Prison.get().getPlatform().getConfigStringArray( configKey ); } public boolean onCommand(CommandSender sender, PluginCommand command, String label, @@ -964,8 +890,8 @@ public boolean onCommand(CommandSender sender, PluginCommand command, String lab RootCommand rootCommand = rootCommands.get(command); if (rootCommand == null) { - Output.get().logError( "CommandHandler.onCommand(): " + command.getLabel() + - " : No root command found. " ); + Output.get().logError( "CommandHandler.onCommand(): " + command.getLabel() + + " : No root command found. " ); return false; } @@ -975,44 +901,44 @@ public boolean onCommand(CommandSender sender, PluginCommand command, String lab boolean debug = Output.get().isActiveTarget( DebugTarget.commandHandler ); if ( debug ) { - String argz = ""; - for (String arg : args) { - argz += arg + " "; - } - - String msg = String.format( - "CommandHandler.onCommand: Sender %s. Command is marked with 'onlyPlayers'. " - + "Cannot run. : [%s]", - sender.getName(), - (label + " " + argz).trim() - ); - Output.get().logInfo( msg ); - } + String argz = ""; + for (String arg : args) { + argz += arg + " "; + } + + String msg = String.format( + "CommandHandler.onCommand: Sender %s. Command is marked with 'onlyPlayers'. " + + "Cannot run. : [%s]", + sender.getName(), + (label + " " + argz).trim() + ); + Output.get().logInfo( msg ); + } return true; } else if ( !hasCommandAccess( sender, rootCommand, label, args ) ) { - // The player does not have access to this command. - // Who cares! Just exit and do nothing. Never log this. - return true; + // The player does not have access to this command. + // Who cares! Just exit and do nothing. Never log this. + return true; } else { - try { - rootCommand.execute( sender, args ); - } - catch ( Exception e ) { - String message = "Prison CommandHander: onCommand: " + e.getMessage() + - " [" + e.getCause() == null ? "cause not reported" : e.getCause() + "]"; - - Output.get().logError( message ); - for ( StackTraceElement ste : e.getStackTrace() ) { - Output.get().logError( ste.toString() ); - } - - } + try { + rootCommand.execute( sender, args ); + } + catch ( Exception e ) { + String message = "Prison CommandHander: onCommand: " + e.getMessage() + + " [" + e.getCause() == null ? "cause not reported" : e.getCause() + "]"; + + Output.get().logError( message ); + for ( StackTraceElement ste : e.getStackTrace() ) { + Output.get().logError( ste.toString() ); + } + + } } @@ -1063,9 +989,6 @@ public void setRootCommands( Map rootCommands ) { this.rootCommands = rootCommands; } -// private List getCommands() { -// return commands; -// } public TabCompleaterData getTabCompleaterData() { return tabCompleaterData; @@ -1110,27 +1033,27 @@ public List getRootCommandKeys() { */ public String findRegisteredCommand(String command) { - String[] patternParts = command.split( " " ); - - if ( patternParts.length > 0 ) { - String rootPattern = patternParts[0]; - - for ( RegisteredCommand cmd : allRegisteredCommands ) { - - if ( cmd.getLabel().equalsIgnoreCase( rootPattern ) ) { - - if ( cmd.isRoot() ) { - - RootCommand rootCommand = (RootCommand) cmd; - if ( rootCommand.getBukkitCommand().getLabelRegistered() != null ) { - - patternParts[0] = rootCommand.getBukkitCommand().getLabelRegistered(); - } - } - } - } - } - - return String.join( " ", patternParts ); + String[] patternParts = command.split( " " ); + + if ( patternParts.length > 0 ) { + String rootPattern = patternParts[0]; + + for ( RegisteredCommand cmd : allRegisteredCommands ) { + + if ( cmd.getLabel().equalsIgnoreCase( rootPattern ) ) { + + if ( cmd.isRoot() ) { + + RootCommand rootCommand = (RootCommand) cmd; + if ( rootCommand.getBukkitCommand().getLabelRegistered() != null ) { + + patternParts[0] = rootCommand.getBukkitCommand().getLabelRegistered(); + } + } + } + } + } + + return String.join( " ", patternParts ); } } diff --git a/prison-core/src/main/java/tech/mcprison/prison/commands/CommandPagedData.java b/prison-core/src/main/java/tech/mcprison/prison/commands/CommandPagedData.java index f81a536e6..86ba170c4 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/commands/CommandPagedData.java +++ b/prison-core/src/main/java/tech/mcprison/prison/commands/CommandPagedData.java @@ -93,11 +93,11 @@ public void generatePagedCommandFooter( ChatDisplay display, String message ) { RowComponent row = new RowComponent(); if ( getCurPage() > 1 ) { - row.addFancy( - new ButtonComponent( "&e<-- Prev Page", '-', Style.NEGATIVE) - .runCommand(pageCommand + " " + (getCurPage() - 1) + - (getPageCommandSuffix() == null ? "" : " " + getPageCommandSuffix()), - "View the prior page of search results").getFancyMessage() ); + row.addFancy( + new ButtonComponent( "&e<-- Prev Page", '-', Style.NEGATIVE) + .runCommand(pageCommand + " " + (getCurPage() - 1) + + (getPageCommandSuffix() == null ? "" : " " + getPageCommandSuffix()), + "View the prior page of search results").getFancyMessage() ); } row.addFancy( new FancyMessage(" &9< &3Page " + curPage + " of " + @@ -187,7 +187,5 @@ public int getPageEnd() { public void setPageEnd( int pageEnd ) { this.pageEnd = pageEnd; } - - } diff --git a/prison-core/src/main/java/tech/mcprison/prison/commands/Flags.java b/prison-core/src/main/java/tech/mcprison/prison/commands/Flags.java index c95c78d2f..15541d0c9 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/commands/Flags.java +++ b/prison-core/src/main/java/tech/mcprison/prison/commands/Flags.java @@ -23,7 +23,9 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Flags { +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface Flags { /** * @return description of the flags (in the same order as the identifiers) diff --git a/prison-core/src/main/java/tech/mcprison/prison/commands/PluginCommand.java b/prison-core/src/main/java/tech/mcprison/prison/commands/PluginCommand.java index 69a7f7a50..fafd9c57e 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/commands/PluginCommand.java +++ b/prison-core/src/main/java/tech/mcprison/prison/commands/PluginCommand.java @@ -54,17 +54,17 @@ public PluginCommand(String label, String description, String usage, String[] al @Override public String toString() { - StringBuilder sb = new StringBuilder(); - - sb.append( getUsage() ) - .append( " alias: " ).append( getAliases().size() ) - .append( " hasRegCmd: " ).append( getRegisteredCommand() != null ); - - if ( getRegisteredCommand() != null ) { - sb.append( " (" ).append( getRegisteredCommand().getUsage() ).append( ")" ); - } - - return sb.toString(); + StringBuilder sb = new StringBuilder(); + + sb.append( getUsage() ) + .append( " alias: " ).append( getAliases().size() ) + .append( " hasRegCmd: " ).append( getRegisteredCommand() != null ); + + if ( getRegisteredCommand() != null ) { + sb.append( " (" ).append( getRegisteredCommand().getUsage() ).append( ")" ); + } + + return sb.toString(); } public String getLabel() { @@ -72,16 +72,15 @@ public String getLabel() { } public String getLabelRegistered() { - return labelRegistered; + return labelRegistered; } public void setLabelRegistered( String labelRegistered ) { - this.labelRegistered = labelRegistered; + this.labelRegistered = labelRegistered; } public String getDescription() { return description; } - public void setDescription(String description) { this.description = description; } @@ -89,7 +88,6 @@ public void setDescription(String description) { public String getUsage() { return getLabelRegistered() == null ? usage : "/" + getLabelRegistered(); } - public void setUsage(String usage) { this.usage = usage; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/commands/RegisteredCommand.java b/prison-core/src/main/java/tech/mcprison/prison/commands/RegisteredCommand.java index 7dfa712a7..af21e9ce4 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/commands/RegisteredCommand.java +++ b/prison-core/src/main/java/tech/mcprison/prison/commands/RegisteredCommand.java @@ -94,36 +94,36 @@ public RegisteredCommand(String label, CommandHandler handler, RegisteredCommand */ private RegisteredCommand( String jUnitUsage ) { - this.junitTest = jUnitUsage; - - this.label = "junitTest"; - this.handler = null; - this.parent = null; - - this.registeredAliases = new ArrayList<>(); + this.junitTest = jUnitUsage; + + this.label = "junitTest"; + this.handler = null; + this.parent = null; + + this.registeredAliases = new ArrayList<>(); } protected static RegisteredCommand junitTest( String jUnitUsage ) { - RegisteredCommand results = new RegisteredCommand( jUnitUsage ); - - return results; + RegisteredCommand results = new RegisteredCommand( jUnitUsage ); + + return results; } @Override public String toString() { - StringBuilder sb = new StringBuilder(); - - sb.append( getUsage() ) - .append( " isRoot: " ).append( isRoot() ) - .append( " isAlias: " ).append( isAlias() ) - .append( " suffixCnt: " ).append( getSuffixes().size() ) - .append( " hasAliasParent: " ).append( getParentOfAlias() != null ); - - if ( getParentOfAlias() != null ) { - sb.append( " (" ).append( getParentOfAlias().getUsage() ).append( ")" ); - } - - return sb.toString(); + StringBuilder sb = new StringBuilder(); + + sb.append( getUsage() ) + .append( " isRoot: " ).append( isRoot() ) + .append( " isAlias: " ).append( isAlias() ) + .append( " suffixCnt: " ).append( getSuffixes().size() ) + .append( " hasAliasParent: " ).append( getParentOfAlias() != null ); + + if ( getParentOfAlias() != null ) { + sb.append( " (" ).append( getParentOfAlias().getUsage() ).append( ")" ); + } + + return sb.toString(); } /** @@ -148,8 +148,8 @@ boolean doesSuffixCommandExist(String suffix) { } public String getCompleteLabel() { - return (parent == null ? "" : parent.getCompleteLabel() + " " ) + - (label == null ? "-noCommandLabelDefined-" : label) ; + return (parent == null ? "" : parent.getCompleteLabel() + " " ) + + (label == null ? "-noCommandLabelDefined-" : label) ; } /** @@ -163,46 +163,47 @@ public String getCompleteLabel() { * @param args */ protected void execute(CommandSender sender, String[] args) { - execute( sender, args, true ); + execute( sender, args, true ); } + protected void execute(CommandSender sender, String[] args, boolean allowDebug ) { - // Only enable debug mode if the selective debug target is commandHanlder. - // To enable this use ... - boolean debug = Output.get().isActiveTarget( DebugTarget.commandHandler ); - - // First ensure the player is not locked out of this command: - if ( !handler.hasCommandAccess(sender, this, getLabel(), args) ) { - - if ( debug ) { - String argz = ""; - for (String arg : args) { - argz += arg + " "; - } - - String msg = String.format( - "RegisteredCommand.execute: Player %s does not have access to a command: [%s]", - sender.getName(), - (getLabel() + " " + argz).trim() - ); - Output.get().logInfo( msg ); - } - return; - } - - if ( debug ) { - String argz = ""; - for (String arg : args) { - argz += arg + " "; - } - - String msg = String.format( - "RegisteredCommand.execute: Player %s is attempting to run command: [%s]", - sender.getName(), - (getLabel() + " " + argz).trim() - ); - Output.get().logInfo( msg ); - } + // Only enable debug mode if the selective debug target is commandHanlder. + // To enable this use ... + boolean debug = Output.get().isActiveTarget( DebugTarget.commandHandler ); + + // First ensure the player is not locked out of this command: + if ( !handler.hasCommandAccess(sender, this, getLabel(), args) ) { + + if ( debug ) { + String argz = ""; + for (String arg : args) { + argz += arg + " "; + } + + String msg = String.format( + "RegisteredCommand.execute: Player %s does not have access to a command: [%s]", + sender.getName(), + (getLabel() + " " + argz).trim() + ); + Output.get().logInfo( msg ); + } + return; + } + + if ( debug ) { + String argz = ""; + for (String arg : args) { + argz += arg + " "; + } + + String msg = String.format( + "RegisteredCommand.execute: Player %s is attempting to run command: [%s]", + sender.getName(), + (getLabel() + " " + argz).trim() + ); + Output.get().logInfo( msg ); + } if (!testPermission(sender)) { Prison.get().getLocaleManager().getLocalizable("noPermission") @@ -285,18 +286,17 @@ private void executeMethod(CommandSender sender, String[] args ) { try { try { - // The command is ran here with the invoke... - - // Record that the command has been "ran", which does not mean it was successful: - incrementUsageCount(); - - if ( isAlias() && getParentOfAlias() != null ) { -// getParentOfAlias().incrementUsageCount(); - getParentOfAlias().incrementUsageCountAlias(); - - } - nanosStart = System.nanoTime(); - + // The command is ran here with the invoke... + + // Record that the command has been "ran", which does not mean it was successful: + incrementUsageCount(); + + if ( isAlias() && getParentOfAlias() != null ) { + getParentOfAlias().incrementUsageCountAlias(); + + } + nanosStart = System.nanoTime(); + method.invoke(getMethodInstance(), resultArgs.toArray()); nanosEnd = System.nanoTime(); @@ -307,48 +307,49 @@ private void executeMethod(CommandSender sender, String[] args ) { } catch ( IllegalArgumentException | InvocationTargetException e) { - nanosEnd = System.nanoTime(); - - long nanosDuration = nanosEnd - nanosStart; - this.usageRunTimeNanos += nanosDuration; - - if (e.getCause() instanceof CommandError) { - CommandError ce = (CommandError) e.getCause(); - Output.get().sendError(sender, ce.getColorizedMessage()); - if (ce.showUsage()) { - sender.sendMessage(getUsage()); - } - } - else { - StringBuilder sb = new StringBuilder(); - - for ( Object arg : resultArgs ) { - sb.append( "[" ); - sb.append( arg.toString() ); - sb.append( "] " ); - } - - String message = "RegisteredCommand.executeMethod(): Invoke error: [" + - e.getMessage() + "] cause: [" + - (e.getCause() == null ? "" : e.getCause().getMessage()) + "] " + - " target instance: [methodName= " + - method.getName() + " parmCnt=" + method.getParameterCount() + " methodInstance=" + - getMethodInstance().getClass().getCanonicalName() + "] " + - "command arguments: " + sb.toString() - ; - - // Warning: if the args contains a % then the following sendError will fail because - // the % will be treated as String.format() placeholders. So to be safe and - // to prevent this failure, escape all % with a double % such as %%. - message = message.replace( "%", "%%" ); - - Output.get().logError( message ); - - Output.get().sendError( sender, "An exception has occurred. Details have been " + - "logged to the server's console." ); - - // Generally these errors are major and require program fixes, so throw - // the exception so the stacklist is logged. + nanosEnd = System.nanoTime(); + + long nanosDuration = nanosEnd - nanosStart; + this.usageRunTimeNanos += nanosDuration; + + if (e.getCause() instanceof CommandError) { + + CommandError ce = (CommandError) e.getCause(); + Output.get().sendError(sender, ce.getColorizedMessage()); + if (ce.showUsage()) { + sender.sendMessage(getUsage()); + } + } + else { + StringBuilder sb = new StringBuilder(); + + for ( Object arg : resultArgs ) { + sb.append( "[" ); + sb.append( arg.toString() ); + sb.append( "] " ); + } + + String message = "RegisteredCommand.executeMethod(): Invoke error: [" + + e.getMessage() + "] cause: [" + + (e.getCause() == null ? "" : e.getCause().getMessage()) + "] " + + " target instance: [methodName= " + + method.getName() + " parmCnt=" + method.getParameterCount() + " methodInstance=" + + getMethodInstance().getClass().getCanonicalName() + "] " + + "command arguments: " + sb.toString() + ; + + // Warning: if the args contains a % then the following sendError will fail because + // the % will be treated as String.format() placeholders. So to be safe and + // to prevent this failure, escape all % with a double % such as %%. + message = message.replace( "%", "%%" ); + + Output.get().logError( message ); + + Output.get().sendError( sender, "An exception has occurred. Details have been " + + "logged to the server's console." ); + + // Generally these errors are major and require program fixes, so throw + // the exception so the stacklist is logged. throw e; } } @@ -463,20 +464,17 @@ public boolean isSet() { return set; } -// public boolean onlyPlayers() { -// return onlyPlayers; -// } - public void sendHelpMessage(CommandSender sender) { - ChatDisplay chatDisp = getHelpMessage( sender ); - - if ( chatDisp != null ) { - chatDisp.send( sender ); - } + ChatDisplay chatDisp = getHelpMessage( sender ); + + if ( chatDisp != null ) { + chatDisp.send( sender ); + } } void set(Object methodInstance, Method method) { + this.methodInstance = methodInstance; this.method = method; method.setAccessible(true); @@ -486,11 +484,9 @@ void set(Object methodInstance, Method method) { this.permissions = command.permissions(); this.altPermissions = command.altPermissions(); - String[] aliases = CommandHandler.addConfigAliases( command.identifier(), command.aliases() ); - //addConfigAliases( command.identifier(), command.aliases() ); + String[] aliases = CommandHandler.addConfigAliases( command.identifier(), command.aliases() ); this.aliases = aliases; -// this.aliases = command.aliases(); this.docURLs = command.docURLs(); this.onlyPlayers = command.onlyPlayers(); @@ -612,33 +608,6 @@ void set(Object methodInstance, Method method) { } -// private String[] addConfigAliases( String label, String[] aliases ) -// { -// String[] results = aliases; -// -// String configKey = "prisonCommandHandler.aliases." + label.replace( " ", "." ); -// -// List ca = Prison.get().getPlatform().getConfigStringArray( configKey ); -// if ( ca != null && ca.size() > 0 && ca.get( 0 ) instanceof String ) { -// -// List configAliases = new ArrayList<>(); -// -// for ( String alias : aliases ) { -// configAliases.add( alias ); -// } -// -// for ( Object aliasObj : ca ) { -// if ( aliasObj instanceof String ) { -// configAliases.add( aliasObj.toString() ); -// } -// } -// -// results = configAliases.toArray( new String[0] ); -// -// } -// return results; -// } - public boolean testPermission(CommandSender sender) { if (!set) { return true; @@ -659,7 +628,7 @@ public void incrementUsageCount() { usageCount++; } public int getUsageCount() { - return usageCount; + return usageCount; } public void setUsageCount(int usageCount) { this.usageCount = usageCount; diff --git a/prison-core/src/main/java/tech/mcprison/prison/commands/TabCompleaterData.java b/prison-core/src/main/java/tech/mcprison/prison/commands/TabCompleaterData.java index ea32b10e2..fdb05382a 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/commands/TabCompleaterData.java +++ b/prison-core/src/main/java/tech/mcprison/prison/commands/TabCompleaterData.java @@ -74,11 +74,6 @@ private void addCommand( RegisteredCommand registeredCommand, String... usage ) getData().put( key, tcd ); } -// else { -// TabCompleaterData tcd = getData().get( key ); -// tcd.addCommand( registeredCommand, subArray ); -// } - TabCompleaterData tcd = getData().get( key ); tcd.addCommand( registeredCommand, subArray ); @@ -112,20 +107,6 @@ public void add( RegisteredCommand registeredCommand ) { addCommand( registeredCommand, usage ); -// if ( usage.length > 0 ) { -// String key = usage[0]; -// -// String[] subArray = Arrays.copyOfRange( usage, 1, usage.length ); -// -// if ( !getData().containsKey( key ) ) { -// TabCompleterData tcd = new TabCompleterData( key, subArray ); -// getData().put( key, tcd ); -// } -// else { -// getData().get( key ).add( subArray ); -// } -// } - } /** @@ -181,9 +162,7 @@ private List checkLabel( CommandSender commandSender, String label, Stri } } - else if ( args.length > 1 -// || args.length == 1 && getData().containsKey( args[0] ) - ) { + else if ( args.length > 1 ) { // if length is greater than 1 then that means that we need to // traverse to the next level of depth if we have a hit for diff --git a/prison-core/src/main/java/tech/mcprison/prison/commands/Wildcard.java b/prison-core/src/main/java/tech/mcprison/prison/commands/Wildcard.java index 5043aa39f..036115799 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/commands/Wildcard.java +++ b/prison-core/src/main/java/tech/mcprison/prison/commands/Wildcard.java @@ -23,7 +23,9 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.PARAMETER) public @interface Wildcard { +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.PARAMETER) +public @interface Wildcard { boolean join() default true; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/BlockArgumentHandler.java b/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/BlockArgumentHandler.java index ef7908ea1..0ed3554ad 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/BlockArgumentHandler.java +++ b/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/BlockArgumentHandler.java @@ -25,9 +25,11 @@ import tech.mcprison.prison.internal.CommandSender; import tech.mcprison.prison.internal.block.PrisonBlock; -public class BlockArgumentHandler extends ArgumentHandler { +public class BlockArgumentHandler + extends ArgumentHandler { public BlockArgumentHandler() { + } @Override @@ -36,50 +38,13 @@ public PrisonBlock transform(CommandSender sender, CommandArgument argument, Str PrisonBlock b = null; if ( value != null ) { - b = new PrisonBlock( value ); - - if ( b != null ) { - return b; - } + b = new PrisonBlock( value ); + + if ( b != null ) { + return b; + } } -// // Try block legacy (numerical) ID first -// try { -// m = BlockType.getBlock(Integer.parseInt(value)); -// } catch (NumberFormatException ignored) { -// } -// -// if (m != null) { -// return m; -// } -// -// // Now try new block IDs -// -// m = BlockType.getBlock(value); -// -// if (m != null) { -// return m; -// } -// -// // Now try id:data format -// if (value.contains(":")) { -// int id; -// short data; -// try { -// id = Integer.parseInt(value.split(":")[0]); -// data = Short.parseShort(value.split(":")[1]); -// } catch (NumberFormatException ignored) { -// throw new TransformError( -// Prison.get().getLocaleManager().getLocalizable("blockParseError") -// .withReplacements(value).localizeFor(sender)); -// } -// m = BlockType.getBlockWithData(id, data); -// } -// -// if (m != null) { -// return m; -// } - // No more checks, just fail throw new TransformError(Prison.get().getLocaleManager().getLocalizable("blockParseError") diff --git a/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/DoubleArgumentHandler.java b/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/DoubleArgumentHandler.java index 5728a17f1..d92eb0e61 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/DoubleArgumentHandler.java +++ b/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/DoubleArgumentHandler.java @@ -23,9 +23,11 @@ import tech.mcprison.prison.commands.TransformError; import tech.mcprison.prison.internal.CommandSender; -public class DoubleArgumentHandler extends NumberArgumentHandler { +public class DoubleArgumentHandler + extends NumberArgumentHandler { public DoubleArgumentHandler() { + super(); } @Override @@ -33,9 +35,6 @@ public Double transform(CommandSender sender, CommandArgument argument, String v throws TransformError { value = value.replaceAll( "$|%", "" ); try { -// if ( value == null || value.trim().length() == 0 ) { -// return null; -// } return Double.parseDouble(value); } catch (NumberFormatException e) { throw new TransformError( diff --git a/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/DoubleClassArgumentHandler.java b/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/DoubleClassArgumentHandler.java index 2842f043a..6034358e6 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/DoubleClassArgumentHandler.java +++ b/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/DoubleClassArgumentHandler.java @@ -5,30 +5,32 @@ import tech.mcprison.prison.commands.TransformError; import tech.mcprison.prison.internal.CommandSender; -public class DoubleClassArgumentHandler extends NumberArgumentHandler { +public class DoubleClassArgumentHandler + extends NumberArgumentHandler { public DoubleClassArgumentHandler() { + super(); } @Override public Double transform(CommandSender sender, CommandArgument argument, String value) throws TransformError { - Double results = null; - - if ( value != null ) { - - value = value.replaceAll( "$|%", "" ); - if ( value.trim().length() > 0 ) { - try { - results = Double.parseDouble(value); - } catch (NumberFormatException e) { - throw new TransformError( - Prison.get().getLocaleManager().getLocalizable("numberParseError") - .withReplacements(value).localizeFor(sender)); - } - } - } - return results; + Double results = null; + + if ( value != null ) { + + value = value.replaceAll( "$|%", "" ); + if ( value.trim().length() > 0 ) { + try { + results = Double.parseDouble(value); + } catch (NumberFormatException e) { + throw new TransformError( + Prison.get().getLocaleManager().getLocalizable("numberParseError") + .withReplacements(value).localizeFor(sender)); + } + } + } + return results; } } diff --git a/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/IntegerArgumentHandler.java b/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/IntegerArgumentHandler.java index 4118d2af0..1ecc2b20a 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/IntegerArgumentHandler.java +++ b/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/IntegerArgumentHandler.java @@ -27,15 +27,16 @@ public class IntegerArgumentHandler extends NumberArgumentHandler { public IntegerArgumentHandler() { + super(); } @Override public Integer transform(CommandSender sender, CommandArgument argument, String value) throws TransformError { - if ( value != null ) { - value = value.replaceAll( "$|%", "" ); - } + if ( value != null ) { + value = value.replaceAll( "$|%", "" ); + } try { return Integer.parseInt(value); diff --git a/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/IntegerClassArgumentandler.java b/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/IntegerClassArgumentandler.java index f7e31ac49..177eb1cd2 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/IntegerClassArgumentandler.java +++ b/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/IntegerClassArgumentandler.java @@ -8,29 +8,29 @@ public class IntegerClassArgumentandler extends NumberArgumentHandler { - public IntegerClassArgumentandler() { + super(); } - @Override public Integer transform(CommandSender sender, CommandArgument argument, String value) + @Override + public Integer transform(CommandSender sender, CommandArgument argument, String value) throws TransformError { - Integer results = null; - - if ( value != null ) { - - value = value.replaceAll( "$|%", "" ); - - //value = value.replaceAll("$|%", ""); - if ( value.trim().length() > 0 ) { - try { - results = Integer.parseInt(value); - } catch (NumberFormatException e) { - throw new TransformError( - Prison.get().getLocaleManager().getLocalizable("numberParseError") - .withReplacements(value).localizeFor(sender)); - } - } - } - return results; + Integer results = null; + + if ( value != null ) { + + value = value.replaceAll( "$|%", "" ); + + if ( value.trim().length() > 0 ) { + try { + results = Integer.parseInt(value); + } catch (NumberFormatException e) { + throw new TransformError( + Prison.get().getLocaleManager().getLocalizable("numberParseError") + .withReplacements(value).localizeFor(sender)); + } + } + } + return results; } } diff --git a/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/LongArgumentHandler.java b/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/LongArgumentHandler.java index e10fb6905..3816d18a3 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/LongArgumentHandler.java +++ b/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/LongArgumentHandler.java @@ -9,15 +9,16 @@ public class LongArgumentHandler extends NumberArgumentHandler { public LongArgumentHandler() { + super(); } @Override public Long transform(CommandSender sender, CommandArgument argument, String value) throws TransformError { - if ( value != null ) { - value = value.replaceAll( "$|%", "" ); - } + if ( value != null ) { + value = value.replaceAll( "$|%", "" ); + } try { return Long.parseLong(value); diff --git a/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/LongClassArgumentHandler.java b/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/LongClassArgumentHandler.java index 665e24653..07e885e1a 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/LongClassArgumentHandler.java +++ b/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/LongClassArgumentHandler.java @@ -9,28 +9,28 @@ public class LongClassArgumentHandler extends NumberArgumentHandler { public LongClassArgumentHandler() { + super(); } @Override public Long transform(CommandSender sender, CommandArgument argument, String value) throws TransformError { - Long results = null; - - if ( value != null ) { - - value = value.replaceAll( "$|%", "" ); - - try { - results = Long.parseLong(value); - } catch (NumberFormatException e) { - throw new TransformError( - Prison.get().getLocaleManager().getLocalizable("numberParseError") - .withReplacements(value).localizeFor(sender)); - } - } + Long results = null; + + if ( value != null ) { + + value = value.replaceAll( "$|%", "" ); + + try { + results = Long.parseLong(value); + } catch (NumberFormatException e) { + throw new TransformError( + Prison.get().getLocaleManager().getLocalizable("numberParseError") + .withReplacements(value).localizeFor(sender)); + } + } return results; } - } diff --git a/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/NumberArgumentHandler.java b/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/NumberArgumentHandler.java index 3c8e2fa58..d56e900d9 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/NumberArgumentHandler.java +++ b/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/NumberArgumentHandler.java @@ -23,9 +23,12 @@ import tech.mcprison.prison.commands.VerifyError; import tech.mcprison.prison.internal.CommandSender; -public abstract class NumberArgumentHandler extends ArgumentHandler { +public abstract class NumberArgumentHandler + extends ArgumentHandler { public NumberArgumentHandler() { + super(); + addVerifier("min", new ArgumentVerifier() { @Override public void verify(CommandSender sender, CommandArgument argument, String verifyName, diff --git a/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/PlayerArgumentHandler.java b/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/PlayerArgumentHandler.java index 7b1976313..139dee602 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/PlayerArgumentHandler.java +++ b/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/PlayerArgumentHandler.java @@ -41,7 +41,8 @@ public Player var(CommandSender sender, CommandArgument argument, String varName }); } - @Override public Player transform(CommandSender sender, CommandArgument argument, String value) + @Override + public Player transform(CommandSender sender, CommandArgument argument, String value) throws TransformError { return Prison.get().getPlatform().getPlayer(value).orElseThrow(() -> new TransformError( diff --git a/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/StringArgumentHandler.java b/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/StringArgumentHandler.java index acce7abe3..adab3b177 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/StringArgumentHandler.java +++ b/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/StringArgumentHandler.java @@ -71,12 +71,13 @@ public void verify(CommandSender sender, CommandArgument argument, String verify }); } - @Override public String transform(CommandSender sender, CommandArgument argument, String value) + @Override + public String transform(CommandSender sender, CommandArgument argument, String value) throws TransformError { - if ( value != null ) { - value = value.replaceAll( "$|%", "" ); - } + if ( value != null ) { + value = value.replaceAll( "$|%", "" ); + } return value; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/WorldArgumentHandler.java b/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/WorldArgumentHandler.java index ac3cec1b3..3cec63e95 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/WorldArgumentHandler.java +++ b/prison-core/src/main/java/tech/mcprison/prison/commands/handlers/WorldArgumentHandler.java @@ -42,7 +42,8 @@ public World var(CommandSender sender, CommandArgument argument, String varName) }); } - @Override public World transform(CommandSender sender, CommandArgument argument, String value) + @Override + public World transform(CommandSender sender, CommandArgument argument, String value) throws TransformError { return Prison.get().getPlatform().getWorld(value).orElseThrow(() -> new TransformError( Prison.get().getLocaleManager().getLocalizable("worldNotFound").withReplacements(value) diff --git a/prison-core/src/main/java/tech/mcprison/prison/discord/DiscordWebhook.java b/prison-core/src/main/java/tech/mcprison/prison/discord/DiscordWebhook.java index 09203dfb6..14c4ddb22 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/discord/DiscordWebhook.java +++ b/prison-core/src/main/java/tech/mcprison/prison/discord/DiscordWebhook.java @@ -14,9 +14,6 @@ import javax.net.ssl.HttpsURLConnection; -import tech.mcprison.prison.output.Output; -import tech.mcprison.prison.output.Output.DebugTarget; - /** * * This class is based upon the github gist of k3kdude: diff --git a/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonDiscordWebhook.java b/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonDiscordWebhook.java index 66b4b40ec..ad83bf78f 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonDiscordWebhook.java +++ b/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonDiscordWebhook.java @@ -11,7 +11,6 @@ import tech.mcprison.prison.discord.DiscordWebhook.EmbedObject; import tech.mcprison.prison.internal.CommandSender; import tech.mcprison.prison.output.Output; -import tech.mcprison.prison.output.Output.DebugTarget; import tech.mcprison.prison.util.Text; /** @@ -64,6 +63,7 @@ public boolean setup() { return results; } + @SuppressWarnings("unused") public void send( CommandSender sender, String title, String message, boolean addPrisonStats ) { int totalSize = 0; @@ -76,7 +76,7 @@ public void send( CommandSender sender, String title, String message, boolean ad if ( addPrisonStats ) { - totalSize += addPrisonStats( title, webhook ); + totalSize += addPrisonStats( title, webhook ); } 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 dff4b7092..50f64e4c0 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 @@ -356,8 +356,6 @@ private String postPasteHelpchAt( String text, boolean raw ) if ( rawJson != null ) { - //Output.get().logInfo( "### rawJson : " + rawJson ); - // ### rawJson : {"key":"utozikecag"} Gson gson = new Gson(); JsonObject object = gson.fromJson( rawJson, JsonObject.class ); 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 1f05643f4..5fb6ec2bb 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 @@ -85,20 +85,6 @@ public static ColorMaps match( String line ) { 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; @@ -138,17 +124,6 @@ public void saveToSupportFile( StringBuilder text, String supportName ) { } -// 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, String supportName ) { File file = getSupportFile(); @@ -183,7 +158,6 @@ private void appendSaveSupportDataToFile( StringBuilder text ) { bw.write( "\n\n- = - = - = - = - = - = - = - = - = - = -\n\n"); writeBufferedWriter( bw, text ); -// bw.write( text.toString() ); } catch (IOException e) { @@ -217,6 +191,7 @@ private void writeBufferedWriter( BufferedWriter bw, StringBuilder text ) { + @SuppressWarnings("unused") private List extractAllHyperlinkPlaceholders( StringBuilder text ) { List hlp = new ArrayList<>(); @@ -384,13 +359,6 @@ private File createSupportFile( String name ) { 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; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonSupportLinkageData.java b/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonSupportLinkageData.java index 2de468e2e..348da842e 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonSupportLinkageData.java +++ b/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonSupportLinkageData.java @@ -2,7 +2,12 @@ import tech.mcprison.prison.discord.PrisonSupportFileLinkage.PrimaryLinkages; import tech.mcprison.prison.discord.PrisonSupportFileLinkage.SecondaryLinkages; - +/** + *

    This may be a work in progress to provide hyperlinked help docs + * that are submitted when admins are needing help with their systems. + *

    + * + */ public class PrisonSupportLinkageData { private String rawLine; @@ -13,8 +18,6 @@ public class PrisonSupportLinkageData { private String secondaryText; - - private PrisonSupportLinkageData otherLinkage; @@ -41,8 +44,41 @@ public PrisonSupportLinkageData( String line ) { this.secondaryText = secondaryText; } - - + } + + protected String getRawLine() { + return rawLine; + } + protected void setRawLine(String rawLine) { + this.rawLine = rawLine; + } + + protected PrimaryLinkages getPrimary() { + return primary; + } + protected void setPrimary(PrimaryLinkages primary) { + this.primary = primary; + } + + protected SecondaryLinkages getSecondary() { + return secondary; + } + protected void setSecondary(SecondaryLinkages secondary) { + this.secondary = secondary; + } + + protected String getSecondaryText() { + return secondaryText; + } + protected void setSecondaryText(String secondaryText) { + this.secondaryText = secondaryText; + } + + protected PrisonSupportLinkageData getOtherLinkage() { + return otherLinkage; + } + protected void setOtherLinkage(PrisonSupportLinkageData otherLinkage) { + this.otherLinkage = otherLinkage; } } diff --git a/prison-core/src/main/java/tech/mcprison/prison/file/FileCollection.java b/prison-core/src/main/java/tech/mcprison/prison/file/FileCollection.java index 40dfa3e93..c357950c6 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/file/FileCollection.java +++ b/prison-core/src/main/java/tech/mcprison/prison/file/FileCollection.java @@ -23,8 +23,8 @@ public class FileCollection private File collDir; public FileCollection(File collDir) { - // This may be within a module. If so then pass these values... - super(null, null); + // This may be within a module. If so then pass these values... + super(null, null); this.collDir = collDir; } @@ -54,100 +54,86 @@ public File getCollDir() { */ @Override public List getAll() { - List allDocs = new ArrayList<>(); - - FileFilter fFilter = JsonFileIO.getPrisonFileFilter(); - - - // Each folder in the root directory is its own database. - // We'll initialize each of them here. - File[] collectionFiles = this.collDir.listFiles( fFilter ); -// File[] collectionFiles = this.collDir.listFiles((dir, name) -> name.endsWith(".json")); - if (collectionFiles != null) { - for (File dbFile : collectionFiles) { - if ( isDeleted( dbFile ) ) { - String message = "FileCollection.getAll skipping logically deleted FileDocument: " + - dbFile.getAbsolutePath(); - Output.get().logInfo( message ); - } else { - Document doc = (Document) readJsonFile(dbFile, new Document()); - if ( doc != null ) - { - allDocs.add( doc ); - } - } - } - } - - return allDocs; + List allDocs = new ArrayList<>(); + + FileFilter fFilter = JsonFileIO.getPrisonFileFilter(); + + + // Each folder in the root directory is its own database. + // We'll initialize each of them here. + File[] collectionFiles = this.collDir.listFiles( fFilter ); + + if (collectionFiles != null) { + for (File dbFile : collectionFiles) { + if ( isDeleted( dbFile ) ) { + String message = "FileCollection.getAll skipping logically deleted FileDocument: " + + dbFile.getAbsolutePath(); + Output.get().logInfo( message ); + } else { + Document doc = (Document) readJsonFile(dbFile, new Document()); + if ( doc != null ) + { + allDocs.add( doc ); + } + } + } + } + + return allDocs; } @Override public Optional get(String key) { - File dbFile = getFile(key); - Document doc = (Document) readJsonFile(dbFile, new Document()); + File dbFile = getFile(key); + Document doc = (Document) readJsonFile(dbFile, new Document()); return Optional.ofNullable(doc); } -// @Override -// public void save(Document document) -// { -// save((String)document.get("name"), document); -// } - -// @Override -// public void save(String filename, Document document) -// { -// String suffix = filename.endsWith(FILE_SUFFIX_JSON) ? "" : FILE_SUFFIX_JSON; -// File dbFile = new File(collDir, filename + suffix); -// saveJsonFile( dbFile, document ); -// } - @Override public void save(String filename, Document document, String oldFilename, String fileType ) { File dbFile = getFile(filename); - saveJsonFile( dbFile, document ); - - if ( oldFilename != null ) { - - // Since the new file should have been saved by now... - File oldDbFile = getFile(oldFilename); - - // If both the new file and old file exists, then need to remove the old file: - if ( dbFile.exists() && dbFile.length() > 0 && oldDbFile.exists() ) { - - boolean deleted = oldDbFile.delete(); - - if ( deleted ) { - - Output.get().logInfo( - "&3%s File Converted: &7%s &3--> &7%s", - fileType, - oldFilename + FILE_SUFFIX_JSON, - filename + FILE_SUFFIX_JSON - ); - } - else { - Output.get().logInfo( - "&3The old %s file could not be removed: " - + "Old file &7%s &3. " + - "Reason unknown (check logs?). " - + "New file name &7%s. [%s]", - fileType, - oldFilename + FILE_SUFFIX_JSON, - filename + FILE_SUFFIX_JSON, - oldDbFile.getAbsolutePath() - ); - - } - } - } + saveJsonFile( dbFile, document ); + + if ( oldFilename != null ) { + + // Since the new file should have been saved by now... + File oldDbFile = getFile(oldFilename); + + // If both the new file and old file exists, then need to remove the old file: + if ( dbFile.exists() && dbFile.length() > 0 && oldDbFile.exists() ) { + + boolean deleted = oldDbFile.delete(); + + if ( deleted ) { + + Output.get().logInfo( + "&3%s File Converted: &7%s &3--> &7%s", + fileType, + oldFilename + FILE_SUFFIX_JSON, + filename + FILE_SUFFIX_JSON + ); + } + else { + Output.get().logInfo( + "&3The old %s file could not be removed: " + + "Old file &7%s &3. " + + "Reason unknown (check logs?). " + + "New file name &7%s. [%s]", + fileType, + oldFilename + FILE_SUFFIX_JSON, + filename + FILE_SUFFIX_JSON, + oldDbFile.getAbsolutePath() + ); + + } + } + } } @@ -175,17 +161,17 @@ public boolean exists(String name) @Override public boolean delete(String name) { - File dbFile = getFile(name); - return dbFile.exists() ? virtualDelete( dbFile ) : false; + File dbFile = getFile(name); + return dbFile.exists() ? virtualDelete( dbFile ) : false; } @Override public File backup( String name ) { - File dbFile = getFile(name); - File backupFile = dbFile.exists() ? virtualBackup( dbFile ) : null; - - return backupFile; + File dbFile = getFile(name); + File backupFile = dbFile.exists() ? virtualBackup( dbFile ) : null; + + return backupFile; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/file/FileDatabase.java b/prison-core/src/main/java/tech/mcprison/prison/file/FileDatabase.java index a5354cce6..6daa4d816 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/file/FileDatabase.java +++ b/prison-core/src/main/java/tech/mcprison/prison/file/FileDatabase.java @@ -39,22 +39,22 @@ public File getDbDir() { *

    */ public void refresh() { - collectionMap.clear(); - - // Each folder in the db directory is its own collection. - // We'll initialize each of them here. - File[] collectionDirs = dbDir.listFiles(File::isDirectory); - if (collectionDirs != null) { - for (File collDir : collectionDirs) { - if ( isDeleted( collDir ) ) { - String message = "FileDatabase.refresh skipping logically deleted FileCollection: " + - collDir.getAbsolutePath(); - Output.get().logInfo( message ); - } else { - collectionMap.put(collDir.getName(), new FileCollection(collDir)); - } - } - } + collectionMap.clear(); + + // Each folder in the db directory is its own collection. + // We'll initialize each of them here. + File[] collectionDirs = dbDir.listFiles(File::isDirectory); + if (collectionDirs != null) { + for (File collDir : collectionDirs) { + if ( isDeleted( collDir ) ) { + String message = "FileDatabase.refresh skipping logically deleted FileCollection: " + + collDir.getAbsolutePath(); + Output.get().logInfo( message ); + } else { + collectionMap.put(collDir.getName(), new FileCollection(collDir)); + } + } + } } @@ -67,15 +67,15 @@ public void refresh() { @Override public Optional getCollection(String name) { - Collection results = collectionMap.get(name); - - if ( results == null ) - { - // try to create the FileCollection: - createCollection(name); - results = collectionMap.get(name); - } - + Collection results = collectionMap.get(name); + + if ( results == null ) + { + // try to create the FileCollection: + createCollection(name); + results = collectionMap.get(name); + } + return Optional.ofNullable(results); } @@ -93,15 +93,15 @@ public Optional getCollection(String name) */ @Override public boolean createCollection(String name) { - boolean results = false; + boolean results = false; File collDir = new File(dbDir, name); if (!collDir.exists()) { - results = collDir.mkdirs(); + results = collDir.mkdirs(); } else { - // the directory already exist... who cares? Let's use it: - results = true; + // the directory already exist... who cares? Let's use it: + results = true; } collectionMap.put(name, new FileCollection(collDir)); @@ -132,24 +132,21 @@ public boolean createCollection(String name) { */ @Override public boolean deleteCollection(String name) { - boolean results = false; + boolean results = false; File collDir = new File(dbDir, name); Collection coll = collectionMap.get(name); if (collDir.exists() && coll != null) { - // Perform a logical delete on the collection so it can be manually recovered if this is an error: - virtualDelete( collDir ); - - // This dispose just removes the entries from the collection and deletes nothing from the file system: - //coll.dispose(); - //results = collDir.delete(); - collectionMap.remove(name); - results = true; + // Perform a logical delete on the collection so it can be manually recovered if this is an error: + virtualDelete( collDir ); + + collectionMap.remove(name); + results = true; } else { - String message = "The attempt to delete a FileCollection named " + name + - " failed because either the directory does not exist or it was not in the collectionMap."; - Output.get().logWarn( message ); + String message = "The attempt to delete a FileCollection named " + name + + " failed because either the directory does not exist or it was not in the collectionMap."; + Output.get().logWarn( message ); } return results; diff --git a/prison-core/src/main/java/tech/mcprison/prison/file/FileIO.java b/prison-core/src/main/java/tech/mcprison/prison/file/FileIO.java index 8dce4ad90..063af2332 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/file/FileIO.java +++ b/prison-core/src/main/java/tech/mcprison/prison/file/FileIO.java @@ -97,8 +97,6 @@ protected void saveFile( File file, String data ) if ( file != null && data != null ) { File tempFile = getTempFile( file ); -// String tempFileName = file.getName() + "." + getTimestampFormat() + ".tmp"; -// File tempFile = new File(file.getParentFile(), tempFileName); boolean disableAdvancedSaves = Prison.get().getPlatform().getConfigBooleanFalse( @@ -116,8 +114,6 @@ protected void saveFile( File file, String data ) // Write as an UTF-8 stream: Files.write( tempFile.toPath(), lines, StandardCharsets.UTF_8 ); -// Files.write( tempFile.toPath(), data.getBytes() ); - // If original target exists, then delete it: if ( file.exists() ) { @@ -160,17 +156,6 @@ protected void saveFile( File file, String data ) Files.write( file.toPath(), lines, StandardCharsets.UTF_8, sooW, sooTe ); -// Files.write( tempFile.toPath(), data.getBytes() ); - - // If original target exists, then delete it: -// if ( file.exists() ) -// { -// file.delete(); -// } -// -// tempFile.renameTo( file ); - - if ( !keepTempFiles ) { tempFile.delete(); } @@ -189,7 +174,6 @@ protected void saveFile( File file, String data ) protected String readFile( File file ) { StringBuilder results = new StringBuilder(); -// String results = null; if ( file.exists() ) { @@ -200,9 +184,6 @@ protected String readFile( File file ) for ( String line : lines ) { results.append( line ).append( "\n" ); } - -// byte[] bytes = Files.readAllBytes( file.toPath() ); -// results = new String(bytes); } catch ( IOException e ) { @@ -296,37 +277,13 @@ public static String getFileNameUUIDFragment( String filename ) { : uuidTmp; } return uuid; - -// String uuid = player.getUUID().toString(); -// return uuid.substring( 0, 9 ) + -// uuid.substring( 25 ); } -// /** -// *

    This is a helper function to ensure that the given file name is -// * always generated correctly and consistently. -// *

    -// * -// * @return "player_" plus the least significant bits of the UID -// */ -// public static String filenamePlayer( Player player ) -// { -// boolean useNewFormat = useFriendlyUserFileNames(); -// -// return useNewFormat ? filenamePlayerNew( player ) : filenamePlayerOld( player ); -// } - -// public static String filenameCache( Player player ) -// { -// boolean useNewFormat = useFriendlyUserFileNames(); -// -// return useNewFormat ? filenameCacheNew( player ) : filenameCacheOld( player ); -// } public String filenamePrefix( String filename, String prefixDeliminator ) { - int idx = filename.lastIndexOf( prefixDeliminator ) + 1; - String prefix = idx > 0 ? filename.substring(0, idx) : null; - return prefix; + int idx = filename.lastIndexOf( prefixDeliminator ) + 1; + String prefix = idx > 0 ? filename.substring(0, idx) : null; + return prefix; } /** @@ -345,75 +302,61 @@ public String filenamePrefix( String filename, String prefixDeliminator ) { * @return */ public File checkFile( File path, String filename, String prefixDeliminator ) { - - String prefix = filenamePrefix( filename, prefixDeliminator ); - - List files = getFilesFromPrefix( prefix, path ); - - return files.size() > 0 ? files.get(0) : new File( path, filename ); + + String prefix = filenamePrefix( filename, prefixDeliminator ); + + List files = getFilesFromPrefix( prefix, path ); + + return files.size() > 0 ? files.get(0) : new File( path, filename ); } public static File filePlayer( Player player ) { - FileIO fIO = new FileIO() {}; - return fIO.checkFiles( filenamePlayerNew( player ), filenamePlayerOld( player ), PLAYER_PATH ); + FileIO fIO = new FileIO() {}; + return fIO.checkFiles( filenamePlayerNew( player ), filenamePlayerOld( player ), PLAYER_PATH ); } public static File fileCache( Player player ) { - FileIO fIO = new FileIO() {}; - return fIO.checkFiles( filenameCacheNew( player ), filenameCacheOld( player ), CACHE_PATH ); + FileIO fIO = new FileIO() {}; + return fIO.checkFiles( filenameCacheNew( player ), filenameCacheOld( player ), CACHE_PATH ); } private File checkFiles( String newFileName, String oldFileName, String pathName ) { - File results = null; - - File path = new File( Prison.get().getDataFolder(), pathName ); - - File newPlayerFile = checkFile( path, newFileName, "_" ); - - if ( newPlayerFile.exists() ) { - results = newPlayerFile; - } - else { - File oldPlayerFile = checkFile( path, oldFileName, "." ); - - if ( oldPlayerFile.exists() ) { - results = oldPlayerFile; - } - } - - if ( results == null ) { - // Did not find a new format file, or an old file format, so use the new format: - results = newPlayerFile; - } - - // If the file chosen is not equal to the newFileName, then rename it: - else if ( !newFileName.equals(results.getName()) ) { - File newFile = new File( path, newFileName ); - results.renameTo(newFile); - - // Rename does not change the original file path in results so have to reassign it: - results = newFile; - } - - return results; + File results = null; + + File path = new File( Prison.get().getDataFolder(), pathName ); + + File newPlayerFile = checkFile( path, newFileName, "_" ); + + if ( newPlayerFile.exists() ) { + results = newPlayerFile; + } + else { + File oldPlayerFile = checkFile( path, oldFileName, "." ); + + if ( oldPlayerFile.exists() ) { + results = oldPlayerFile; + } + } + + if ( results == null ) { + // Did not find a new format file, or an old file format, so use the new format: + results = newPlayerFile; + } + + // If the file chosen is not equal to the newFileName, then rename it: + else if ( !newFileName.equals(results.getName()) ) { + File newFile = new File( path, newFileName ); + results.renameTo(newFile); + + // Rename does not change the original file path in results so have to reassign it: + results = newFile; + } + + return results; } -// /** -// *

    This function will check two things. First will be the config settings within -// * 'config.yml' to see if the new format is enabled. Secondly, it checks to see if -// * the PrisonSystemSettings has recorded if the conversion has taken place. -// * Both have to be true in order for this function to return a value of true., -// *

    -// * -// * @return -// */ -// public static boolean useFriendlyUserFileNames() { -// -// return PrisonSystemSettings.useFriendlyUserFileNames(); -// } - /** * Do not use. Use 'filenameCache( player )'. * @@ -422,7 +365,7 @@ else if ( !newFileName.equals(results.getName()) ) { */ public static String filenameCacheNew( Player player ) { - return "cache_" + getPlayerFileNameNewVersion( player ); + return "cache_" + getPlayerFileNameNewVersion( player ); } /** * Do not use. Use 'filenameCache( player )'. @@ -432,7 +375,7 @@ public static String filenameCacheNew( Player player ) { */ public static String filenameCacheOld( Player player ) { - return getPlayerFileNameShortVersion( player ); + return getPlayerFileNameShortVersion( player ); } /** @@ -443,7 +386,7 @@ public static String filenameCacheOld( Player player ) { */ public static String filenamePlayerNew( Player player ) { - return "player_" + getPlayerFileNameNewVersion( player ); + return "player_" + getPlayerFileNameNewVersion( player ); } /** * Do not use. Use 'filenamePlayer( player )'. @@ -453,7 +396,7 @@ public static String filenamePlayerNew( Player player ) */ public static String filenamePlayerOld( Player player ) { - return "player_" + player.getUUID().getLeastSignificantBits() + FILE_SUFFIX_JSON; + return "player_" + player.getUUID().getLeastSignificantBits() + FILE_SUFFIX_JSON; } @@ -479,7 +422,7 @@ public static String filenamePlayerOld( Player player ) @Deprecated public static String getPlayerFileNameShortVersion( Player player ) { - String UUIDString = player.getUUID().toString(); + String UUIDString = player.getUUID().toString(); String uuidFragment = getFileNamePrefixObsolete( UUIDString ); return uuidFragment + "_" + player.getName() + FILE_SUFFIX_JSON; @@ -507,18 +450,18 @@ private static String getFileNamePrefixObsolete( String UUIDString ) { public List getFilesFromPrefix( String filePrefix, File path ) { List results = new ArrayList<>(); - FileFilter fFilter = getFilePrefixFilter( filePrefix ); - - - File[] collectionFiles = path.listFiles( fFilter ); - if ( collectionFiles != null ) { - - for (File file : collectionFiles ) { - results.add(file); - } - } - - return results; + FileFilter fFilter = getFilePrefixFilter( filePrefix ); + + + File[] collectionFiles = path.listFiles( fFilter ); + if ( collectionFiles != null ) { + + for (File file : collectionFiles ) { + results.add(file); + } + } + + return results; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/file/FileStorage.java b/prison-core/src/main/java/tech/mcprison/prison/file/FileStorage.java index a1b554458..bdfde2b81 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/file/FileStorage.java +++ b/prison-core/src/main/java/tech/mcprison/prison/file/FileStorage.java @@ -47,23 +47,23 @@ public FileStorage(File rootDir) { *

    */ public void refresh() { - databaseMap.clear(); - - // Each folder in the root directory is its own database. - // We'll initialize each of them here. - File[] databaseFiles = this.rootDir.listFiles(File::isDirectory); - if (databaseFiles != null) { - for (File dbFile : databaseFiles) { - if ( isDeleted( dbFile ) ) { - String message = "FileStorage.refresh skipping logically deleted FileDatabase: " + - dbFile.getAbsolutePath(); - Output.get().logInfo( message ); - } else { - databaseMap.put(dbFile.getName(), new FileDatabase(dbFile)); - - } - } - } + databaseMap.clear(); + + // Each folder in the root directory is its own database. + // We'll initialize each of them here. + File[] databaseFiles = this.rootDir.listFiles(File::isDirectory); + if (databaseFiles != null) { + for (File dbFile : databaseFiles) { + if ( isDeleted( dbFile ) ) { + String message = "FileStorage.refresh skipping logically deleted FileDatabase: " + + dbFile.getAbsolutePath(); + Output.get().logInfo( message ); + } else { + databaseMap.put(dbFile.getName(), new FileDatabase(dbFile)); + + } + } + } } @@ -86,15 +86,15 @@ public boolean isConnected() { */ @Override public Optional getDatabase(String name) { - Database results = databaseMap.get(name); - - if ( results == null ) - { - // try to create the FileDatabase: - createDatabase(name); - results = databaseMap.get(name); - } - + Database results = databaseMap.get(name); + + if ( results == null ) + { + // try to create the FileDatabase: + createDatabase(name); + results = databaseMap.get(name); + } + return Optional.ofNullable(results); } @@ -109,15 +109,15 @@ public Optional getDatabase(String name) { */ @Override public boolean createDatabase(String name) { - boolean results = false; + boolean results = false; File directory = new File(rootDir, name); if (!directory.exists()) { - results = directory.mkdirs(); + results = directory.mkdirs(); } else { - // directory already exists, so use it: - results = true; + // directory already exists, so use it: + results = true; } databaseMap.put(name, new FileDatabase(directory)); @@ -148,24 +148,24 @@ public boolean createDatabase(String name) { */ @Override public boolean deleteDatabase(String name) { - boolean results = false; + boolean results = false; File directory = new File(rootDir, name); Database db = databaseMap.get(name); if (directory.exists() && db != null) { - // Perform a logical delete on the database so it can be manually recovered if this is an error: - virtualDelete( directory ); - - // This dispose just removes the entries from the collection and deletes nothing from the file system: - db.dispose(); - //directory.delete(); - databaseMap.remove(name); - results = true; + // Perform a logical delete on the database so it can be manually recovered if this is an error: + virtualDelete( directory ); + + // This dispose just removes the entries from the collection and deletes nothing from the file system: + db.dispose(); + //directory.delete(); + databaseMap.remove(name); + results = true; } else { - String message = "The attempt to delete a FileDatabase named " + name + - " failed because either the directory does not exist or it was not in the databaseMap."; - Output.get().logWarn( message ); + String message = "The attempt to delete a FileDatabase named " + name + + " failed because either the directory does not exist or it was not in the databaseMap."; + Output.get().logWarn( message ); } return results; diff --git a/prison-core/src/main/java/tech/mcprison/prison/file/FileVirtualDelete.java b/prison-core/src/main/java/tech/mcprison/prison/file/FileVirtualDelete.java index 5be2b65a6..5663a15a0 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/file/FileVirtualDelete.java +++ b/prison-core/src/main/java/tech/mcprison/prison/file/FileVirtualDelete.java @@ -1,6 +1,3 @@ -/** - * - */ package tech.mcprison.prison.file; import java.io.File; @@ -12,9 +9,6 @@ import tech.mcprison.prison.output.Output; -/** - * - */ public abstract class FileVirtualDelete { public static final String FILE_LOGICAL_DELETE_PREFIX = ".deleted_"; @@ -55,23 +49,23 @@ protected boolean virtualDelete( File source ) */ protected File virtualBackup( File source ) { - SimpleDateFormat sdf = new SimpleDateFormat("_yyyy-MM-dd_HH-mm-ss"); - String name = FILE_LOGICAL_BACKUP_PREFIX + source.getName() + sdf.format( new Date() ) + ".bu"; - File backupFile = new File( source.getParentFile(), name); - - try { - Files.copy( source, backupFile ); - } - catch ( IOException e ) - { - Output.get().logError( - String.format( - "Could not create a backup. SourceFile: %s BackupFile: %s Error: [%s]", - source.getAbsolutePath(), backupFile.getAbsolutePath(), e.getMessage() )); - e.printStackTrace(); - } - - return backupFile; + SimpleDateFormat sdf = new SimpleDateFormat("_yyyy-MM-dd_HH-mm-ss"); + String name = FILE_LOGICAL_BACKUP_PREFIX + source.getName() + sdf.format( new Date() ) + ".bu"; + File backupFile = new File( source.getParentFile(), name); + + try { + Files.copy( source, backupFile ); + } + catch ( IOException e ) + { + Output.get().logError( + String.format( + "Could not create a backup. SourceFile: %s BackupFile: %s Error: [%s]", + source.getAbsolutePath(), backupFile.getAbsolutePath(), e.getMessage() )); + e.printStackTrace(); + } + + return backupFile; } /** @@ -85,9 +79,9 @@ protected File virtualBackup( File source ) */ protected boolean isDeleted( File source ) { - return - source.getName().toLowerCase().startsWith( FILE_LOGICAL_DELETE_PREFIX ) || - source.getName().toLowerCase().startsWith( FILE_LOGICAL_BACKUP_PREFIX ); + return + source.getName().toLowerCase().startsWith( FILE_LOGICAL_DELETE_PREFIX ) || + source.getName().toLowerCase().startsWith( FILE_LOGICAL_BACKUP_PREFIX ); } } diff --git a/prison-core/src/main/java/tech/mcprison/prison/file/YamlFileIO.java b/prison-core/src/main/java/tech/mcprison/prison/file/YamlFileIO.java index e01e17bbb..376f4e493 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/file/YamlFileIO.java +++ b/prison-core/src/main/java/tech/mcprison/prison/file/YamlFileIO.java @@ -98,35 +98,6 @@ public boolean saveYamlAutoFeatures( Map config ) { break; } -// if ( value.isNullNode() ) { -// // skip nulls -// set( key, null ); -// } -// else if ( value.isBooleanNode() ) { -// set( key, ((BooleanNode) value).getValue() ); -// } -// else if ( value.isTextNode() ) { -// set( key, ((TextNode) value).getValue() ); -// } -// else if ( value.isDoubleNode() ) { -// set( key, ((DoubleNode) value).getValue() ); -// } -// else if ( value.isLongNode() ) { -// set( key, ((LongNode) value).getValue() ); -// } -// else if ( value.isIntegerNode() ) { -// set( key, ((IntegerNode) value).getValue() ); -// } -// else if ( value.isStringListNode() ) { -// set( key, ((StringListNode) value).getValue() ); -// } -// else if ( value.isBlockConverterNode() ) { -// set( key, ((BlockConvertersNode) value).t ); -// } -// else { -// // invalid type... not supported. -//// set( key, value ); -// } } return saveYaml(); diff --git a/prison-core/src/main/java/tech/mcprison/prison/integration/CustomBlockIntegration.java b/prison-core/src/main/java/tech/mcprison/prison/integration/CustomBlockIntegration.java index 8c6a015fb..a05c4b3a8 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/integration/CustomBlockIntegration.java +++ b/prison-core/src/main/java/tech/mcprison/prison/integration/CustomBlockIntegration.java @@ -51,7 +51,6 @@ public CustomBlockIntegration( String keyName, String providerName, public abstract void setCustomBlockIdAsync( PrisonBlock prisonBlock, Location location ); public abstract List getDrops( Player player, PrisonBlock prisonBlock, ItemStack tool ); -// public abstract List getDrops( PrisonBlock prisonBlock ); public abstract List getCustomBlockList(); diff --git a/prison-core/src/main/java/tech/mcprison/prison/integration/IntegrationManager.java b/prison-core/src/main/java/tech/mcprison/prison/integration/IntegrationManager.java index 68e01dbf5..4046e2e6d 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/integration/IntegrationManager.java +++ b/prison-core/src/main/java/tech/mcprison/prison/integration/IntegrationManager.java @@ -76,35 +76,35 @@ public boolean hasForType(IntegrationType type) { * @param i The {@link Integration}. */ public void register(Integration i) { - IntegrationType iType = i.getType(); - if ( !integrations.containsKey( iType ) ) { - integrations.put(iType, new ArrayList<>()); - } - - // If integration is already stored, remove the older one. Check on keyName: - List regIntegrations = integrations.get(iType); - for ( int x = 0; x < regIntegrations.size(); x++ ) { - if ( i.getKeyName().equals( regIntegrations.get(x).getKeyName() ) ) { - regIntegrations.remove( x ); - break; - } - } - integrations.get(iType).add(i); + IntegrationType iType = i.getType(); + if ( !integrations.containsKey( iType ) ) { + integrations.put(iType, new ArrayList<>()); + } + + // If integration is already stored, remove the older one. Check on keyName: + List regIntegrations = integrations.get(iType); + for ( int x = 0; x < regIntegrations.size(); x++ ) { + if ( i.getKeyName().equals( regIntegrations.get(x).getKeyName() ) ) { + regIntegrations.remove( x ); + break; + } + } + integrations.get(iType).add(i); } public PermissionIntegration getPermission() { - return (PermissionIntegration) getForType(IntegrationType.PERMISSION) - .orElse( null ); + return (PermissionIntegration) getForType(IntegrationType.PERMISSION) + .orElse( null ); } public EconomyIntegration getEconomy() { - return (EconomyIntegration) getForType(IntegrationType.ECONOMY) - .orElse( null ); + return (EconomyIntegration) getForType(IntegrationType.ECONOMY) + .orElse( null ); } public EconomyCurrencyIntegration getEconomyForCurrency(String currency) { - EconomyCurrencyIntegration results = null; - + EconomyCurrencyIntegration results = null; + if(integrations.containsKey(IntegrationType.ECONOMY)) { List econs = getAllForType(IntegrationType.ECONOMY); @@ -129,34 +129,16 @@ public EconomyCurrencyIntegration getEconomyForCurrency(String currency) { public CustomBlockIntegration getCustomBlockIntegration( PrisonBlockType blockType ) { - CustomBlockIntegration results = null; - - for ( CustomBlockIntegration customBlock : getCustomBlockIntegrations() ) - { - - if ( customBlock.getBlockType() == blockType ) { - results = customBlock; - break; - } + CustomBlockIntegration results = null; + + for ( CustomBlockIntegration customBlock : getCustomBlockIntegrations() ) { + + if ( customBlock.getBlockType() == blockType ) { + results = customBlock; + break; + } } -// if(integrations.containsKey(IntegrationType.CUSTOMBLOCK)) { -// -// List cbIntegrations = getAllForType(IntegrationType.CUSTOMBLOCK); -// -// for ( Integration cbIntegration : cbIntegrations ) { -// if ( cbIntegration.hasIntegrated() && cbIntegration instanceof CustomBlockIntegration ) { -// -// CustomBlockIntegration customBlock = (CustomBlockIntegration) cbIntegration; -// -// if ( customBlock.getBlockType() == blockType ) { -// results = customBlock; -// break; -// } -// } -// } -// } - return results; } @@ -186,38 +168,38 @@ public List getCustomBlockIntegrations() public String getIntegrationDetails( IntegrationType integrationType ) { - StringBuilder sb = new StringBuilder(); - Set keys = integrations.keySet(); - - for ( IntegrationType key : keys ) { - if ( key == integrationType ) { - sb.append( key.name() ); - sb.append( ": [" ); - - StringBuilder sb2 = new StringBuilder(); - List integrates = integrations.get( key ); - for ( Integration i : integrates ) { - if ( sb2.length() > 0 ) { - sb2.append( ", " ); - } - sb2.append( i.getDisplayName() ); - sb2.append( " (registered=" ); - sb2.append( i.isRegistered() ); - sb2.append( ", integrated=" ); - sb2.append( i.hasIntegrated() ); - sb2.append( ")" ); - if ( i.getDebugInfo() != null && i.getDebugInfo().trim().length() > 0 ) { - sb2.append( " Debug: {" ); - sb2.append( i.getDebugInfo() ); - sb2.append( "}" ); - } - } - - sb.append( sb2 ); - sb.append( "] " ); - } + StringBuilder sb = new StringBuilder(); + Set keys = integrations.keySet(); + + for ( IntegrationType key : keys ) { + if ( key == integrationType ) { + sb.append( key.name() ); + sb.append( ": [" ); + + StringBuilder sb2 = new StringBuilder(); + List integrates = integrations.get( key ); + for ( Integration i : integrates ) { + if ( sb2.length() > 0 ) { + sb2.append( ", " ); + } + sb2.append( i.getDisplayName() ); + sb2.append( " (registered=" ); + sb2.append( i.isRegistered() ); + sb2.append( ", integrated=" ); + sb2.append( i.hasIntegrated() ); + sb2.append( ")" ); + if ( i.getDebugInfo() != null && i.getDebugInfo().trim().length() > 0 ) { + sb2.append( " Debug: {" ); + sb2.append( i.getDebugInfo() ); + sb2.append( "}" ); + } + } + + sb.append( sb2 ); + sb.append( "] " ); + } } - return sb.toString(); + return sb.toString(); } /** @@ -233,26 +215,25 @@ public String getIntegrationDetails( IntegrationType integrationType ) { * @return */ public List getIntegrationComponents(boolean isBasic) { - List results = new ArrayList<>(); + List results = new ArrayList<>(); for ( IntegrationType integrationType : IntegrationType.values() ) { - if ( integrationType == IntegrationType.WORLDGUARD ) { - // Skip this integration type: - continue; + if ( integrationType == IntegrationType.WORLDGUARD ) { + // Skip this integration type: + continue; } boolean activeIntegration = false; - results.add( new TextComponent( String.format( "&7Integration Type: &3%s", integrationType.name() ) )); + results.add( new TextComponent( String.format( "&7Integration Type: &3%s", integrationType.name() ) )); - // Generates the placeholder list for the /prison version command, printing - // two placeholders per line. + // Generates the placeholder list for the /prison version command, printing + // two placeholders per line. if ( integrationType == IntegrationType.PLACEHOLDER ) { results.add( new TextComponent( ". . &7To list all or search for placeholders see: " + "&a/prison placeholders") ); -// getPlaceholderTemplateList( results ); } List plugins = getAllForType( integrationType ); @@ -320,7 +301,7 @@ else if ( plugins == null || plugins.size() == 0 ) { } } - return results; + return results; } /** @@ -329,33 +310,12 @@ else if ( plugins == null || plugins.size() == 0 ) { */ public void getPlaceholderTemplateList( List results ) { - //results.add( new TextComponent( " &7Available PlaceHolders: " )); List placeholders = PrisonPlaceHolders.getAllChatList(true); -// StringBuilder sb = new StringBuilder(); for ( String placeholder : placeholders ) { results.add( new TextComponent( " " + placeholder )); -// if ( sb.length() == 0) { -// sb.append( " " ); -// sb.append( placeholder ); -// } -// else if ( (sb.length() + placeholder.length()) > 90) { -// // will be too long combined so write existing sb then start over: -// results.add( new TextComponent( sb.toString() )); -// sb.setLength( 0 ); -// -// sb.append( " " ); -// sb.append( placeholder ); -// } else { -// sb.append( placeholder ); -// results.add( new TextComponent( sb.toString() )); -// sb.setLength( 0 ); -// } } -// if ( sb.length() > 0 ) { -// results.add( new TextComponent( sb.toString() )); -// } } public List getDeferredIntegrations() { @@ -381,30 +341,19 @@ public void register( Integration integration, boolean isRegistered, String vers if ( integration.hasIntegrated() ) { register(integration ); } -// else { -// boolean deferredRemoved = getDeferredIntegrations().remove( integration ); -// -// Output.get().logWarn( -// String.format( "Warning: An integration that is registered with bukkit " + -// "failed to integrate: %s %s %s[%s]", -// integration.getKeyName(), integration.getVersion(), -// ( deferredRemoved ? "(Deferred Processing Removed) " : "" ), -// (integration.getDebugInfo() == null ? -// "no debug info" : integration.getDebugInfo()) )); -// } } catch ( Exception e ) { - boolean deferredRemoved = getDeferredIntegrations().remove( integration ); - - removeIntegration( integration ); - - Output.get().logWarn( - String.format( "Warning: An integration caused an error while loading. " + - "Disabling the integration to protect Prison: %s %s %s[%s]", - integration.getKeyName(), integration.getVersion(), - ( deferredRemoved ? "(Deferred Processing Removed) " : "" ), - (integration.getDebugInfo() == null ? - "no debug info" : integration.getDebugInfo()) )); + boolean deferredRemoved = getDeferredIntegrations().remove( integration ); + + removeIntegration( integration ); + + Output.get().logWarn( + String.format( "Warning: An integration caused an error while loading. " + + "Disabling the integration to protect Prison: %s %s %s[%s]", + integration.getKeyName(), integration.getVersion(), + ( deferredRemoved ? "(Deferred Processing Removed) " : "" ), + (integration.getDebugInfo() == null ? + "no debug info" : integration.getDebugInfo()) )); } diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/ArmorStand.java b/prison-core/src/main/java/tech/mcprison/prison/internal/ArmorStand.java index ec741f0ed..697767f4d 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/ArmorStand.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/ArmorStand.java @@ -3,12 +3,6 @@ public interface ArmorStand extends Entity { - - //public ArmorStand spawn(Location location); - -// public void setupArmorStand(String itemType); -// public void setupArmorStand( ItemStack item ); - public boolean isVisible(); public void setVisible( boolean visible ); diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/CommandSender.java b/prison-core/src/main/java/tech/mcprison/prison/internal/CommandSender.java index 512401118..1780ff33b 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/CommandSender.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/CommandSender.java @@ -31,13 +31,6 @@ public interface CommandSender extends PlayerPermissions { -// /** -// * Returns the UUID for CommandSender if they are a bukkit Player. -// * -// * @return -// */ -// public UUID getUUID(); - /** * Returns the name of the command sender. */ @@ -89,18 +82,6 @@ public interface CommandSender public void sendRaw(String json); -// public boolean isOp(); -// -// public void recalculatePermissions(); -// -// /** -// * Returns true if the command sender has access to the permission specified. -// * -// * @param perm The permission to check. -// */ -// boolean hasPermission(String perm); - - public boolean isPlayer(); public List getSellAllMultiplierListings(); diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/Entity.java b/prison-core/src/main/java/tech/mcprison/prison/internal/Entity.java index a0333c60d..d770d637f 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/Entity.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/Entity.java @@ -10,7 +10,6 @@ public interface Entity extends CommandSender { - public String getNbtString( String key ); public void setNbtString( String key, String value ); diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/EulerAngle.java b/prison-core/src/main/java/tech/mcprison/prison/internal/EulerAngle.java index e974096fe..2f94f4270 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/EulerAngle.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/EulerAngle.java @@ -75,8 +75,6 @@ public EulerAngle rotateAroundAxisY( double angle ) { setY( ea.getY() ); setZ( ea.getZ() ); -// Output.get().logInfo( toString() + " angle: " + angle ); - return this; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/ItemStack.java b/prison-core/src/main/java/tech/mcprison/prison/internal/ItemStack.java index 58108b602..4d105e035 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/ItemStack.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/ItemStack.java @@ -39,24 +39,22 @@ public class ItemStack { private int amount; private PrisonBlock material; private List lore; -// private Map enchantments; public static final ItemStack SELECTION_WAND; static { - SELECTION_WAND = new ItemStack( 1, PrisonBlock.SELECTION_WAND, - "&7Corner 1 - Left click", - "&7Corner 2 - Right click"); + SELECTION_WAND = new ItemStack( 1, PrisonBlock.SELECTION_WAND, + "&7Corner 1 - Left click", + "&7Corner 2 - Right click"); } /** * Do not use this constructor, it is for unit testing. */ protected ItemStack() { - super(); - - this.lore = new ArrayList<>(); -// this.enchantments = new HashMap<>(); + super(); + + this.lore = new ArrayList<>(); } public ItemStack(String displayName, int amount, PrisonBlock material, String... lore) { @@ -69,7 +67,6 @@ public ItemStack(String displayName, int amount, PrisonBlock material, String... this.material.setDisplayName( displayName.trim() ); } -// this.enchantments = new HashMap<>(); } public ItemStack(int amount, PrisonBlock material, String... lore) { @@ -78,18 +75,18 @@ public ItemStack(int amount, PrisonBlock material, String... lore) { this.lore = new ArrayList<>(Arrays.asList(lore)); if ( material.getDisplayName() != null && material.getDisplayName().trim().length() > 0 ) { - setDisplayName( material.getDisplayName() ); + setDisplayName( material.getDisplayName() ); } } public ItemStack( ItemStack iStack ) { - this.displayName = iStack.getDisplayName(); - this.amount = iStack.getAmount(); - this.material = iStack.getMaterial().clone(); - this.lore = new ArrayList<>( iStack.getLore() ); + this.displayName = iStack.getDisplayName(); + this.amount = iStack.getAmount(); + this.material = iStack.getMaterial().clone(); + this.lore = new ArrayList<>( iStack.getLore() ); if ( displayName != null && displayName.trim().length() > 0 ) { - this.material.setDisplayName( displayName.trim() ); + this.material.setDisplayName( displayName.trim() ); } } @@ -97,11 +94,11 @@ public ItemStack( ItemStack iStack ) { * Returns the name of the item stack, derived from its BlockType name. */ public String getName() { - String name = (material != null ? - material.getBlockName() : - ( getDisplayName() != null ? - getDisplayName() : - "none")); + String name = (material != null ? + material.getBlockName() : + ( getDisplayName() != null ? + getDisplayName() : + "none")); return StringUtils.capitalize(name.replaceAll("_", " ").toLowerCase()); } @@ -130,11 +127,11 @@ public void setAmount( int amount ) { */ public PrisonBlock getMaterial() { - if ( getDisplayName() != null && getDisplayName().trim().length() > 0 && - material.getDisplayName() == null || - material.getDisplayName() != null && material.getDisplayName().trim().length() == 0 ) { - material.setDisplayName( getDisplayName() ); - } + if ( getDisplayName() != null && getDisplayName().trim().length() > 0 && + material.getDisplayName() == null || + material.getDisplayName() != null && material.getDisplayName().trim().length() == 0 ) { + material.setDisplayName( getDisplayName() ); + } return material; } @@ -149,7 +146,7 @@ public void setMaterial( PrisonBlock material ) { * @return */ public PrisonBlock getPrisonBlock() { - return getMaterial(); + return getMaterial(); } public List getLore() { @@ -159,23 +156,9 @@ public void setLore( List lore ) { this.lore = lore; } -// public Map getEnchantments() { -// return enchantments; -// } -// -// public void addEnchantment(Object enchantment, int level) { -// enchantments.put(enchantment, level); -// } -// -// public boolean hasEnchantments() { -// return !enchantments.isEmpty(); -// } -// -// public boolean hasEnchantment(int enchantment) { -// return enchantments.containsKey(enchantment); -// } - - @Override public boolean equals(Object o) { + + @Override + public boolean equals(Object o) { if (this == o) { return true; } @@ -194,16 +177,17 @@ public void setLore( List lore ) { material.compareTo( stack.material ) == 0; } - @Override public int hashCode() { + @Override + public int hashCode() { int result = amount; result = 31 * result + material.hashCode(); return result; } - @Override public String toString() { + @Override + public String toString() { return "ItemStack{" + "displayName='" + displayName + '\'' + ", amount=" + amount + ", material=" + material + ", lore=" + lore + "}"; - //", enchantments=" + enchantments + '}'; } } diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/World.java b/prison-core/src/main/java/tech/mcprison/prison/internal/World.java index 8bcfc85ad..c37391c11 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/World.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/World.java @@ -82,8 +82,6 @@ public void setBlocksSynchronously( List tBlocks, -// public Entity spawnEntity(EntityType entityType); - public Entity spawnEntity( Location loc, EntityType entityType); 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 677eb1717..0cc80727f 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 @@ -46,25 +46,10 @@ public interface Block { */ public Block getRelative(BlockFace face); -// /** -// * Returns the type of this block. -// * -// * @return The {@link BlockType}. -// */ -// BlockType getType(); - public PrisonBlock getPrisonBlock(); -// /** -// * Sets the block to a different type. -// * -// * @param type The new {@link BlockType}. -// */ -// void setType(BlockType type); - - public void setPrisonBlock( PrisonBlock prisonBlock ); /** diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/block/BlockFace.java b/prison-core/src/main/java/tech/mcprison/prison/internal/block/BlockFace.java index cd71f48fe..f54ae67f4 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/block/BlockFace.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/block/BlockFace.java @@ -33,21 +33,21 @@ public BlockFace getOppositeFace() { case NORTH: return SOUTH; case SOUTH: - return NORTH; + return NORTH; case EAST: - return WEST; + return WEST; case WEST: - return EAST; + return EAST; case TOP: - return BOTTOM; + return BOTTOM; case BOTTOM: - return TOP; + return TOP; case UP: - return DOWN; + return DOWN; case DOWN: - return UP; + return UP; default: - return NORTH; + return NORTH; } } diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/block/BlockState.java b/prison-core/src/main/java/tech/mcprison/prison/internal/block/BlockState.java index 480222cdc..837f231b2 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/block/BlockState.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/block/BlockState.java @@ -19,14 +19,16 @@ package tech.mcprison.prison.internal.block; /** - * Represents a captured state of a block, which will not change + *

    Represents a captured state of a block, which will not change * automatically. - *

    - * Unlike {@link Block }, which only one object can exist per coordinate, {@link BlockState} + *

    + * + *

    Unlike {@link Block }, which only one object can exist per coordinate, {@link BlockState} * can exist multiple times for any given Block. Note that another plugin may * change the state of the block and you will not know, or they may change the * block to another type entirely, causing your BlockState to become invalid. - * + *

    + * * @author Faizaan A. Datoo * @since API 1.0 */ diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/block/Door.java b/prison-core/src/main/java/tech/mcprison/prison/internal/block/Door.java index 3b157900b..4eef48e1a 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/block/Door.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/block/Door.java @@ -54,16 +54,11 @@ default void toggleOpen() { */ default boolean isWoodenDoor() { - String blockName = getBlock().getPrisonBlock().getBlockName(); - - return blockName != null && - blockName.matches( "ACACIA_DOOR|BIRCH_DOOR|CRIMSON_DOOR|OAK_DOOR|DARK_OAK_DOOR|" + - "JUNGLE_DOOR|SPRUCE_DOOR|WARPED_DOOR" ); - -// BlockType block = getBlock().getType(); -// return block == BlockType.ACACIA_DOOR_BLOCK || block == BlockType.BIRCH_DOOR_BLOCK -// || block == BlockType.DARK_OAK_DOOR_BLOCK || block == BlockType.JUNGLE_DOOR_BLOCK -// || block == BlockType.OAK_DOOR_BLOCK || block == BlockType.SPRUCE_DOOR_BLOCK; + String blockName = getBlock().getPrisonBlock().getBlockName(); + + return blockName != null && + blockName.matches( "ACACIA_DOOR|BIRCH_DOOR|CRIMSON_DOOR|OAK_DOOR|DARK_OAK_DOOR|" + + "JUNGLE_DOOR|SPRUCE_DOOR|WARPED_DOOR" ); } } diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/block/MineTargetBlockKey.java b/prison-core/src/main/java/tech/mcprison/prison/internal/block/MineTargetBlockKey.java index ff4f56922..179c6ccad 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/block/MineTargetBlockKey.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/block/MineTargetBlockKey.java @@ -1,7 +1,6 @@ package tech.mcprison.prison.internal.block; import tech.mcprison.prison.internal.World; -import tech.mcprison.prison.output.Output; import tech.mcprison.prison.util.Location; public class MineTargetBlockKey @@ -21,7 +20,6 @@ public MineTargetBlockKey() { this.y = 0; this.z = 0; -// Output.get().logInfo( "MineTargetBlockKey: World and coordinates need to be set." ); } public MineTargetBlockKey( World world, int x, int y, int z ) { @@ -122,12 +120,7 @@ public int hashCode() hash += x * 13 + y * 37 + z * 17; -// return super.hashCode(); - return hash; } - - - } 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 f812ed5fd..7fefc4925 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 @@ -18,7 +18,6 @@ public class MineTargetPrisonBlock private boolean mined = false; private Block minedBlock; -// private boolean blockEvent = false; private boolean counted = false; private boolean ignoreAllBlockEvents = false; @@ -123,7 +122,6 @@ public String getBlockCoordinates() { StringBuilder sb = new StringBuilder(); sb.append( getPrisonBlock().getBlockName() ); -// sb.append( getPrisonBlock().getBlockNameFormal() ); if ( getLocation() != null ) { sb.append( "::" ); @@ -180,13 +178,6 @@ public void setMined( boolean mined ) { this.mined = mined; } -// public boolean isBlockEvent() { -// return blockEvent; -// } -// public void setBlockEvent( boolean blockEvent ) { -// this.blockEvent = blockEvent; -// } - public boolean isCounted() { return counted; } 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 b66242977..632773694 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 @@ -31,13 +31,8 @@ public class PrisonBlock public static PrisonBlock IGNORE; public static PrisonBlock NULL_BLOCK; -// private PrisonBlockType blockType; private boolean useBlockTypeAsPrefix = false; -// private String blockName; - -// private double chance; - private boolean valid = true; private boolean block = true; private boolean sellallOnly = false; @@ -133,11 +128,6 @@ public PrisonBlock( String blockName, boolean block ) { public PrisonBlock( PrisonBlockType blockType, String blockName, double chance, long blockCountTotal ) { super( blockType, blockName, chance, blockCountTotal ); -// this.blockType = blockType; - -// this.blockName = blockName.toLowerCase(); -// this.chance = chance; - } public PrisonBlock( PrisonBlock clonable ) { @@ -170,34 +160,14 @@ public String toString() { sb.append( getBlockNameSearch() ); -// sb.append( getBlockType().name() ) -// .append( ":" ) -// .append( getBlockName() ); - if ( getChance() > 0 ) { sb.append( " " ) .append( Double.toString( getChance()) ); } return sb.toString(); - -// return getBlockType().name() + ": " + getBlockName() + -// ( getChance() > 0 ? " " + Double.toString( getChance()) : ""); } -// public PrisonBlockType getBlockType() { -// return blockType; -// } -// public void setBlockType( PrisonBlockType blockType ) { -// this.blockType = blockType; -// } - -// public String getBlockName() { -// return blockName; -// } -// public void setBlockName( String blockName ) { -// this.blockName = blockName; -// } /** *

    This function always prefixes the block name with the BlockType. @@ -324,13 +294,6 @@ public void setUseBlockTypeAsPrefix( boolean useBlockTypeAsPrefix ) { this.useBlockTypeAsPrefix = useBlockTypeAsPrefix; } -// public double getChance() { -// return chance; -// } -// public void setChance( double chance ) { -// this.chance = chance; -// } - public boolean isValid() { return valid; } @@ -476,9 +439,6 @@ public int compareTo( PrisonBlock block ) if ( results == 0 && getBlockNameSearch() != null && block.getBlockNameSearch() != null ) { results = getBlockNameSearch().compareToIgnoreCase( block.getBlockNameSearch() ); } -// if ( results == 0 && getDisplayName() != null && block.getDisplayName() != null ) { -// results = getDisplayName().compareToIgnoreCase( block.getDisplayName() ); -// } } } @@ -570,16 +530,6 @@ public void setBlockFace( BlockFace blockFace ) { (( PrisonBlock ) relativeBlock).setPrisonBlock( this ); -// PrisonBlock cloned = this.clone(); -// -// (( PrisonBlock ) relativeBlock).getLocation().setBlockAsync( cloned ); -// -// PrisonBlockType blockType = getBlockType(); -// -// // Set that block with this block's type: -// (( PrisonBlock ) relativeBlock).setBlockType( blockType ); -// (( PrisonBlock ) relativeBlock).setBlockName( getBlockName() ); - } } diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/block/PrisonBlockStatusData.java b/prison-core/src/main/java/tech/mcprison/prison/internal/block/PrisonBlockStatusData.java index 199f0f738..74df1befa 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/block/PrisonBlockStatusData.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/block/PrisonBlockStatusData.java @@ -46,8 +46,6 @@ public abstract class PrisonBlockStatusData { private boolean preventDrops = false; -// private transient boolean includeInLayerCalculations; - private transient String altAlias; private transient String altColorCode; @@ -100,8 +98,6 @@ public PrisonBlockStatusData( this.preventDrops = false; - -// this.includeInLayerCalculations = true; } @@ -187,13 +183,6 @@ public static PrisonBlock parseFromSaveFileFormat( String blockString ) { results.parseFromSaveFileFormatStats( blockString ); } -// else { -// if ( blockTypeName.equalsIgnoreCase( "gold_ore" ) ) { -// Output.get().logInfo( "### parseFromSaveFile: no results!? [" + -// String.join( ", ", split ) + "]" -// ); -// } -// } } return results; @@ -208,7 +197,6 @@ public void parseFromSaveFileFormatStats( String blockString ) { String[] split = blockString.split("-"); if ( split != null && split.length > 0 ) { -// String blockTypeName = split[0]; // The new way to get the PrisonBlocks: double chance = split.length > 1 ? Double.parseDouble(split[1]) : 0; @@ -227,12 +215,6 @@ public void parseFromSaveFileFormatStats( String blockString ) { setConstraintExcludeBottomLayers( constraintExcludeBottomLayers ); setPreventDrops(preventDrops); -// if ( blockTypeName.equalsIgnoreCase( "gold_ore" ) ) { -// Output.get().logInfo( "### parseFromSaveFile: [" + -// String.join( ", ", split ) + "] [" + -// block.toSaveFileFormat() + "]" -// ); -// } } } @@ -264,13 +246,11 @@ public String toPlaceholderString() { String percent = fFmt.format(getChance()); -// String spawned = dFmt.format( getResetBlockCount() ); String remaining = dFmt.format( getBlockPlacedCount() - getBlockCountUnsaved() ); String total = PlaceholdersUtil.formattedKmbtSISize( 1.0d * getBlockCountTotal(), dFmt, "" ); sb.append( getBlockName() ).append( " (" ) .append( percent ).append( " pct) " ) -// .append( spawned ) .append( " r: " ).append( remaining ) .append( " T: " ) .append( total ) ; @@ -589,14 +569,6 @@ public void setPreventDrops(boolean preventDrops) { } - -// public boolean isIncludeInLayerCalculations() { -// return includeInLayerCalculations; -// } -// public void setIncludeInLayerCalculations(boolean includeInLayerCalculations) { -// this.includeInLayerCalculations = includeInLayerCalculations; -// } - /** *

    This is only used when calculating which blocks should be placed diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/block/PrisonBlockTypes.java b/prison-core/src/main/java/tech/mcprison/prison/internal/block/PrisonBlockTypes.java index ba5cbfff2..b6feae6e7 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/block/PrisonBlockTypes.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/block/PrisonBlockTypes.java @@ -58,7 +58,6 @@ private void initializeBlockTypes() { // Add in prison's internal block types here: getBlockTypes().add( PrisonBlock.IGNORE ); -// getBlockTypes().add( PrisonBlock.NULL_BLOCK ); // Map all available blocks to the blockTypesByName map: @@ -98,13 +97,8 @@ public void addBlockTypes( List blockTypes ) { getBlockTypesByName().put( blockKey, pb ); -// getBlockTypesByName().put( pb.getBlockName().toLowerCase(), pb ); getBlockTypes().add( pb ); -// if ( pb.getBlockType() != PrisonBlockType.minecraft || pb.getDisplayName() != null ) { -// -// getBlockTypesByName().put( blockKey, pb ); -// } } } diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/events/block/BlockBreakEvent.java b/prison-core/src/main/java/tech/mcprison/prison/internal/events/block/BlockBreakEvent.java index 2a1fe9915..bc1c9be05 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/events/block/BlockBreakEvent.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/events/block/BlockBreakEvent.java @@ -42,9 +42,6 @@ public class BlockBreakEvent public BlockBreakEvent( PrisonBlock block, Location blockLocation, Player player) { this(block,blockLocation,player,0); } -// public BlockBreakEvent(BlockType block, Location blockLocation, Player player) { -// this(block,blockLocation,player,0); -// } public BlockBreakEvent( PrisonBlock block, Location blockLocation, Player player, int xp ) { this.block = block; @@ -53,11 +50,13 @@ public BlockBreakEvent( PrisonBlock block, Location blockLocation, Player player this.exp = xp; } - @Override public boolean isCanceled() { + @Override + public boolean isCanceled() { return canceled; } - @Override public void setCanceled(boolean canceled) { + @Override + public void setCanceled(boolean canceled) { this.canceled = canceled; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/events/block/BlockPlaceEvent.java b/prison-core/src/main/java/tech/mcprison/prison/internal/events/block/BlockPlaceEvent.java index c041b2cfa..6f5258534 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/events/block/BlockPlaceEvent.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/events/block/BlockPlaceEvent.java @@ -40,17 +40,14 @@ public BlockPlaceEvent( PrisonBlock block, Location blockLocation, Player player this.blockLocation = blockLocation; this.player = player; } -// public BlockPlaceEvent(BlockType block, Location blockLocation, Player player) { -// this.block = block; -// this.blockLocation = blockLocation; -// this.player = player; -// } - @Override public boolean isCanceled() { + @Override + public boolean isCanceled() { return canceled; } - @Override public void setCanceled(boolean canceled) { + @Override + public void setCanceled(boolean canceled) { this.canceled = canceled; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/BrewEvent.java b/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/BrewEvent.java index 7aab8134f..a5327053b 100755 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/BrewEvent.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/BrewEvent.java @@ -23,8 +23,6 @@ import tech.mcprison.prison.internal.inventory.BrewerInventory; /** - * Currently undocumented. - * * @author DMP9 */ public class BrewEvent implements Cancelable { diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/CraftItemEvent.java b/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/CraftItemEvent.java index b0b2a3504..11b5eb540 100755 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/CraftItemEvent.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/CraftItemEvent.java @@ -24,8 +24,6 @@ import tech.mcprison.prison.internal.inventory.Viewable; /** - * Currently undocumented. - * * @author DMP9 */ public class CraftItemEvent extends InventoryClickEvent { diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/FurnaceBurnEvent.java b/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/FurnaceBurnEvent.java index 6b33c8231..eff044725 100755 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/FurnaceBurnEvent.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/FurnaceBurnEvent.java @@ -23,8 +23,6 @@ import tech.mcprison.prison.internal.events.Cancelable; /** - * Currently undocumented. - * * @author DMP9 */ public class FurnaceBurnEvent implements Cancelable { diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/FurnaceExtractEvent.java b/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/FurnaceExtractEvent.java index cd1f29ec3..2e82cd36c 100755 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/FurnaceExtractEvent.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/FurnaceExtractEvent.java @@ -22,8 +22,6 @@ import tech.mcprison.prison.internal.block.PrisonBlock; /** - * Currently undocumented. - * * @author DMP9 */ public class FurnaceExtractEvent { @@ -32,9 +30,6 @@ public class FurnaceExtractEvent { private int expToDrop; private PrisonBlock prisonBlock; -// private Block block; -// private BlockType blockType; - private PrisonBlock blockType; private Player player; diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/FurnaceSmeltEvent.java b/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/FurnaceSmeltEvent.java index 999875c01..ce15e7097 100755 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/FurnaceSmeltEvent.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/FurnaceSmeltEvent.java @@ -23,8 +23,6 @@ import tech.mcprison.prison.internal.events.Cancelable; /** - * Currently undocumented. - * * @author DMP9 */ public class FurnaceSmeltEvent implements Cancelable { diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/InventoryClickEvent.java b/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/InventoryClickEvent.java index 066e05fc7..3884bed8a 100755 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/InventoryClickEvent.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/InventoryClickEvent.java @@ -23,8 +23,6 @@ import tech.mcprison.prison.internal.inventory.Viewable; /** - * Currently undocumented. - * * @author DMP9 */ public class InventoryClickEvent extends InventoryInteractEvent { diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/InventoryCloseEvent.java b/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/InventoryCloseEvent.java index 23dfc5ba2..eb9fd58bc 100755 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/InventoryCloseEvent.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/InventoryCloseEvent.java @@ -22,8 +22,6 @@ import tech.mcprison.prison.internal.inventory.Viewable; /** - * Currently undocumented. - * * @author DMP9 */ public class InventoryCloseEvent extends InventoryEvent { diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/InventoryCreativeEvent.java b/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/InventoryCreativeEvent.java index ec2873ab7..74c75a417 100755 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/InventoryCreativeEvent.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/InventoryCreativeEvent.java @@ -23,8 +23,6 @@ import tech.mcprison.prison.internal.inventory.Viewable; /** - * Currently undocumented. - * * @author DMP9 */ public class InventoryCreativeEvent extends InventoryClickEvent { diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/InventoryDragEvent.java b/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/InventoryDragEvent.java index d18902205..c4cd2a899 100755 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/InventoryDragEvent.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/InventoryDragEvent.java @@ -26,8 +26,6 @@ import java.util.Set; /** - * Currently undocumented. - * * @author DMP9 */ public class InventoryDragEvent extends InventoryInteractEvent { diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/InventoryInteractEvent.java b/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/InventoryInteractEvent.java index fbabf137b..cb9d3ddae 100755 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/InventoryInteractEvent.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/InventoryInteractEvent.java @@ -23,8 +23,6 @@ import tech.mcprison.prison.internal.inventory.Viewable; /** - * Currently undocumented. - * * @author DMP9 */ public class InventoryInteractEvent extends InventoryEvent implements Cancelable { @@ -35,11 +33,13 @@ public InventoryInteractEvent(Viewable transaction) { super(transaction); } - @Override public boolean isCanceled() { + @Override + public boolean isCanceled() { return cancel; } - @Override public void setCanceled(boolean canceled) { + @Override + public void setCanceled(boolean canceled) { cancel = canceled; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/InventoryMoveItemEvent.java b/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/InventoryMoveItemEvent.java index 3682e7f13..3075660ab 100755 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/InventoryMoveItemEvent.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/InventoryMoveItemEvent.java @@ -23,8 +23,6 @@ import tech.mcprison.prison.internal.inventory.Inventory; /** - * Currently undocumented. - * * @author DMP9 */ public class InventoryMoveItemEvent implements Cancelable { diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/InventoryOpenEvent.java b/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/InventoryOpenEvent.java index bcedbd3b6..0953da08d 100755 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/InventoryOpenEvent.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/InventoryOpenEvent.java @@ -23,8 +23,6 @@ import tech.mcprison.prison.internal.inventory.Viewable; /** - * Currently undocumented. - * * @author DMP9 */ public class InventoryOpenEvent extends InventoryEvent implements Cancelable { diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/PrepareAnvilEvent.java b/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/PrepareAnvilEvent.java index 055cfa904..193407628 100755 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/PrepareAnvilEvent.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/PrepareAnvilEvent.java @@ -23,8 +23,6 @@ import tech.mcprison.prison.internal.inventory.Viewable; /** - * Currently undocumented. - * * @author DMP9 */ public class PrepareAnvilEvent extends InventoryEvent { diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/PrepareItemCraftEvent.java b/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/PrepareItemCraftEvent.java index 008830e64..559e7b4ef 100755 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/PrepareItemCraftEvent.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/events/inventory/PrepareItemCraftEvent.java @@ -23,8 +23,6 @@ import tech.mcprison.prison.internal.inventory.Viewable; /** - * Currently undocumented. - * * @author DMP9 */ public class PrepareItemCraftEvent extends InventoryEvent { From 726d787c98949ec02ef9932fafeeaba7a1488df9 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 7 Mar 2026 02:26:18 -0500 Subject: [PATCH 311/323] Prison Cleanup: prison-core: Removed obsolete and unneeded comments and fix indentation where needed. Fourth part. --- docs/changelog_v3.3.x.md | 3 + .../java/tech/mcprison/prison/Prison.java | 345 +-- .../java/tech/mcprison/prison/PrisonAPI.java | 18 +- .../tech/mcprison/prison/PrisonCommand.java | 2737 +++++++---------- .../prison/PrisonCommandMessages.java | 14 +- .../mcprison/prison/alerts/AlertCommands.java | 47 +- .../tech/mcprison/prison/alerts/Alerts.java | 18 +- .../prison/backpacks/BackpackCacheEvents.java | 8 +- .../BackpackCacheLoadPlayerTask.java | 2 +- .../backpacks/BackpackCachePlayerData.java | 7 - .../BackpackCacheSaveAllPlayersTask.java | 2 +- .../prison/backpacks/BackpackCacheStats.java | 2 +- .../prison/backpacks/BackpackCacheTask.java | 2 +- .../BackpackCacheUnloadPlayerTask.java | 2 +- .../BackpackConverterOldPrisonBackpacks.java | 1 - .../prison/backpacks/BackpackEnums.java | 2 +- .../prison/backpacks/PlayerBackpack.java | 1 - .../prison/backups/PrisonBackups.java | 8 - .../prison/backups/PrisonSystemSettings.java | 153 - .../prison/bombs/GeometricShapes.java | 43 - .../bombs/MineBombCooldownException.java | 3 - .../mcprison/prison/bombs/MineBombData.java | 16 - .../tech/mcprison/prison/bombs/MineBombs.java | 42 - .../prison/bombs/MineBombsConfigData.java | 22 - .../animations/BombAnimationOrbital.java | 4 - .../bombs/animations/BombAnimationsTask.java | 7 - .../mcprison/prison/cache/CoreCacheFiles.java | 220 -- .../mcprison/prison/cache/PlayerCache.java | 53 +- .../prison/cache/PlayerCacheEvents.java | 20 +- .../mcprison/prison/chat/FancyMessage.java | 16 +- .../mcprison/prison/chat/MessagePart.java | 4 +- .../prison/chat/TextualComponent.java | 39 +- 32 files changed, 1303 insertions(+), 2558 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 73facc9d9..41eea8107 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.19j 2026-03-06 +* **Prison Cleanup: prison-core: Removed obsolete and unneeded comments and fix indentation where needed.** Fourth part. + + * **Prison Cleanup: prison-core: Removed obsolete and unneeded comments and fix indentation where needed.** Third part. diff --git a/prison-core/src/main/java/tech/mcprison/prison/Prison.java b/prison-core/src/main/java/tech/mcprison/prison/Prison.java index 3c6fcd776..51601a7f4 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/Prison.java +++ b/prison-core/src/main/java/tech/mcprison/prison/Prison.java @@ -96,7 +96,6 @@ public class Prison private LocaleManager localeManager; private File moduleDataFolder; -// private ItemManager itemManager; private ErrorManager errorManager; private TroubleshootManager troubleshootManager; private IntegrationManager integrationManager; @@ -115,11 +114,11 @@ public class Prison private static boolean dfSymStatic = false; private Prison() { - super(); - - this.serverStartupTime = System.currentTimeMillis(); - - this.localeLoadInfo = new ArrayList<>(); + super(); + + this.serverStartupTime = System.currentTimeMillis(); + + this.localeLoadInfo = new ArrayList<>(); } /** @@ -136,24 +135,24 @@ public static Prison get() { } public DecimalFormat getDecimalFormat( String format ) { - DecimalFormat dFmt = new DecimalFormat( format, getDecimalFormatSymbols() ); - return dFmt; + DecimalFormat dFmt = new DecimalFormat( format, getDecimalFormatSymbols() ); + return dFmt; } public DecimalFormat getDecimalFormatInt() { - return getDecimalFormat("#,##0"); + return getDecimalFormat("#,##0"); } public DecimalFormat getDecimalFormatDouble() { - return getDecimalFormat("#,##0.000"); + return getDecimalFormat("#,##0.000"); } public static DecimalFormat getDecimalFormatStatic( String format ) { - DecimalFormat dFmt = new DecimalFormat( format, getDecimalFormatSymbolsStatic() ); + DecimalFormat dFmt = new DecimalFormat( format, getDecimalFormatSymbolsStatic() ); return dFmt; } public static DecimalFormat getDecimalFormatStaticInt() { - return getDecimalFormatStatic("#,##0"); + return getDecimalFormatStatic("#,##0"); } public static DecimalFormat getDecimalFormatStaticDouble() { - return getDecimalFormatStatic("#,##0.000"); + return getDecimalFormatStatic("#,##0.000"); } /** @@ -174,29 +173,29 @@ public static DecimalFormat getDecimalFormatStaticDouble() { * @return */ private DecimalFormatSymbols getDecimalFormatSymbols() { - if ( dfSym == null || dfSymStatic ) { - - String location = getPlatform().getConfigString( "number-format-location", "en_US" ); - String[] loc = location.split("_"); - - Locale locale = new Locale( - loc != null && loc.length >= 1 ? loc[0] : "en", - loc != null && loc.length >= 2 ? loc[1] : "US" ); - -// Locale locale = new Locale( "en", "US" ); - dfSym = new DecimalFormatSymbols( locale ); - dfSymStatic = false; - } - return dfSym; + if ( dfSym == null || dfSymStatic ) { + + String location = getPlatform().getConfigString( "number-format-location", "en_US" ); + String[] loc = location.split("_"); + + Locale locale = new Locale( + loc != null && loc.length >= 1 ? loc[0] : "en", + loc != null && loc.length >= 2 ? loc[1] : "US" ); + + // Locale locale = new Locale( "en", "US" ); + dfSym = new DecimalFormatSymbols( locale ); + dfSymStatic = false; + } + return dfSym; } private static DecimalFormatSymbols getDecimalFormatSymbolsStatic() { - if ( dfSym == null ) { - - Locale locale = new Locale( "en", "US" ); - dfSym = new DecimalFormatSymbols( locale ); - dfSymStatic = true; - } - return dfSym; + if ( dfSym == null ) { + + Locale locale = new Locale( "en", "US" ); + dfSym = new DecimalFormatSymbols( locale ); + dfSymStatic = true; + } + return dfSym; } /** @@ -211,16 +210,16 @@ private static DecimalFormatSymbols getDecimalFormatSymbolsStatic() { */ public LocaleManager getLocaleManager() { - if ( this.localeManager == null ) { - - synchronized ( this ) { - if ( this.localeManager == null ) { - - this.localeManager = new LocaleManager(this, "lang/core"); - } + if ( this.localeManager == null ) { + + synchronized ( this ) { + if ( this.localeManager == null ) { + + this.localeManager = new LocaleManager(this, "lang/core"); + } } - - } + + } return localeManager; } @@ -233,20 +232,20 @@ public LocaleManager getLocaleManager() { */ public File getModuleDataFolder() { - if ( moduleDataFolder == null ) { - if ( this.localeManager == null ) { - if ( moduleDataFolder == null ) { - - this.moduleDataFolder = Module.setupModuleDataFolder( "core" ); - - } - } - } + if ( moduleDataFolder == null ) { + if ( this.localeManager == null ) { + if ( moduleDataFolder == null ) { + + this.moduleDataFolder = Module.setupModuleDataFolder( "core" ); + + } + } + } return moduleDataFolder; } - + public void setupJUnitInstance( Platform platform ) { - this.platform = platform; + this.platform = platform; } @@ -259,11 +258,9 @@ public void setupJUnitInstance( Platform platform ) { * Note that modules should not call this method. This is solely for the implementations. */ public void init(Platform platform, String minecraftVersion ) { - //long startTime = System.currentTimeMillis(); - - - this.platform = platform; - this.minecraftVersion = minecraftVersion; + + this.platform = platform; + this.minecraftVersion = minecraftVersion; } @@ -277,10 +274,6 @@ public void init(Platform platform, String minecraftVersion ) { public boolean init( File dataFolder ) { long startTime = System.currentTimeMillis(); - -// this.platform = platform; -// this.minecraftVersion = minecraftVersion; - this.dataFolder = dataFolder; if (!initDataFolder()) { @@ -307,13 +300,12 @@ public boolean init( File dataFolder ) { Output.get().logInfo("Enabling and starting..."); - //getPrisonStatsUtil().checkDirectoryStructures( ); // Initialize various parts of the API. The magic happens here :) initManagers(); if (!initMetaDatabase()) { - Output.get().logInfo("&cFailure: &eInitializing the Prison Database!" ); - Output.get().logInfo("&e&k!=&d Prison Plugin Terminated! &e&k=!&7" ); + Output.get().logInfo("&cFailure: &eInitializing the Prison Database!" ); + Output.get().logInfo("&e&k!=&d Prison Plugin Terminated! &e&k=!&7" ); return false; } Alerts.getInstance(); // init alerts @@ -350,31 +342,31 @@ public boolean init( File dataFolder ) { private void sendBanner() { - ChatDisplay display = new ChatDisplay(""); - - display.addText(""); - display.addText("&6 _____ _ "); - display.addText("&6| __ \\ (_) "); - display.addText("&6| |__) | __ _ ___ ___ _ __ "); - display.addText("&6| ___/ '__| / __|/ _ \\| '_ \\"); - display.addText("&6| | | | | \\__ \\ (_) | | | |"); - display.addText("&6|_| |_| |_|___/\\___/|_| |_|"); - display.addText(""); - display.addText("&7Loading Prison version: &3%s", PrisonAPI.getPluginVersion()); - display.addText("&7Running on platform: &3%s", platform.getClass().getSimpleName()); - display.addText("&7Minecraft version: &3%s", getMinecraftVersion()); - // display.addText("&7Server runtime: %s", getServerRuntimeFormatted() ); - display.addText(""); - - displaySystemSettings( display ); - displaySystemTPS( display ); - - display.addText(""); - - - getPrisonStatsUtil().checkDirectoryStructures( display ); - - display.sendtoOutputLogInfo(); + ChatDisplay display = new ChatDisplay(""); + + display.addText(""); + display.addText("&6 _____ _ "); + display.addText("&6| __ \\ (_) "); + display.addText("&6| |__) | __ _ ___ ___ _ __ "); + display.addText("&6| ___/ '__| / __|/ _ \\| '_ \\"); + display.addText("&6| | | | | \\__ \\ (_) | | | |"); + display.addText("&6|_| |_| |_|___/\\___/|_| |_|"); + display.addText(""); + display.addText("&7Loading Prison version: &3%s", PrisonAPI.getPluginVersion()); + display.addText("&7Running on platform: &3%s", platform.getClass().getSimpleName()); + display.addText("&7Minecraft version: &3%s", getMinecraftVersion()); + // display.addText("&7Server runtime: %s", getServerRuntimeFormatted() ); + display.addText(""); + + displaySystemSettings( display ); + displaySystemTPS( display ); + + display.addText(""); + + + getPrisonStatsUtil().checkDirectoryStructures( display ); + + display.sendtoOutputLogInfo(); } public void displaySystemSettings( ChatDisplay display ) { @@ -498,28 +490,17 @@ public void displaySystemTPS( ChatDisplay display ) { String tpsHistory = prisonTPS.getLastFewTPS(); if ( tpsHistory.length() > 0 ) { - display.addText( "&7TPS History: %s", tpsHistory ); + display.addText( "&7TPS History: %s", tpsHistory ); } } public void getSystemTPS( LinkedHashMap fields ) { - //DecimalFormat iFmt = getDecimalFormatInt(); - PrisonTPSSingleton prisonTPS = Prison.get().getPrisonTPS(); - - fields.put( "tps", prisonTPS.getAverageTPSFormatted() ); - fields.put( "tpsMin", prisonTPS.getTPSMinFormatted() ); -// fields.put( "tpsMax", ( prisonTPS.getTpsMax() >= 100 ? ">" : "") + prisonTPS.getTPSMaxFormatted() ); - //fields.put( "tpsInterval", iFmt.format( PrisonTPS.SUBMIT_TICKS_INTERVAL ) ); - //fields.put( "tpsSamples", iFmt.format( prisonTPS.getTpsSamples() ) ); - - -// String tpsHistory = prisonTPS.getLastFewTPS(); -// if ( tpsHistory.length() > 0 ) { -// -// fields.put( "tpsHistory", prisonTPS.getLastFewTPS() ); -// } - + PrisonTPSSingleton prisonTPS = Prison.get().getPrisonTPS(); + + fields.put( "tps", prisonTPS.getAverageTPSFormatted() ); + fields.put( "tpsMin", prisonTPS.getTPSMinFormatted() ); + } private void getPrisonDiskSpaceUsage( ChatDisplay display, @@ -549,26 +530,22 @@ private void getPrisonDiskSpaceUsage( ChatDisplay display, public void getPrisonDiskSpaceUsage( LinkedHashMap fields ) { File prisonFolder = Prison.get().getDataFolder(); - PrisonDiskStats diskStats = new PrisonDiskStats(); - - // Increment folder count for prison's plugin folder: - diskStats.incrementFolderCount(); - - calculatePrisonDiskUsage( diskStats, prisonFolder ); - - DecimalFormat dFmt = getDecimalFormatDouble(); - DecimalFormat iFmt = getDecimalFormatInt(); - - String prisonFileCount = iFmt.format( diskStats.getFileCount() ); -// String prisonFolderCount = iFmt.format( diskStats.getFolderCount() ); - //String prisonOtherObjectCount = iFmt.format( diskStats.getOtherObjectCount() ); - String prisonStorageSize = PlaceholdersUtil.formattedIPrefixBinarySize( - diskStats.getStorageSize(), dFmt, " " ); - - fields.put( "prisonStorageFiles", prisonFileCount ); -// fields.put( "prisonStorageFolders", prisonFolderCount ); - fields.put( "prisonStorageSize", prisonStorageSize ); - //fields.put( "prisonStorageObjects", prisonOtherObjectCount ); + PrisonDiskStats diskStats = new PrisonDiskStats(); + + // Increment folder count for prison's plugin folder: + diskStats.incrementFolderCount(); + + calculatePrisonDiskUsage( diskStats, prisonFolder ); + + DecimalFormat dFmt = getDecimalFormatDouble(); + DecimalFormat iFmt = getDecimalFormatInt(); + + String prisonFileCount = iFmt.format( diskStats.getFileCount() ); + String prisonStorageSize = PlaceholdersUtil.formattedIPrefixBinarySize( + diskStats.getStorageSize(), dFmt, " " ); + + fields.put( "prisonStorageFiles", prisonFileCount ); + fields.put( "prisonStorageSize", prisonStorageSize ); } @@ -596,18 +573,18 @@ else if ( file.isFile() ) { public class PrisonDiskStats { - long fileCount = 0L; - long folderCount = 0L; - long otherObjectCount = 0L; - long storageSize = 0L; + long fileCount = 0L; + long folderCount = 0L; + long otherObjectCount = 0L; + long storageSize = 0L; - public PrisonDiskStats() { - super(); - } - - public void incrementFileCount() { - fileCount++; - } + public PrisonDiskStats() { + super(); + } + + public void incrementFileCount() { + fileCount++; + } public long getFileCount() { return fileCount; } @@ -649,7 +626,6 @@ public void setStorageSize( long storageSize ) { private boolean initDataFolder() { // Creates the /Prison directory, for core configuration. -// this.dataFolder = getPlatform().getPluginDirectory(); return this.dataFolder.exists() || this.dataFolder.mkdirs(); } @@ -685,15 +661,6 @@ private void initManagers() { this.integrationManager = new IntegrationManager(); this.placeholderManager = new PlaceholderManager(); - -// try { -// this.itemManager = new ItemManager(); -// } catch (Exception e) { -// this.errorManager.throwError(new Error( -// "Error while loading items.csv. Try running /prison troubleshoot item_scan.") -// .appendStackTrace("when loading items.csv", e)); -// Output.get().logError("Try running /prison troubleshoot item_scan."); -// } } private void registerInbuiltTroubleshooters() { @@ -702,15 +669,10 @@ private void registerInbuiltTroubleshooters() { private void scheduleAlertNagger() { - // Nag the users with the correct perms 5 mins after server starts, and every - // hour thereafter. - Alerts.getInstance().submitShowAlertsTask(); + // Nag the users with the correct perms 5 mins after server starts, and every + // hour thereafter. + Alerts.getInstance().submitShowAlertsTask(); -// // Nag the user with alerts every 5 minutes -// PrisonAPI.getScheduler().runTaskTimerAsync(() -> PrisonAPI.getOnlinePlayers().stream() -// .filter(player -> player.hasPermission("prison.admin") -// && Alerts.getInstance().getAlertsFor(player.getUUID()).size() > 0) -// .forEach(Alerts.getInstance()::showAlerts), 60 * 20 * 5, 60 * 20 * 5); } // End initialization steps @@ -723,7 +685,6 @@ public void deinit() { moduleManager.unregisterAll(); } - // Getters public String getMinecraftVersion() { @@ -731,34 +692,34 @@ public String getMinecraftVersion() } public List getMVersionMajMin() { - if ( versionMajMin == null ) { - - this.versionMajMin = new ArrayList<>(); - - String v = Prison.get().getMinecraftVersion(); - String versionStr = v.substring( v.indexOf( "(MC:" ) + 4, v.lastIndexOf( ")" ) ); - String[] vMN = versionStr.split( "\\." ); - - for ( int x = 0; x < vMN.length; x++ ) { - String ver = vMN[x]; + if ( versionMajMin == null ) { - try { - this.versionMajMin.add( - Integer.parseInt( ver.trim() ) ); - } - catch ( NumberFormatException e ) { - // ignore... just break out: - break; + this.versionMajMin = new ArrayList<>(); + + String v = Prison.get().getMinecraftVersion(); + String versionStr = v.substring( v.indexOf( "(MC:" ) + 4, v.lastIndexOf( ")" ) ); + String[] vMN = versionStr.split( "\\." ); + + for ( int x = 0; x < vMN.length; x++ ) { + String ver = vMN[x]; + + try { + this.versionMajMin.add( + Integer.parseInt( ver.trim() ) ); + } + catch ( NumberFormatException e ) { + // ignore... just break out: + break; + } } - } - -// Output.get().logInfo( "#### Prison.getMVersionMajMin() : " + -// ( versionMajMin != null && versionMajMin.size() > 0 ? versionMajMin.get(0) : "?" ) + " " + -// ( versionMajMin != null && versionMajMin.size() > 1 ? versionMajMin.get(1) : "?" ) + " " + -// ( versionMajMin != null && versionMajMin.size() > 2 ? versionMajMin.get(2) : "?" ) -// ); - } - return versionMajMin; + + // Output.get().logInfo( "#### Prison.getMVersionMajMin() : " + + // ( versionMajMin != null && versionMajMin.size() > 0 ? versionMajMin.get(0) : "?" ) + " " + + // ( versionMajMin != null && versionMajMin.size() > 1 ? versionMajMin.get(1) : "?" ) + " " + + // ( versionMajMin != null && versionMajMin.size() > 2 ? versionMajMin.get(2) : "?" ) + // ); + } + return versionMajMin; } @Override @@ -784,7 +745,7 @@ public Platform getPlatform() { * @param platform */ public void setPlatform( Platform platform ) { - this.platform = platform; + this.platform = platform; } /** @@ -854,12 +815,6 @@ public SelectionManager getSelectionManager() { return selectionManager; } -// /** -// * Returns the item manager, which manages the "friendly" names of items -// */ -// public ItemManager getItemManager() { -// return itemManager; -// } /** * Returns the meta database, which is used to store data from within the core. @@ -887,7 +842,7 @@ public IntegrationManager getIntegrationManager() { * Returns the integration manager, which returns {@link tech.mcprison.prison.integration.Integration}s. */ public PlaceholderManager getPlaceholderManager() { - return placeholderManager; + return placeholderManager; } @@ -899,9 +854,9 @@ public void setServerStartupTime( long serverStartupTime ) { } public String getServerRuntimeFormatted() { - long currentTime = System.currentTimeMillis(); - long runtimeMs = currentTime - getServerStartupTime(); - return PlaceholdersUtil.formattedTime( runtimeMs / 1000 ); + long currentTime = System.currentTimeMillis(); + long runtimeMs = currentTime - getServerStartupTime(); + return PlaceholdersUtil.formattedTime( runtimeMs / 1000 ); } public PrisonTPSSingleton getPrisonTPS() { diff --git a/prison-core/src/main/java/tech/mcprison/prison/PrisonAPI.java b/prison-core/src/main/java/tech/mcprison/prison/PrisonAPI.java index fc9fe7280..27eb52f8d 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/PrisonAPI.java +++ b/prison-core/src/main/java/tech/mcprison/prison/PrisonAPI.java @@ -20,7 +20,6 @@ import tech.mcprison.prison.internal.scoreboard.ScoreboardManager; import tech.mcprison.prison.modules.ModuleManager; import tech.mcprison.prison.store.Storage; -import tech.mcprison.prison.troubleshoot.TroubleshootManager; import tech.mcprison.prison.util.Location; /** @@ -43,10 +42,6 @@ public static EventBus getEventBus() { return Prison.get().getEventBus(); } -// public static ItemManager getItemManager() { -// return Prison.get().getItemManager(); -// } - public static Optional getWorld(String name) { return Prison.get().getPlatform().getWorld(name); } @@ -88,18 +83,15 @@ public static void dispatchCommand(String cmd) { } public static void dispatchCommand(tech.mcprison.prison.internal.CommandSender sender, String cmd) { - Prison.get().getPlatform().dispatchCommand( sender, cmd); + Prison.get().getPlatform().dispatchCommand( sender, cmd); } public static Scheduler getScheduler() { return Prison.get().getPlatform().getScheduler(); } -// public static GUI createGUI(String title, int numRows) { -// return Prison.get().getPlatform().createGUI(title, numRows); -// } - - @Deprecated public static void toggleDoor(Location doorLocation) { + @Deprecated + public static void toggleDoor(Location doorLocation) { Prison.get().getPlatform().toggleDoor(doorLocation); } @@ -127,10 +119,6 @@ public static ScoreboardManager getScoreboardManager() { return Prison.get().getPlatform().getScoreboardManager(); } -// public static TroubleshootManager getTroubleshootManager() { -// return Prison.get().getTroubleshootManager(); -// } - public static IntegrationManager getIntegrationManager() { return Prison.get().getIntegrationManager(); } 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 79b9c5cf0..9985eceea 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java +++ b/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java @@ -54,8 +54,6 @@ import tech.mcprison.prison.output.Output; import tech.mcprison.prison.output.Output.DebugTarget; import tech.mcprison.prison.placeholders.PlaceholdersStats; -import tech.mcprison.prison.troubleshoot.TroubleshootResult; -import tech.mcprison.prison.troubleshoot.Troubleshooter; import tech.mcprison.prison.util.PrisonJarReporter; /** @@ -93,24 +91,19 @@ public void versionCommand(CommandSender sender, @Wildcard(join=true) @Arg(name = "options", description = "Options [basic, all]", def = "basic" ) String options) { - if ( options != null && !"basic".equalsIgnoreCase( options ) && !"all".equalsIgnoreCase( options ) ) { - Output.get().logInfo( "&7Invalid option. [basic, all]" ); - return; - - } - else if ( options == null ) { - options = "basic"; - } + if ( options != null && !"basic".equalsIgnoreCase( options ) && !"all".equalsIgnoreCase( options ) ) { + Output.get().logInfo( "&7Invalid option. [basic, all]" ); + return; + + } + else if ( options == null ) { + options = "basic"; + } - ChatDisplay display = Prison.get().getPrisonStatsUtil().displayVersion(options); + ChatDisplay display = Prison.get().getPrisonStatsUtil().displayVersion(options); display.send(sender); -// if ( options != null && "all".equalsIgnoreCase( options )) { -// // Display all Ranks in each ladder: -// boolean includeAll = true; -// PrisonRanks.getInstance().getRankManager().ranksByLadders( includeAll ); -// } } /** @@ -125,31 +118,31 @@ else if ( options == null ) { * */ public class RegisteredPluginsData { - private String pluginName; - private String pluginVersion; - private List registeredCommands; - - private boolean registered = false; - private int aliasCount = 0; - - public RegisteredPluginsData( String pluginName, String pluginVersion, boolean registered ) { - super(); - - this.pluginName = pluginName; - this.pluginVersion = pluginVersion; - this.registered = registered; - - this.registeredCommands = new ArrayList<>(); - } - - public void addCommand( String commandName, List commandAliases ) { - RegisteredPluginCommandData command = - new RegisteredPluginCommandData( commandName, commandAliases ); - - getRegisteredCommands().add( command ); - - setAliasCount( getAliasCount() + commandAliases.size() ); - } + private String pluginName; + private String pluginVersion; + private List registeredCommands; + + private boolean registered = false; + private int aliasCount = 0; + + public RegisteredPluginsData( String pluginName, String pluginVersion, boolean registered ) { + super(); + + this.pluginName = pluginName; + this.pluginVersion = pluginVersion; + this.registered = registered; + + this.registeredCommands = new ArrayList<>(); + } + + public void addCommand( String commandName, List commandAliases ) { + RegisteredPluginCommandData command = + new RegisteredPluginCommandData( commandName, commandAliases ); + + getRegisteredCommands().add( command ); + + setAliasCount( getAliasCount() + commandAliases.size() ); + } public Object formatted() @@ -228,15 +221,15 @@ public void setAliasCount( int aliasCount ) { } public class RegisteredPluginCommandData { - private String command; - private List aliases; - - public RegisteredPluginCommandData( String command, List aliases ) { - super(); - - this.command = command; - this.aliases = aliases; - } + private String command; + private List aliases; + + public RegisteredPluginCommandData( String command, List aliases ) { + super(); + + this.command = command; + this.aliases = aliases; + } public String getCommand() { return command; @@ -254,196 +247,6 @@ public void setAliases( List aliases ) { } -// -// public ChatDisplay displayVersion(String options) { -// -// boolean isBasic = options == null || "basic".equalsIgnoreCase( options ); -// -// ChatDisplay display = new ChatDisplay("/prison version"); -// display.addText("&7Prison Version: %s", Prison.get().getPlatform().getPluginVersion()); -// -// display.addText("&7Running on Platform: %s", Prison.get().getPlatform().getClass().getName()); -// display.addText("&7Minecraft Version: %s", Prison.get().getMinecraftVersion()); -// -// -// // System stats: -// display.addText(""); -// -// Prison.get().displaySystemSettings( display ); -// -// Prison.get().displaySystemTPS( display ); -// -// -// display.addText(""); -// -// -// // This generates the module listing, the autoFeatures overview, -// // the integrations listings, and the plugins listings. -// boolean showLaddersAndRanks = true; -// Prison.get().getPlatform().prisonVersionFeatures( display, isBasic, showLaddersAndRanks ); -// -// -// -//// List features = Prison.get().getPlatform().getActiveFeatures(); -//// if ( features.size() > 0 ) { -//// -//// display.addText(""); -//// for ( String feature : features ) { -//// -//// if ( !feature.startsWith( "+" ) ) { -//// -//// display.addText( feature ); -//// } -//// else if ( !isBasic ) { -//// -//// display.addText( feature.substring( 1 ) ); -//// } -//// } -//// } -//// -//// -//// display.addText(""); -//// -//// // Active Modules: -//// display.addText("&7Prison's root Command: &3/prison"); -//// -//// for ( Module module : Prison.get().getModuleManager().getModules() ) { -//// -//// display.addText( "&7Module: %s : %s %s", module.getName(), -//// module.getStatus().getStatusText(), -//// (module.getStatus().getStatus() == ModuleStatus.Status.FAILED ? -//// "[" + module.getStatus().getMessage() + "]" : "") -//// ); -//// // display.addText( ". &7Base Commands: %s", module.getBaseCommands() ); -//// } -//// -//// List disabledModules = Prison.get().getModuleManager().getDisabledModules(); -//// if ( disabledModules.size() > 0 ) { -//// display.addText( "&7Disabled Module%s:", (disabledModules.size() > 1 ? "s" : "")); -//// for ( String disabledModule : Prison.get().getModuleManager().getDisabledModules() ) { -//// display.addText( ". &cDisabled Module:&7 %s. Related commands and placeholders are non-functional. ", -//// disabledModule ); -//// } -//// } -//// -//// display.addText(""); -//// display.addText("&7Integrations:"); -//// -//// IntegrationManager im = Prison.get().getIntegrationManager(); -//// String permissions = -//// (im.hasForType(IntegrationType.PERMISSION) ? -//// " " + im.getForType(IntegrationType.PERMISSION).get().getDisplayName() : -//// "None"); -//// -//// display.addText(". . &7Permissions: " + permissions); -//// -//// String economy = -//// (im.hasForType(IntegrationType.ECONOMY) ? -//// " " + im.getForType(IntegrationType.ECONOMY).get().getDisplayName() : -//// "None"); -//// -//// display.addText(". . &7Economy: " + economy); -//// -//// -//// List integrationRows = im.getIntegrationComponents( isBasic ); -//// for ( DisplayComponent component : integrationRows ) -//// { -//// display.addComponent( component ); -//// } -//// -//// -//// display.addText(""); -//// display.addText("&7Locale Settings:"); -//// -//// for ( String localeInfo : Prison.get().getLocaleLoadInfo() ) { -//// display.addText( ". . " + localeInfo ); -//// } -// -//// -//// Prison.get().getPlatform().identifyRegisteredPlugins(); -//// -//// // NOTE: This list of plugins is good enough and the detailed does not have all the info. -//// // Display all loaded plugins: -//// if ( getRegisteredPlugins().size() > 0 ) { -//// display.addText(""); -//// display.addText( "&7Registered Plugins: " ); -//// -//// List plugins = getRegisteredPlugins(); -//// Collections.sort( plugins ); -//// List plugins2Cols = Text.formatColumnsFromList( plugins, 2 ); -//// -//// for ( String rp : plugins2Cols ) { -//// -//// display.addText( rp ); -//// } -//// -////// StringBuilder sb = new StringBuilder(); -////// for ( String plugin : getRegisteredPlugins() ) { -////// if ( sb.length() == 0) { -////// sb.append( ". " ); -////// sb.append( plugin ); -////// } else { -////// sb.append( ", " ); -////// sb.append( plugin ); -////// display.addText( sb.toString() ); -////// sb.setLength( 0 ); -////// } -////// } -////// if ( sb.length() > 0 ) { -////// display.addText( sb.toString()); -////// } -//// } -//// -//// // This version of plugins does not have all the registered commands: -////// // The new plugin listings: -////// if ( getRegisteredPluginData().size() > 0 ) { -////// display.text( "&7Registered Plugins Detailed: " ); -////// StringBuilder sb = new StringBuilder(); -////// Set keys = getRegisteredPluginData().keySet(); -////// -////// for ( String key : keys ) { -////// RegisteredPluginsData plugin = getRegisteredPluginData().get(key); -////// -////// if ( sb.length() == 0) { -////// sb.append( " " ); -////// sb.append( plugin.formatted() ); -////// } else { -////// sb.append( ", " ); -////// sb.append( plugin.formatted() ); -////// display.text( sb.toString() ); -////// sb.setLength( 0 ); -////// } -////// } -////// if ( sb.length() > 0 ) { -////// display.text( sb.toString()); -////// } -////// } -//// -//// -////// RegisteredPluginsData plugin = getRegisteredPluginData().get( "Prison" ); -////// String pluginDetails = plugin.getdetails(); -////// -////// display.text( pluginDetails ); -//// -//// -////// if ( !isBasic ) { -////// Prison.get().getPlatform().dumpEventListenersBlockBreakEvents(); -////// } -//// -//// -//// Prison.get().getPlatform().getWorldLoadErrors( display ); -//// -//// if ( !isBasic && getPrisonStartupDetails().size() > 0 ) { -//// display.addText(""); -//// -//// for ( String msg : getPrisonStartupDetails() ) { -//// display.addText( msg ); -//// } -//// } -// -// return display; -// } - /** * A test to see if these dummy command placeholders could possibly lock out @@ -454,25 +257,25 @@ public void setAliases( List aliases ) { @Command(identifier = "prison", onlyPlayers = false, permissions = "prison.commands") public void prisonSubcommands(CommandSender sender) { - sender.dispatchCommand( "prison help" ); + sender.dispatchCommand( "prison help" ); } @Command(identifier = "prison placeholders", onlyPlayers = false, permissions = "prison.commands") public void prisonPlaceholdersSubcommands(CommandSender sender) { - sender.dispatchCommand( "prison placeholders help" ); + sender.dispatchCommand( "prison placeholders help" ); } @Command(identifier = "prison reload", onlyPlayers = false, permissions = "prison.commands") public void prisonReloadSubcommands(CommandSender sender) { - sender.dispatchCommand( "prison reload help" ); + sender.dispatchCommand( "prison reload help" ); } @Command(identifier = "prison utils", onlyPlayers = false, permissions = "prison.commands") public void prisonUtilsSubcommands(CommandSender sender) { - sender.dispatchCommand( "prison utils help" ); + sender.dispatchCommand( "prison utils help" ); } @@ -494,48 +297,6 @@ public void modulesCommand(CommandSender sender) { display.send(sender); } -// @Command(identifier = "prison troubleshoot", description = "Runs a troubleshooter.", -// onlyPlayers = false, permissions = "prison.troubleshoot") - public void troubleshootCommand(CommandSender sender, - @Arg(name = "name", def = "list", description = "The name of the troubleshooter.") String name) { - // They just want to list stuff - if (name.equals("list")) { - sender.dispatchCommand("prison troubleshoot list"); - return; - } - -// TroubleshootResult result = -// PrisonAPI.getTroubleshootManager().invokeTroubleshooter(name, sender); -// if (result == null) { -// Output.get().sendError(sender, "The troubleshooter %s doesn't exist.", name); -// return; -// } -// -// ChatDisplay display = new ChatDisplay("Result Summary"); -// display.addText("&7Troubleshooter name: &b%s", name.toLowerCase()) // -// .addText("&7Result type: &b%s", result.getResult().name()) // -// .addText("&7Result details: &b%s", result.getDescription()) // -// .send(sender); - - } - -// @Command(identifier = "prison troubleshoot list", description = "Lists the troubleshooters.", -// onlyPlayers = false, permissions = "prison.troubleshoot") - public void troubleshootListCommand(CommandSender sender) { - ChatDisplay display = new ChatDisplay("Troubleshooters"); - display.addText("&8Type /prison troubleshoot to run a troubleshooter."); - -// BulletedListComponent.BulletedListBuilder builder = -// new BulletedListComponent.BulletedListBuilder(); -// for (Troubleshooter troubleshooter : PrisonAPI.getTroubleshootManager() -// .getTroubleshooters()) { -// builder.add("&b%s &8- &7%s", troubleshooter.getName(), troubleshooter.getDescription()); -// } -// display.addComponent(builder.build()); -// -// display.send(sender); - } - @Command(identifier = "prison placeholders test", description = "Converts any Prison placeholders in the test string to their values. " @@ -550,69 +311,69 @@ public void placeholdersTestCommand(CommandSender sender, description = "Placeholder text to test using { } as escape characters" ) String text ) { - if ( playerName != null && playerName.contains( "%" ) || - text != null && text.contains( "%" ) ) { - Output.get().logInfo( "&3You cannot use &7 %%%% &3 as escape characters. Use &7{&3 &7}&3 instead." ); - return; - } - - - // blank defaults do not work when there are more than one at a time. So had to - // default to periods. So convert periods to blanks initially: - playerName = (playerName.equals( "." ) ? "" : playerName ); - - // Try to get player from the supplied playerName first: - Player player = getPlayer( null, playerName ); - if ( player == null ) { - // No player found, or none specified. Need to shift parameters over by one: - if ( text != null && text.trim().length() > 0 ) { - - // playerName should be moved to the pageNumber, after pageNumber is moved to patterns: - text = (playerName.trim() + " " + text).trim(); - } - else { - text = playerName; - } - - // Try to get player from the sender: - player = getPlayer( sender ); - } - - boolean isShort = text.startsWith( "-s " ); - if ( isShort ) { - text = text.substring( 3 ); - } - - ChatDisplay display = new ChatDisplay("Placeholder Test"); - - BulletedListComponent.BulletedListBuilder builder = - new BulletedListComponent.BulletedListBuilder(); - - - UUID playerUuid = player == null ? null : player.getUUID(); - playerName = player != null ? player.getName() : - (playerName.isEmpty() ? sender.getName() : playerName); - - String translated = Prison.get().getPlatform().getPlaceholders() - .placeholderTranslateText( playerUuid, playerName, 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)); - - display.addComponent(builder.build()); - display.send(sender); + if ( playerName != null && playerName.contains( "%" ) || + text != null && text.contains( "%" ) ) { + Output.get().logInfo( "&3You cannot use &7 %%%% &3 as escape characters. Use &7{&3 &7}&3 instead." ); + return; + } + + + // blank defaults do not work when there are more than one at a time. So had to + // default to periods. So convert periods to blanks initially: + playerName = (playerName.equals( "." ) ? "" : playerName ); + + // Try to get player from the supplied playerName first: + Player player = getPlayer( null, playerName ); + if ( player == null ) { + // No player found, or none specified. Need to shift parameters over by one: + if ( text != null && text.trim().length() > 0 ) { + + // playerName should be moved to the pageNumber, after pageNumber is moved to patterns: + text = (playerName.trim() + " " + text).trim(); + } + else { + text = playerName; + } + + // Try to get player from the sender: + player = getPlayer( sender ); + } + + boolean isShort = text.startsWith( "-s " ); + if ( isShort ) { + text = text.substring( 3 ); + } + + ChatDisplay display = new ChatDisplay("Placeholder Test"); + + BulletedListComponent.BulletedListBuilder builder = + new BulletedListComponent.BulletedListBuilder(); + + + UUID playerUuid = player == null ? null : player.getUUID(); + playerName = player != null ? player.getName() : + (playerName.isEmpty() ? sender.getName() : playerName); + + String translated = Prison.get().getPlatform().getPlaceholders() + .placeholderTranslateText( playerUuid, playerName, 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)); + + display.addComponent(builder.build()); + display.send(sender); } private Player getPlayer( CommandSender sender ) { @@ -640,10 +401,8 @@ private Player getPlayer( CommandSender sender, String playerName ) { if ( !opt.isPresent() ) { result = Prison.get().getPlatform().getRankPlayer( null, playerName ); -// opt = Prison.get().getPlatform().getOfflinePlayer( playerName ); } -// if ( opt.isPresent() ) { else { result = opt.get(); } @@ -663,58 +422,58 @@ public void placeholdersSearchCommand(CommandSender sender, - // blank defaults do not work when there are more than one at a time. So had to - // default to periods. So convert periods to blanks initially: - playerName = (playerName.equals( "." ) ? "" : playerName ); - pageNumber = (pageNumber.equals( "." ) ? "" : pageNumber ); - patterns = (patterns.equals( "." ) ? "" : patterns ); - - Player player = getPlayer( null, playerName ); - if ( player == null ) { - // No player found, or none specified. Need to shift parameters over by one: - if ( pageNumber != null && pageNumber.trim().length() > 0 ) { - - // playerName should be moved to the pageNumber, after pageNumber is moved to patterns: - patterns = (pageNumber.trim() + " " + patterns).trim(); - } - pageNumber = playerName; - } - - - int page = 1; - - /** - * Please note: Page is optional and defaults to a value of 1. But when it is not - * provided, it "grabs" the first pattern. So basically, if pageNumber proves not - * to be a number, then we must prefix whatever is in patterns with that value. - */ - if ( pageNumber != null ) { - - try { - page = Integer.parseInt( pageNumber ); + // blank defaults do not work when there are more than one at a time. So had to + // default to periods. So convert periods to blanks initially: + playerName = (playerName.equals( "." ) ? "" : playerName ); + pageNumber = (pageNumber.equals( "." ) ? "" : pageNumber ); + patterns = (patterns.equals( "." ) ? "" : patterns ); + + Player player = getPlayer( null, playerName ); + if ( player == null ) { + // No player found, or none specified. Need to shift parameters over by one: + if ( pageNumber != null && pageNumber.trim().length() > 0 ) { + + // playerName should be moved to the pageNumber, after pageNumber is moved to patterns: + patterns = (pageNumber.trim() + " " + patterns).trim(); + } + pageNumber = playerName; + } + + + int page = 1; + + /** + * Please note: Page is optional and defaults to a value of 1. But when it is not + * provided, it "grabs" the first pattern. So basically, if pageNumber proves not + * to be a number, then we must prefix whatever is in patterns with that value. + */ + if ( pageNumber != null ) { + + try { + page = Integer.parseInt( pageNumber ); } - catch ( NumberFormatException e ) { - // If exception, add pageNumber to the beginning patterns. - // So no page number was specified, it was part of the patterns - patterns = (pageNumber.trim() + " " + patterns).trim(); + catch ( NumberFormatException e ) { + // If exception, add pageNumber to the beginning patterns. + // So no page number was specified, it was part of the patterns + patterns = (pageNumber.trim() + " " + patterns).trim(); } - - } - - - // Cannot allow pages less than 1: - if ( page < 1 ) { - page = 1; - } - - ChatDisplay display = new ChatDisplay("Placeholders Search"); - - - if ( patterns == null || patterns.trim().length() == 0 ) { - sender.sendMessage( "&7Pattern required. Placeholder results must match all pattern terms." ); - return; - } - + + } + + + // Cannot allow pages less than 1: + if ( page < 1 ) { + page = 1; + } + + ChatDisplay display = new ChatDisplay("Placeholders Search"); + + + if ( patterns == null || patterns.trim().length() == 0 ) { + sender.sendMessage( "&7Pattern required. Placeholder results must match all pattern terms." ); + return; + } + BulletedListComponent.BulletedListBuilder builder = new BulletedListComponent.BulletedListBuilder(); @@ -742,30 +501,30 @@ public void placeholdersSearchCommand(CommandSender sender, DecimalFormat dFmt = Prison.get().getDecimalFormatInt(); builder.add( String.format( "&7 Results: &c%s &7Original patterns: &3%s", - dFmt.format(placeholders.size()), patterns )); + dFmt.format(placeholders.size()), patterns )); CommandPagedData cmdPageData = new CommandPagedData( - "/prison placeholders search", placeholders.size(), - 0, Integer.toString( page ), 20 ); + "/prison placeholders search", placeholders.size(), + 0, Integer.toString( page ), 20 ); // Need to provide more "parts" to the command that follows the page number: cmdPageData.setPageCommandSuffix( patterns ); int count = 0; - for ( String placeholder : placeholders ) { - if ( cmdPageData == null || - count++ >= cmdPageData.getPageStart() && - count <= cmdPageData.getPageEnd() ) { - - builder.add( String.format( placeholder )); - } + for ( String placeholder : placeholders ) { + if ( cmdPageData == null || + count++ >= cmdPageData.getPageStart() && + count <= cmdPageData.getPageEnd() ) { + + builder.add( String.format( placeholder )); + } } - display.addComponent(builder.build()); - - cmdPageData.generatePagedCommandFooter( display ); - - display.send(sender); + display.addComponent(builder.build()); + + cmdPageData.generatePagedCommandFooter( display ); + + display.send(sender); } @@ -775,27 +534,27 @@ public void placeholdersSearchCommand(CommandSender sender, public void placeholdersListCommand(CommandSender sender ) { - ChatDisplay display = new ChatDisplay("Placeholders List"); - - display.addText( "&a Placeholders are case insensitive, but are registered in all lowercase."); - display.addText( "&a Placeholder escape characters may be { } or % %. If one does not work, try the other."); - display.addText( "&a Placeholders that include 'rankname', 'laddername', or 'minename' should be"); - display.addText( "&a replaced with the appropriate rank names, ladder names, or mine names."); - - for ( String disabledModule : Prison.get().getModuleManager().getDisabledModules() ) { - display.addText( "&a &cDisabled Module: &7%s&a. Related placeholders maybe listed but are non-functional. ", - disabledModule ); - } - - List placeholders = new ArrayList<>(); - Prison.get().getIntegrationManager().getPlaceholderTemplateList( placeholders ); - - - for ( DisplayComponent placeholder : placeholders ) { - display.addComponent( placeholder ); - } - - display.send(sender); + ChatDisplay display = new ChatDisplay("Placeholders List"); + + display.addText( "&a Placeholders are case insensitive, but are registered in all lowercase."); + display.addText( "&a Placeholder escape characters may be { } or % %. If one does not work, try the other."); + display.addText( "&a Placeholders that include 'rankname', 'laddername', or 'minename' should be"); + display.addText( "&a replaced with the appropriate rank names, ladder names, or mine names."); + + for ( String disabledModule : Prison.get().getModuleManager().getDisabledModules() ) { + display.addText( "&a &cDisabled Module: &7%s&a. Related placeholders maybe listed but are non-functional. ", + disabledModule ); + } + + List placeholders = new ArrayList<>(); + Prison.get().getIntegrationManager().getPlaceholderTemplateList( placeholders ); + + + for ( DisplayComponent placeholder : placeholders ) { + display.addComponent( placeholder ); + } + + display.send(sender); } @@ -811,33 +570,25 @@ public void placeholdersStatsCommand(CommandSender sender, def = "." ) String options ) { - ChatDisplay display = new ChatDisplay("Placeholders List"); - - if ( options != null && !".".equals(options) ) { - boolean resetCache = "resetCache".equalsIgnoreCase( options ); - boolean removeErrors = "removeErrors".equalsIgnoreCase( options ); - - PlaceholdersStats.getInstance().clearCache( resetCache, removeErrors ); - } - - ArrayList stats = PlaceholdersStats.getInstance().generatePlaceholderReport(); - - for (String stat : stats) { - display.addText( stat.replace( "%", "%%") ); - } - - - display.send(sender); + ChatDisplay display = new ChatDisplay("Placeholders List"); + + if ( options != null && !".".equals(options) ) { + boolean resetCache = "resetCache".equalsIgnoreCase( options ); + boolean removeErrors = "removeErrors".equalsIgnoreCase( options ); + + PlaceholdersStats.getInstance().clearCache( resetCache, removeErrors ); + } + + ArrayList stats = PlaceholdersStats.getInstance().generatePlaceholderReport(); + + for (String stat : stats) { + display.addText( stat.replace( "%", "%%") ); + } + + + display.send(sender); } -// @Command(identifier = "prison reload placeholders", -// description = "Placeholder reload: Regenerates all placeholders and reregisters them.", -// onlyPlayers = false, -// permissions = "prison.placeholder", -// aliases = { "prison reload configyml" }) -// public void placeholdersReloadCommandAlias(CommandSender sender ) { -// placeholdersReloadCommand( sender ); -// } @Command(identifier = "prison placeholders reload", description = "Placeholder reload: Regenerates all placeholders and reregisters them. " @@ -852,12 +603,12 @@ public void placeholdersStatsCommand(CommandSender sender, } ) public void placeholdersReloadCommand(CommandSender sender ) { - Prison.get().getPlatform().getPlaceholders().reloadPlaceholders(); - - String message = "Placeholder and config.yml reload was attempted. " + - "No guarentees that it worked 100%. Restart server if any doubts."; - - sender.sendMessage( message ); + Prison.get().getPlatform().getPlaceholders().reloadPlaceholders(); + + String message = "Placeholder and config.yml reload was attempted. " + + "No guarentees that it worked 100%. Restart server if any doubts."; + + sender.sendMessage( message ); } @@ -867,14 +618,14 @@ public void placeholdersReloadCommand(CommandSender sender ) { onlyPlayers = false, permissions = "prison.reload") public void localesReloadCommand(CommandSender sender ) { - for ( LocaleManager LocalManager : LocaleManager.getRegisteredInstances() ) { - LocalManager.reload(); - } - - String message = "Locales reload was attempted. " + - "No guarentees that it worked 100%. Restart server if any doubts."; - - sender.sendMessage( message ); + for ( LocaleManager LocalManager : LocaleManager.getRegisteredInstances() ) { + LocalManager.reload(); + } + + String message = "Locales reload was attempted. " + + "No guarentees that it worked 100%. Restart server if any doubts."; + + sender.sendMessage( message ); } @@ -882,37 +633,21 @@ public void localesReloadCommand(CommandSender sender ) { description = "AutoFeatures reload: Reloads the auto features settings. The current " + "settings will be discarded before reloading the configuration file.", onlyPlayers = false, permissions = "prison.autofeatures") - public void reloadAutoFeatures(CommandSender sender ) { - - AutoFeaturesWrapper.getInstance().reloadConfigs(); - - String message = "&7AutoFeatures were reloaded. The new settings are now in effect. "; - sender.sendMessage( message ); - - try { - String filePath = AutoFeaturesWrapper.getInstance().getAutoFeaturesConfig() - .getConfigFile().getCanonicalPath(); - sender.sendMessage( filePath ); - } - catch ( IOException e ) { - // Ignore - } -// 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 -// } + public void reloadAutoFeatures(CommandSender sender ) { + + AutoFeaturesWrapper.getInstance().reloadConfigs(); + + String message = "&7AutoFeatures were reloaded. The new settings are now in effect. "; + sender.sendMessage( message ); + + try { + String filePath = AutoFeaturesWrapper.getInstance().getAutoFeaturesConfig() + .getConfigFile().getCanonicalPath(); + sender.sendMessage( filePath ); + } + catch ( IOException e ) { + // Ignore + } } @@ -922,26 +657,26 @@ public void reloadAutoFeatures(CommandSender sender ) { onlyPlayers = false, permissions = "prison.autofeatures") public void reloadBlockConverters(CommandSender sender ) { - if ( AutoFeaturesWrapper.getBlockConvertersInstance() != null ) { - - 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 - } - - } + if ( AutoFeaturesWrapper.getBlockConvertersInstance() != null ) { + + 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 + } + + } } @@ -967,205 +702,205 @@ public void reloadBlockConverters(CommandSender sender ) { // "prison.autofeatures.block" }) public void autoFeaturesInformation(CommandSender sender) { - ChatDisplay display = new ChatDisplay("Auto Features Information"); - - display.addText( "&a Prison auto features provide the following options:"); - display.addText( "&7 Auto pickup - &aUpon block break, items are placed directly in to player inventory."); - display.addText( "&a - Features for enabling XP, Durability, and Fortune are within the config file."); - display.addText( "&7 Auto smelt - &aItems that can be smelted will be smelted automatically."); - display.addText( "&7 Auto block - &aConverts ores to blocks."); - display.addText( "&7 Tool lore starts with: Pickup, Smelt, or Block. Only one per line." ); - display.addText( "&7 Tool lore names can be customize in config file, but color codes could be an issue." ); - display.addText( "&7 Tool lore 100 percent with just name. Can have value 0.001 to 100.0 percent." ); - display.addText( "&7 Tool lore examples: Pickup, Pickup 7.13, Smelt 55, Block 75.123" ); - - display.addText( "&a To configure modify plugin/Prison/autoFeaturesConfig.yml"); - display.addText( "&a Or better yet, you can use the &7/prison gui"); - - display.addText( "&a"); - display.addText( "&aPrison supports TokenEnchant's explosion based enchants. Please see our online " + - "documentation related to WorldGuard and LuckPerms with protecting mines (its near the bottom). " + - "TE's configurations may not be obvious without reading the document."); - display.addText( "&a"); - display.addText( "&aPrison also supports Crazy Enchant's explosion based enchantments too. "); - - - List afs = AutoFeatures.permissions.getChildren(); - StringBuilder sb = new StringBuilder(); - for ( AutoFeatures af : afs ) { - if ( sb.length() > 0 ) { - sb.append( " " ); + ChatDisplay display = new ChatDisplay("Auto Features Information"); + + display.addText( "&a Prison auto features provide the following options:"); + display.addText( "&7 Auto pickup - &aUpon block break, items are placed directly in to player inventory."); + display.addText( "&a - Features for enabling XP, Durability, and Fortune are within the config file."); + display.addText( "&7 Auto smelt - &aItems that can be smelted will be smelted automatically."); + display.addText( "&7 Auto block - &aConverts ores to blocks."); + display.addText( "&7 Tool lore starts with: Pickup, Smelt, or Block. Only one per line." ); + display.addText( "&7 Tool lore names can be customize in config file, but color codes could be an issue." ); + display.addText( "&7 Tool lore 100 percent with just name. Can have value 0.001 to 100.0 percent." ); + display.addText( "&7 Tool lore examples: Pickup, Pickup 7.13, Smelt 55, Block 75.123" ); + + display.addText( "&a To configure modify plugin/Prison/autoFeaturesConfig.yml"); + display.addText( "&a Or better yet, you can use the &7/prison gui"); + + display.addText( "&a"); + display.addText( "&aPrison supports TokenEnchant's explosion based enchants. Please see our online " + + "documentation related to WorldGuard and LuckPerms with protecting mines (its near the bottom). " + + "TE's configurations may not be obvious without reading the document."); + display.addText( "&a"); + display.addText( "&aPrison also supports Crazy Enchant's explosion based enchantments too. "); + + + List afs = AutoFeatures.permissions.getChildren(); + StringBuilder sb = new StringBuilder(); + for ( AutoFeatures af : afs ) { + if ( sb.length() > 0 ) { + sb.append( " " ); + } + sb.append( af.getMessage() ); } - sb.append( af.getMessage() ); - } - display.addText( "&3Permissions:" ); - display.addText( "&b %s", sb.toString() ); - display.addText( "&7 NOTE: Permissions enables that feature even if disabled for mines." ); - display.addText( " " ); - - - - AutoFeaturesWrapper afw = AutoFeaturesWrapper.getInstance(); - - display.addText( "&3Selected Settings from &bplugins/Prison/autoFeaturesConfigs.yml&3:" ); - display.addText( "&b " ); - display.addText( "&b options.general.isAutoManagerEnabled %s", - afw.isBoolean( AutoFeatures.isAutoManagerEnabled )); - - - if ( afw.isBoolean( AutoFeatures.isAutoManagerEnabled ) ) { - - - display.addText( "&b " ); - display.addText( "&b options.blockBreakEvents.applyBlockBreaksThroughSyncTask: %s", - afw.getMessage( AutoFeatures.applyBlockBreaksThroughSyncTask ) ); - - display.addText( "&b options.blockBreakEvents.cancelAllBlockBreakEvents: %s", - afw.getMessage( AutoFeatures.cancelAllBlockBreakEvents ) ); - - display.addText( "&b options.blockBreakEvents.cancelAllBlockEventBlockDrops: %s", - afw.getMessage( AutoFeatures.cancelAllBlockEventBlockDrops ) ); - - - display.addText( "&b options.blockBreakEvents.TokenEnchantBlockExplodeEventPriority: %s", - afw.getMessage( AutoFeatures.TokenEnchantBlockExplodeEventPriority ) ); - - display.addText( "&b options.blockBreakEvents.CrazyEnchantsBlastUseEventPriority: %s", - afw.getMessage( AutoFeatures.CrazyEnchantsBlastUseEventPriority ) ); - - display.addText( "&b options.blockBreakEvents.RevEnchantsExplosiveEventPriority: %s", - afw.getMessage( AutoFeatures.RevEnchantsExplosiveEventPriority ) ); - - display.addText( "&b options.blockBreakEvents.RevEnchantsJackHammerEventPriority: %s", - afw.getMessage( AutoFeatures.RevEnchantsJackHammerEventPriority ) ); - - display.addText( "&b options.blockBreakEvents.ZenchantmentsBlockShredEventPriority: %s", - afw.getMessage( AutoFeatures.ZenchantmentsBlockShredEventPriority ) ); - - display.addText( "&b options.blockBreakEvents.PrisonEnchantsExplosiveEventPriority: %s", - afw.getMessage( AutoFeatures.PrisonEnchantsExplosiveEventPriority ) ); - - display.addText( "&b options.blockBreakEvents.ProcessPrisons_ExplosiveBlockBreakEventsPriority: %s", - afw.getMessage( AutoFeatures.ProcessPrisons_ExplosiveBlockBreakEventsPriority ) ); - - - - display.addText( "&b " ); - display.addText( "&b Normal Drops (if auto pickup is off):" ); - display.addText( "&b options.normalDrop.isProcessNormalDropsEvents: %s", - afw.isBoolean( AutoFeatures.handleNormalDropsEvents ) ); - - display.addText( "&b " ); - display.addText( "&7 NOTE: If this is enabled, then lore and perms will override the settings for " ); - display.addText( "&7 pickup, smelt, and block when they are turned off." ); - - - display.addText( "&b " ); - - - display.addText( "&b options.autoPickup.autoPickupEnabled %s", - afw.isBoolean( AutoFeatures.autoPickupEnabled )); - - display.addText( "&b options.autoSmelt.autoSmeltEnabled %s", - afw.isBoolean( AutoFeatures.autoSmeltEnabled )); - display.addText( "&b options.autoBlock.autoBlockEnabled %s", - afw.isBoolean( AutoFeatures.autoBlockEnabled )); - - - display.addText( "&b " ); - display.addText( "&b options.normalDrop.handleNormalDropsEvents %s", - afw.isBoolean( AutoFeatures.handleNormalDropsEvents )); - display.addText( "&b options.normalDrop.normalDropSmelt %s", - afw.isBoolean( AutoFeatures.normalDropSmelt )); - display.addText( "&b options.normalDrop.normalDropSmelt %s", - afw.isBoolean( AutoFeatures.normalDropSmelt )); - display.addText( "&b options.normalDrop.normalDropCheckForFullInventory %s", - afw.isBoolean( AutoFeatures.normalDropCheckForFullInventory )); - - - - display.addText( "&b " ); - display.addText( "&b options.lore.isLoreEnabled %s", - afw.isBoolean( AutoFeatures.isLoreEnabled )); - display.addText( "&b options.lore.lorePickupValue %s", - afw.isBoolean( AutoFeatures.lorePickupValue )); - display.addText( "&b options.lore.loreSmeltValue %s", - afw.isBoolean( AutoFeatures.loreSmeltValue )); - display.addText( "&b options.lore.loreBlockValue %s", - afw.isBoolean( AutoFeatures.loreBlockValue )); - - - - - display.addText( "&b " ); - display.addText( "&b options.customEnchants.isCustomEnchantsEnabled %s", - afw.isBoolean( AutoFeatures.isCustomEnchantsEnabled )); - display.addText( "&b options.customEnchants.customEnchantsAutoPickup %s", - afw.isBoolean( AutoFeatures.customEnchantsAutoPickup )); - display.addText( "&b options.customEnchants.customEnchantsAutoSmelt %s", - afw.isBoolean( AutoFeatures.customEnchantsAutoSmelt )); - display.addText( "&b options.customEnchants.customEnchantsAutoBlock %s", - afw.isBoolean( AutoFeatures.customEnchantsAutoBlock )); - - - - - display.addText( "&b " ); - display.addText( "&b options.inventory.includePlayerInventoryWhenSmelting %s", - afw.isBoolean( AutoFeatures.includePlayerInventoryWhenSmelting )); - display.addText( "&b options.inventory.includePlayerInventoryWhenBlocking %s", - afw.isBoolean( AutoFeatures.includePlayerInventoryWhenBlocking )); - - - - - display.addText( "&b " ); - display.addText( "&b options.general.isCalculateDurabilityEnabled %s", - afw.isBoolean( AutoFeatures.isCalculateDurabilityEnabled )); - display.addText( "&b options.general.isCalculateFortuneEnabled %s", - afw.isBoolean( AutoFeatures.isCalculateFortuneEnabled )); - display.addText( "&b options.general.isCalculateAltFortuneOnAllBlocksEnabled %s", - afw.isBoolean( AutoFeatures.isCalculateAltFortuneOnAllBlocksEnabled )); - display.addText( "&b options.general.isCalculateXPEnabled %s", - afw.isBoolean( AutoFeatures.isCalculateXPEnabled )); - display.addText( "&b options.general.givePlayerXPAsOrbDrops %s", - afw.isBoolean( AutoFeatures.givePlayerXPAsOrbDrops )); - display.addText( "&b options.general.fortuneMultiplierGlobal %s", - afw.getMessage( AutoFeatures.fortuneMultiplierGlobal )); - display.addText( "&b options.general.fortuneMultiplierMax %s", - afw.getMessage( AutoFeatures.fortuneMultiplierMax )); - - - display.addText( "&b " ); - display.addText( "&b options.isProcessMcMMOBlockBreakEvents %s", - afw.isBoolean( AutoFeatures.isProcessMcMMOBlockBreakEvents )); - display.addText( "&b options.isProcessEZBlocksBlockBreakEvents %s", - afw.isBoolean( AutoFeatures.isProcessEZBlocksBlockBreakEvents )); - display.addText( "&b options.isProcessQuestsBlockBreakEvents %s", - afw.isBoolean( AutoFeatures.isProcessQuestsBlockBreakEvents )); - display.addText( "&b " ); - - - display.addText( "&b " ); - display.addText( "&b options.lore.isLoreEnabled %s", - afw.isBoolean( AutoFeatures.isLoreEnabled )); - display.addText( "&b options.lore.loreTrackBlockBreakCount %s", - afw.isBoolean( AutoFeatures.loreTrackBlockBreakCount )); - display.addText( "&b options.lore.loreBlockBreakCountName %s", - afw.getMessage( AutoFeatures.loreBlockBreakCountName )); - - display.addText( "&b options.lore.loreBlockExplosionCountName %s", - afw.getMessage( AutoFeatures.loreBlockExplosionCountName )); - display.addText( "&b options.lore.loreDurabiltyResistance %s", - afw.isBoolean( AutoFeatures.loreDurabiltyResistance )); - display.addText( "&b options.lore.loreDurabiltyResistanceName %s", - afw.getMessage( AutoFeatures.loreDurabiltyResistanceName )); - display.addText( "&b " ); - } - - - - display.send(sender); + display.addText( "&3Permissions:" ); + display.addText( "&b %s", sb.toString() ); + display.addText( "&7 NOTE: Permissions enables that feature even if disabled for mines." ); + display.addText( " " ); + + + + AutoFeaturesWrapper afw = AutoFeaturesWrapper.getInstance(); + + display.addText( "&3Selected Settings from &bplugins/Prison/autoFeaturesConfigs.yml&3:" ); + display.addText( "&b " ); + display.addText( "&b options.general.isAutoManagerEnabled %s", + afw.isBoolean( AutoFeatures.isAutoManagerEnabled )); + + + if ( afw.isBoolean( AutoFeatures.isAutoManagerEnabled ) ) { + + + display.addText( "&b " ); + display.addText( "&b options.blockBreakEvents.applyBlockBreaksThroughSyncTask: %s", + afw.getMessage( AutoFeatures.applyBlockBreaksThroughSyncTask ) ); + + display.addText( "&b options.blockBreakEvents.cancelAllBlockBreakEvents: %s", + afw.getMessage( AutoFeatures.cancelAllBlockBreakEvents ) ); + + display.addText( "&b options.blockBreakEvents.cancelAllBlockEventBlockDrops: %s", + afw.getMessage( AutoFeatures.cancelAllBlockEventBlockDrops ) ); + + + display.addText( "&b options.blockBreakEvents.TokenEnchantBlockExplodeEventPriority: %s", + afw.getMessage( AutoFeatures.TokenEnchantBlockExplodeEventPriority ) ); + + display.addText( "&b options.blockBreakEvents.CrazyEnchantsBlastUseEventPriority: %s", + afw.getMessage( AutoFeatures.CrazyEnchantsBlastUseEventPriority ) ); + + display.addText( "&b options.blockBreakEvents.RevEnchantsExplosiveEventPriority: %s", + afw.getMessage( AutoFeatures.RevEnchantsExplosiveEventPriority ) ); + + display.addText( "&b options.blockBreakEvents.RevEnchantsJackHammerEventPriority: %s", + afw.getMessage( AutoFeatures.RevEnchantsJackHammerEventPriority ) ); + + display.addText( "&b options.blockBreakEvents.ZenchantmentsBlockShredEventPriority: %s", + afw.getMessage( AutoFeatures.ZenchantmentsBlockShredEventPriority ) ); + + display.addText( "&b options.blockBreakEvents.PrisonEnchantsExplosiveEventPriority: %s", + afw.getMessage( AutoFeatures.PrisonEnchantsExplosiveEventPriority ) ); + + display.addText( "&b options.blockBreakEvents.ProcessPrisons_ExplosiveBlockBreakEventsPriority: %s", + afw.getMessage( AutoFeatures.ProcessPrisons_ExplosiveBlockBreakEventsPriority ) ); + + + + display.addText( "&b " ); + display.addText( "&b Normal Drops (if auto pickup is off):" ); + display.addText( "&b options.normalDrop.isProcessNormalDropsEvents: %s", + afw.isBoolean( AutoFeatures.handleNormalDropsEvents ) ); + + display.addText( "&b " ); + display.addText( "&7 NOTE: If this is enabled, then lore and perms will override the settings for " ); + display.addText( "&7 pickup, smelt, and block when they are turned off." ); + + + display.addText( "&b " ); + + + display.addText( "&b options.autoPickup.autoPickupEnabled %s", + afw.isBoolean( AutoFeatures.autoPickupEnabled )); + + display.addText( "&b options.autoSmelt.autoSmeltEnabled %s", + afw.isBoolean( AutoFeatures.autoSmeltEnabled )); + display.addText( "&b options.autoBlock.autoBlockEnabled %s", + afw.isBoolean( AutoFeatures.autoBlockEnabled )); + + + display.addText( "&b " ); + display.addText( "&b options.normalDrop.handleNormalDropsEvents %s", + afw.isBoolean( AutoFeatures.handleNormalDropsEvents )); + display.addText( "&b options.normalDrop.normalDropSmelt %s", + afw.isBoolean( AutoFeatures.normalDropSmelt )); + display.addText( "&b options.normalDrop.normalDropSmelt %s", + afw.isBoolean( AutoFeatures.normalDropSmelt )); + display.addText( "&b options.normalDrop.normalDropCheckForFullInventory %s", + afw.isBoolean( AutoFeatures.normalDropCheckForFullInventory )); + + + + display.addText( "&b " ); + display.addText( "&b options.lore.isLoreEnabled %s", + afw.isBoolean( AutoFeatures.isLoreEnabled )); + display.addText( "&b options.lore.lorePickupValue %s", + afw.isBoolean( AutoFeatures.lorePickupValue )); + display.addText( "&b options.lore.loreSmeltValue %s", + afw.isBoolean( AutoFeatures.loreSmeltValue )); + display.addText( "&b options.lore.loreBlockValue %s", + afw.isBoolean( AutoFeatures.loreBlockValue )); + + + + + display.addText( "&b " ); + display.addText( "&b options.customEnchants.isCustomEnchantsEnabled %s", + afw.isBoolean( AutoFeatures.isCustomEnchantsEnabled )); + display.addText( "&b options.customEnchants.customEnchantsAutoPickup %s", + afw.isBoolean( AutoFeatures.customEnchantsAutoPickup )); + display.addText( "&b options.customEnchants.customEnchantsAutoSmelt %s", + afw.isBoolean( AutoFeatures.customEnchantsAutoSmelt )); + display.addText( "&b options.customEnchants.customEnchantsAutoBlock %s", + afw.isBoolean( AutoFeatures.customEnchantsAutoBlock )); + + + + + display.addText( "&b " ); + display.addText( "&b options.inventory.includePlayerInventoryWhenSmelting %s", + afw.isBoolean( AutoFeatures.includePlayerInventoryWhenSmelting )); + display.addText( "&b options.inventory.includePlayerInventoryWhenBlocking %s", + afw.isBoolean( AutoFeatures.includePlayerInventoryWhenBlocking )); + + + + + display.addText( "&b " ); + display.addText( "&b options.general.isCalculateDurabilityEnabled %s", + afw.isBoolean( AutoFeatures.isCalculateDurabilityEnabled )); + display.addText( "&b options.general.isCalculateFortuneEnabled %s", + afw.isBoolean( AutoFeatures.isCalculateFortuneEnabled )); + display.addText( "&b options.general.isCalculateAltFortuneOnAllBlocksEnabled %s", + afw.isBoolean( AutoFeatures.isCalculateAltFortuneOnAllBlocksEnabled )); + display.addText( "&b options.general.isCalculateXPEnabled %s", + afw.isBoolean( AutoFeatures.isCalculateXPEnabled )); + display.addText( "&b options.general.givePlayerXPAsOrbDrops %s", + afw.isBoolean( AutoFeatures.givePlayerXPAsOrbDrops )); + display.addText( "&b options.general.fortuneMultiplierGlobal %s", + afw.getMessage( AutoFeatures.fortuneMultiplierGlobal )); + display.addText( "&b options.general.fortuneMultiplierMax %s", + afw.getMessage( AutoFeatures.fortuneMultiplierMax )); + + + display.addText( "&b " ); + display.addText( "&b options.isProcessMcMMOBlockBreakEvents %s", + afw.isBoolean( AutoFeatures.isProcessMcMMOBlockBreakEvents )); + display.addText( "&b options.isProcessEZBlocksBlockBreakEvents %s", + afw.isBoolean( AutoFeatures.isProcessEZBlocksBlockBreakEvents )); + display.addText( "&b options.isProcessQuestsBlockBreakEvents %s", + afw.isBoolean( AutoFeatures.isProcessQuestsBlockBreakEvents )); + display.addText( "&b " ); + + + display.addText( "&b " ); + display.addText( "&b options.lore.isLoreEnabled %s", + afw.isBoolean( AutoFeatures.isLoreEnabled )); + display.addText( "&b options.lore.loreTrackBlockBreakCount %s", + afw.isBoolean( AutoFeatures.loreTrackBlockBreakCount )); + display.addText( "&b options.lore.loreBlockBreakCountName %s", + afw.getMessage( AutoFeatures.loreBlockBreakCountName )); + + display.addText( "&b options.lore.loreBlockExplosionCountName %s", + afw.getMessage( AutoFeatures.loreBlockExplosionCountName )); + display.addText( "&b options.lore.loreDurabiltyResistance %s", + afw.isBoolean( AutoFeatures.loreDurabiltyResistance )); + display.addText( "&b options.lore.loreDurabiltyResistanceName %s", + afw.getMessage( AutoFeatures.loreDurabiltyResistanceName )); + display.addText( "&b " ); + } + + + + display.send(sender); // altPermissions are now a part of this command. // // After displaying the help information above, rerun the same command for the player @@ -1200,7 +935,7 @@ public void toggleDebug(CommandSender sender, "5 debug messages for that player, then debug mode will be disabled. " ) String targets ) { - String playerName = null; + String playerName = null; String playerStr = extractParameter("player=", targets); if ( playerStr != null ) { @@ -1220,66 +955,66 @@ public void toggleDebug(CommandSender sender, } } - if ( targets != null && "jarScan".equalsIgnoreCase( targets ) ) { - - PrisonJarReporter pjr = new PrisonJarReporter(); - pjr.scanForJars(); - pjr.dumpJarDetails(); - - return; - } - - - if ( targets != null && "testLocale".equalsIgnoreCase( targets ) ) { - - coreDebugTestLocaleseMsg( sender ); - - return; - } - - if ( targets != null && "testPlayerUtil".equalsIgnoreCase( targets ) ) { - - Player player = getPlayer( sender, "RoyalBlueRanger" ); - Prison.get().getPlatform().testPlayerUtil( player.getUUID() ); - - return; - } - - // Applies normal and selective targets: - Output.get().applyDebugTargets( targets ); - - String message = "&7Global Debug Logging is " + (Output.get().isDebug() ? "&3enabled" : "&cdisabled"); - sender.sendMessage( message ); - - Set activeDebugTargets = Output.get().getActiveDebugTargets(); - - if ( activeDebugTargets.size() > 0 ) { - message = ". Note: Active Debug Targets:"; - sender.sendMessage( message ); - - for ( DebugTarget target : activeDebugTargets ) - { - message = String.format( ". . Target: %s", target.name() ); - sender.sendMessage( message ); - } - } - - Set selectiveDebugTargets = Output.get().getSelectiveDebugTargets(); - - if ( selectiveDebugTargets.size() > 0 ) { - message = ". Selective Debug Targets:"; - sender.sendMessage( message ); - - for ( DebugTarget target : selectiveDebugTargets ) - { - message = String.format( ". . Target: %s", target.name() ); - sender.sendMessage( message ); - } - } - - String validTargets = Output.get().getDebugTargetsString(); - message = String.format( ". Valid Targets: %s", validTargets ); - sender.sendMessage( message ); + if ( targets != null && "jarScan".equalsIgnoreCase( targets ) ) { + + PrisonJarReporter pjr = new PrisonJarReporter(); + pjr.scanForJars(); + pjr.dumpJarDetails(); + + return; + } + + + if ( targets != null && "testLocale".equalsIgnoreCase( targets ) ) { + + coreDebugTestLocaleseMsg( sender ); + + return; + } + + if ( targets != null && "testPlayerUtil".equalsIgnoreCase( targets ) ) { + + Player player = getPlayer( sender, "RoyalBlueRanger" ); + Prison.get().getPlatform().testPlayerUtil( player.getUUID() ); + + return; + } + + // Applies normal and selective targets: + Output.get().applyDebugTargets( targets ); + + String message = "&7Global Debug Logging is " + (Output.get().isDebug() ? "&3enabled" : "&cdisabled"); + sender.sendMessage( message ); + + Set activeDebugTargets = Output.get().getActiveDebugTargets(); + + if ( activeDebugTargets.size() > 0 ) { + message = ". Note: Active Debug Targets:"; + sender.sendMessage( message ); + + for ( DebugTarget target : activeDebugTargets ) + { + message = String.format( ". . Target: %s", target.name() ); + sender.sendMessage( message ); + } + } + + Set selectiveDebugTargets = Output.get().getSelectiveDebugTargets(); + + if ( selectiveDebugTargets.size() > 0 ) { + message = ". Selective Debug Targets:"; + sender.sendMessage( message ); + + for ( DebugTarget target : selectiveDebugTargets ) + { + message = String.format( ". . Target: %s", target.name() ); + sender.sendMessage( message ); + } + } + + String validTargets = Output.get().getDebugTargetsString(); + message = String.format( ". Valid Targets: %s", validTargets ); + sender.sendMessage( message ); } @@ -1317,10 +1052,10 @@ public void findCommand(CommandSender sender, @Arg(name = "command", description = "The command to search for" ) String command ) { - String registered = Prison.get().getCommandHandler().findRegisteredCommand( command ); - - Output.get().logInfo( "&7Prison Find Registered Command: original= &3%s &7registered= &3%s", - command, registered ); + String registered = Prison.get().getCommandHandler().findRegisteredCommand( command ); + + Output.get().logInfo( "&7Prison Find Registered Command: original= &3%s &7registered= &3%s", + command, registered ); } @@ -1330,10 +1065,10 @@ public void findCommand(CommandSender sender, onlyPlayers = false, permissions = "prison.debug" ) public void statsCommand(CommandSender sender ) { - List cmds = getCommandStats(); - for (String cmd : cmds) { - - Output.get().logInfo( cmd ); + List cmds = getCommandStats(); + for (String cmd : cmds) { + + Output.get().logInfo( cmd ); } } @@ -1343,47 +1078,47 @@ private List getCommandStats() { 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%7s&r &a&n%-11s&r", - " Commands ", " Usage "," Alias ", " Avg ms ") ); - - int count = 0; - int totals = 0; - int totalsAlias = 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%7s &2%11s", - cmd.getCompleteLabel(), - iFmt.format( cmd.getUsageCount() ), - iFmt.format( cmd.getUsageCountAlias() ), - dFmt.format( duration ) - ) ); - count++; - totals += cmd.getUsageCount(); - totalsAlias += cmd.getUsageCountAlias(); - totalDuration += cmd.getUsageRunTimeNanos(); - } + 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%7s&r &a&n%-11s&r", + " Commands ", " Usage "," Alias ", " Avg ms ") ); + + int count = 0; + int totals = 0; + int totalsAlias = 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%7s &2%11s", + cmd.getCompleteLabel(), + iFmt.format( cmd.getUsageCount() ), + iFmt.format( cmd.getUsageCountAlias() ), + dFmt.format( duration ) + ) ); + count++; + totals += cmd.getUsageCount(); + totalsAlias += cmd.getUsageCountAlias(); + 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 )) ); - results.add( Output.stringFormat(" &3Total Prison Command Alias Usage: &7%9s", iFmt.format( totalsAlias )) ); - - 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. " ); - - + 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 )) ); + results.add( Output.stringFormat(" &3Total Prison Command Alias Usage: &7%9s", iFmt.format( totalsAlias )) ); + + 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; } @@ -1405,20 +1140,20 @@ public void runCommand(CommandSender sender, ) { - if ( playerName == null || playerName.isEmpty() ) { - - coreRunCommandNameRequiredMsg(sender); - - return; - } - - if ( command == null || command.trim().length() == 0 ) { - coreRunCommandCommandRequiredMsg(sender); - } - - Player player = getPlayer( playerName ); - - PrisonAPI.dispatchCommand( player, command ); + if ( playerName == null || playerName.isEmpty() ) { + + coreRunCommandNameRequiredMsg(sender); + + return; + } + + if ( command == null || command.trim().length() == 0 ) { + coreRunCommandCommandRequiredMsg(sender); + } + + Player player = getPlayer( playerName ); + + PrisonAPI.dispatchCommand( player, command ); } @@ -1435,15 +1170,15 @@ public void supportSetName(CommandSender sender, String supportName ) { - if ( supportName == null || supportName.trim().isEmpty() ) { - sender.sendMessage( "A value for supportName is required." ); - return; - } - - setSupportName( supportName ); - - sender.sendMessage( String.format( "The support name has been set to: %s", getSupportName() ) ); - sender.sendMessage( "You can now use the support submit options." ); + if ( supportName == null || supportName.trim().isEmpty() ) { + sender.sendMessage( "A value for supportName is required." ); + return; + } + + setSupportName( supportName ); + + sender.sendMessage( String.format( "The support name has been set to: %s", getSupportName() ) ); + sender.sendMessage( "You can now use the support submit options." ); } @@ -1462,54 +1197,54 @@ public void supportSaveToFile(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; - } - - - 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" ) ) { - - StringBuilder text = Prison.get().getPrisonStatsUtil().getSupportSubmitBasic(); - - 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." ); - sender.sendMessage( getSupportFile().getFileStats( text.length() ) ); - -// supportSubmitVersion(sender); -// supportSubmitRanks(sender); -// supportSubmitMines(sender); -// supportSubmitConfigs(sender); - } - } - else { - sender.sendMessage( "Support save file has been disabled. Support files have not been removed." ); - } + 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 saved to files." ); + + sender.sendMessage( " Your support save file location: " + + getSupportFile().getSupportFile().getAbsolutePath() ); + + if ( options.toLowerCase().equals( "basic" ) ) { + + StringBuilder text = Prison.get().getPrisonStatsUtil().getSupportSubmitBasic(); + + 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." ); + sender.sendMessage( getSupportFile().getFileStats( text.length() ) ); + + // supportSubmitVersion(sender); + // supportSubmitRanks(sender); + // supportSubmitMines(sender); + // supportSubmitConfigs(sender); + } + } + else { + sender.sendMessage( "Support save file has been disabled. Support files have not been removed." ); + } } @@ -1519,9 +1254,9 @@ public void supportSaveToFile(CommandSender sender, public void supportColorTest(CommandSender sender ) { - StringBuilder sb = Prison.get().getPrisonStatsUtil().getColorTest(); - - for (String line : sb.toString().split("\n")) { + StringBuilder sb = Prison.get().getPrisonStatsUtil().getColorTest(); + + for (String line : sb.toString().split("\n")) { Output.get().logInfo(line); } } @@ -1533,158 +1268,94 @@ public void supportColorTest(CommandSender sender public void supportSubmitVersion(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 = 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 ) { - // Convert `{br}` to `\n`: - text.replace(idx, idx+4, "\n"); - - idx = text.indexOf("{br}"); - } + + 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 = 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 ) { + // Convert `{br}` to `\n`: + text.replace(idx, idx+4, "\n"); + + idx = text.indexOf("{br}"); + } // Add all of the listeners details: - text.append( "\n\n" ); - text.append( - Prison.get().getPrisonStatsUtil().getSupportSubmitListenersData( "all" ) - ); - - // Include the command stats: - text.append( Prison.get().getPrisonStatsUtil().getCommandStatsDetailData() ); -// text.append( "\n\n" ); -// List cmdStats = getCommandStats(); -// for (String cmd : cmdStats) { -// text.append( cmd ).append( "\n" ); -// } + text.append( "\n\n" ); + text.append( + Prison.get().getPrisonStatsUtil().getSupportSubmitListenersData( "all" ) + ); + + // Include the command stats: + text.append( Prison.get().getPrisonStatsUtil().getCommandStatsDetailData() ); - // Include Prison backup logs: - 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" ); -// } + // Include Prison backup logs: + text.append( Prison.get().getPrisonStatsUtil().getPrisonBackupLogsData() ); - text.append( Prison.get().getPrisonStatsUtil().getSupportSubmitConfigsData() ); - - - - if ( getSupportFile() != null ) { - - getSupportFile().saveToSupportFile( text, getSupportName() ); - - 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 = "(Failure in running the commmand.)"; - - try { - helpURL = pasteChat.post( text.toString() ); - } - catch (Exception e) { - Output.get().logRaw( - - String.format( - "Failed to paste support info to the support server: %s " - + "raw message: [%s]", - e.getMessage(), - 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." ); - } - - } - + text.append( Prison.get().getPrisonStatsUtil().getSupportSubmitConfigsData() ); + + + + if ( getSupportFile() != null ) { + + getSupportFile().saveToSupportFile( text, getSupportName() ); + + 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 = "(Failure in running the commmand.)"; + + try { + helpURL = pasteChat.post( text.toString() ); + } + catch (Exception e) { + Output.get().logRaw( + + String.format( + "Failed to paste support info to the support server: %s " + + "raw message: [%s]", + e.getMessage(), + 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." ); + } + + } } - -// @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", description = "For Prison support: This will copy the contents of Prison's " + @@ -1695,47 +1366,47 @@ public void supportSubmitRanks(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; - } - - - // List Ladder and rank lists: - StringBuilder text = Prison.get().getPrisonStatsUtil().getSupportSubmitRanksData(); - - // List rank files: - text.append( Prison.get().getPrisonStatsUtil().getSupportSubmitRanksFileData() ); - - - if ( getSupportFile() != null ) { - - getSupportFile().saveToSupportFile( text, getSupportName() ); - - sender.sendMessage(" - Support 'ranks' 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 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." ); - } - } - + 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; + } + + + // List Ladder and rank lists: + StringBuilder text = Prison.get().getPrisonStatsUtil().getSupportSubmitRanksData(); + + // List rank files: + text.append( Prison.get().getPrisonStatsUtil().getSupportSubmitRanksFileData() ); + + + if ( getSupportFile() != null ) { + + getSupportFile().saveToSupportFile( text, getSupportName() ); + + sender.sendMessage(" - Support 'ranks' 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 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." ); + } + } + } @@ -1749,42 +1420,42 @@ public void supportSubmitMines(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().getSupportSubmitMinesData(); - - - if ( getSupportFile() != null ) { - - getSupportFile().saveToSupportFile( text, getSupportName() ); - - sender.sendMessage(" - Support 'mines' 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 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." ); - } - } + 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().getSupportSubmitMinesData(); + + + if ( getSupportFile() != null ) { + + getSupportFile().saveToSupportFile( text, getSupportName() ); + + sender.sendMessage(" - Support 'mines' 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 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." ); + } + } } @@ -1797,172 +1468,14 @@ public void supportSubmitMines(CommandSender sender onlyPlayers = false, permissions = "prison.debug" ) public void backpacksListOldCmd(CommandSender sender ) { - - BackpackConverterOldPrisonBackpacks converter = new BackpackConverterOldPrisonBackpacks(); - - converter.convertOldBackpacks(); - + + BackpackConverterOldPrisonBackpacks converter = new BackpackConverterOldPrisonBackpacks(); + + converter.convertOldBackpacks(); } - - -// -// private StringBuilder getSupportSubmitVersionData() { -// ChatDisplay display = displayVersion("ALL"); -// StringBuilder text = display.toStringBuilder(); -// return text; -// } -// -// private StringBuilder getSupportSubmitConfigsData() { -// Prison.get().getPlatform().saveResource( "plugin.yml", true ); -// -// String fileNames = "config.yml plugin.yml backups/versions.txt " + -// "autoFeaturesConfig.yml blockConvertersConfig.json " + -// "modules.yml module_conf/mines/config.json module_conf/mines/mineBombsConfig.json " + -// "SellAllConfig.yml GuiConfig.yml backpacks/backpacksconfig.yml"; -// List files = convertNamesToFiles( fileNames ); -// -// -// StringBuilder text = new StringBuilder(); -// -// for ( File file : files ) { -// -// addFileToText( file, text ); -// -// if ( file.getName().equalsIgnoreCase( "plugin.yml" ) ) { -// file.delete(); -// } -// } -// return text; -// } -// -// -// private StringBuilder getSupportSubmitRanksData() { -// 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 ) { -// -// addFileToText( file, text ); -// -// } -// return text; -// } -// -// -// private StringBuilder getSupportSubmitMinesData() { -// 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" ); -// -// // Display a list of all mines, then display the /mines info all for each: -// text.append( Prison.get().getPlatform().getMinesListString() ); -// printFooter( text ); -// -// -// -// for ( File file : files ) { -// -// addFileToText( file, text ); -// -// } -// return text; -// } - - -// private List listFiles( String path, String fileSuffix ) { -// List files = new ArrayList<>(); -// -// File dataFolder = Prison.get().getDataFolder(); -// File filePaths = new File( dataFolder, path ); -// -// for ( File file : filePaths.listFiles() ) { -// if ( file.getName().toLowerCase().endsWith( fileSuffix.toLowerCase() )) { -// files.add( file ); -// } -// } -// -// return files; -// } -// -// private void addFileToText( File file, StringBuilder sb ) -// { -// DecimalFormat dFmt = Prison.get().getDecimalFormatInt(); -// SimpleDateFormat sdFmt = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ); -// -// sb.append( "\n" ); -// -// JumboTextFont.makeJumboFontText( file.getName(), sb ); -// -// sb.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 " : "" ) -// .append( file.canWrite() ? "WRITEABLE " : "" ) -// .append( "\n" ); -// -// sb.append( "\n" ); -// sb.append( "=== --- --- --- --- --- --- --- --- --- ===\n" ); -// sb.append( "\n" ); -// -// -// if ( file.exists() && file.canRead() ) { -// readFileToStringBulider( file, sb ); -// } -// else { -// sb.append( "Warning: The file is not readable so it cannot be included.\n" ); -// } -// -// -// printFooter( sb ); -// } - -// public static void printFooter( StringBuilder sb ) { -// -// sb.append( "\n\n\n" ); -// sb.append( "=== --- === --- === --- === --- === --- ===\n" ); -// sb.append( "=== # # ### # # # ### # # # ### # # # ### # # # ### # # ===\n" ); -// sb.append( "=== --- === --- === --- === --- === --- ===\n" ); -// sb.append( "\n\n" ); -// -// } -// -// private List convertNamesToFiles( String fileNames ) -// { -// List files = new ArrayList<>(); -// -// File dataFolder = Prison.get().getDataFolder(); -// -// for ( String fileName : fileNames.split( " " )) { -// File file = new File( dataFolder, fileName ); -// files.add( file ); -// } -// -// return files; -// } @Command(identifier = "prison support submit latestLog", description = "For Prison support: This will copy the contents of `logs/latest.log` " + @@ -1972,49 +1485,49 @@ public void supportSubmitLatestLog(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; - } - - - File latestLogFile = new File( Prison.get().getDataFolder().getParentFile().getParentFile(), - "logs/latest.log"); - - sender.sendMessage( "### log path: " + latestLogFile.getAbsolutePath() ); - - - StringBuilder logText = new StringBuilder(); - - if ( latestLogFile.exists() && latestLogFile.canRead() ) { - - readFileToStringBulider( latestLogFile, logText ); - - if ( logText != null ) { - - PrisonPasteChat pasteChat = new PrisonPasteChat( getSupportName(), getSupportURLs() ); - - String helpURL = pasteChat.post( logText.toString() ); - - getSupportURLs().put( "Submit lastlog:", 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 { - // Do nothing since if helpURL is null, then it has probably - // already sent an error message. - } - return; - } - } - - sender.sendMessage( "Unable to send log file. Unknown reason why." ); + 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; + } + + + File latestLogFile = new File( Prison.get().getDataFolder().getParentFile().getParentFile(), + "logs/latest.log"); + + sender.sendMessage( "### log path: " + latestLogFile.getAbsolutePath() ); + + + StringBuilder logText = new StringBuilder(); + + if ( latestLogFile.exists() && latestLogFile.canRead() ) { + + readFileToStringBulider( latestLogFile, logText ); + + if ( logText != null ) { + + PrisonPasteChat pasteChat = new PrisonPasteChat( getSupportName(), getSupportURLs() ); + + String helpURL = pasteChat.post( logText.toString() ); + + getSupportURLs().put( "Submit lastlog:", 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 { + // Do nothing since if helpURL is null, then it has probably + // already sent an error message. + } + return; + } + } + + sender.sendMessage( "Unable to send log file. Unknown reason why." ); } private void readFileToStringBulider( File textFile, StringBuilder text ) @@ -2049,46 +1562,6 @@ 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 listeners", description = "For Prison support: Provide a 'dump' of all event listeners.", @@ -2111,29 +1584,6 @@ public void supportListenersDump(CommandSender sender, String results = Prison.get().getPrisonStatsUtil().getSupportSubmitListenersData( listener ).toString(); -// String results = null; -// -// if ( "blockBreak".equalsIgnoreCase( listener ) ) { -// -// results = Prison.get().getPlatform().dumpEventListenersBlockBreakEvents(); -// } -// -// if ( "chat".equalsIgnoreCase( listener ) ) { -// -// results = Prison.get().getPlatform().dumpEventListenersPlayerChatEvents(); -// } -// -// if ( "traceBlockBreak".equalsIgnoreCase( listener ) ) { -// -// Prison.get().getPlatform().traceEventListenersBlockBreakEvents( sender ); -// -// return; -// } -// -// if ( "playerInteract".equalsIgnoreCase( listener ) ) { -// -// results = Prison.get().getPlatform().dumpEventListenersPlayerInteractEvents(); -// } if ( results != null ) { @@ -2161,12 +1611,12 @@ public void supportBackupPrison( CommandSender sender, + "first 20 characters will be used.", def = "") String notes ) { - PrisonBackups prisonBackup = new PrisonBackups(); - - String message = prisonBackup.startBackup( BackupTypes.manual, notes ); - - sender.sendMessage( message ); - sender.sendMessage( "Backup finished." ); + PrisonBackups prisonBackup = new PrisonBackups(); + + String message = prisonBackup.startBackup( BackupTypes.manual, notes ); + + sender.sendMessage( message ); + sender.sendMessage( "Backup finished." ); } @@ -2179,24 +1629,18 @@ public void supportBackupPrison( CommandSender sender, onlyPlayers = false, permissions = "prison.debug" ) public void supportBackupList( CommandSender sender ) { - ChatDisplay display = new ChatDisplay("Prison Backup Logs:"); - - List backupLogs = Prison.get().getPrisonStatsUtil().getPrisonBackupLogs(); -// List backupLogs = getPrisonBackupLogs(); - - for (String log : backupLogs) { - display.addText(log); - } - - display.send(sender); + ChatDisplay display = new ChatDisplay("Prison Backup Logs:"); + + List backupLogs = Prison.get().getPrisonStatsUtil().getPrisonBackupLogs(); + + for (String log : backupLogs) { + display.addText(log); + } + + display.send(sender); } -// private List getPrisonBackupLogs() { -// PrisonBackups prisonBackup = new PrisonBackups(); -// List backupLogs = prisonBackup.backupReport02BackupLog(); -// return backupLogs; -// } @Command(identifier = "prison tokens balance", @@ -2211,50 +1655,37 @@ public void tokensBalance(CommandSender sender, "another player.") String playerName ) { - Player player = getPlayer( sender ); - - // If player is null, then need to use the playerName, so if it's empty, we have a problem: - if ( ( player == null || !player.isOnline() ) && - ( playerName == null || playerName.isEmpty() ) ) { - - coreTokensNameRequiredMsg(sender); -// String message = "Prison Tokens: A player's name is required when used from console."; -// -// Output.get().logWarn( message ); - return; - } - else - if ( playerName != null && !playerName.isEmpty() ){ - - if ( !sender.isOp() && - !sender.hasPermission( "tokens.bal.others" ) ) { - coreTokensBalanceCannotViewOthersMsg(sender); -// String message = "Prison Tokens: You do not have permission to view other " + -// "player's balances."; -// Output.get().logWarn( message ); - return; - } - - Player tempPlayer = getPlayer( playerName ); - - if ( tempPlayer != null ) { - player = tempPlayer; - } - } - - -// player.getPlayerCache() + Player player = getPlayer( sender ); + + // If player is null, then need to use the playerName, so if it's empty, we have a problem: + if ( ( player == null || !player.isOnline() ) && + ( playerName == null || playerName.isEmpty() ) ) { + + coreTokensNameRequiredMsg(sender); + return; + } + else + if ( playerName != null && !playerName.isEmpty() ){ + + if ( !sender.isOp() && + !sender.hasPermission( "tokens.bal.others" ) ) { + coreTokensBalanceCannotViewOthersMsg(sender); + return; + } + + Player tempPlayer = getPlayer( playerName ); + + if ( tempPlayer != null ) { + player = tempPlayer; + } + } + + + + long tokens = player.getPlayerCachePlayerData().getTokens(); + + coreTokensBalanceViewMsg( sender, player.getName(), tokens ); - long tokens = player.getPlayerCachePlayerData().getTokens(); - - coreTokensBalanceViewMsg( sender, player.getName(), tokens ); - -// DecimalFormat dFmt = Prison.get().getDecimalFormatInt(); -// String tokensMsg = dFmt.format( tokens ); -// -// String message = String.format( "&3%s has %s tokens.", player.getName(), tokensMsg ); -// -// sender.sendMessage( message ); } @Command(identifier = "prison tokens add", @@ -2279,88 +1710,75 @@ public void tokensAdd( CommandSender sender, def = "") String options ) { - boolean silent = options != null && options.toLowerCase().contains( "silent" ); - boolean forcePlayer = options != null && options.toLowerCase().contains( "forceplayer" ); - - if ( playerName == null || playerName.isEmpty() ) { - - if ( !silent ) { - coreTokensNameRequiredMsg(sender); -// String message = "Prison Tokens: A player's name is required."; -// Output.get().logWarn( message ); - } - - return; - } - -// DecimalFormat dFmt = Prison.get().getDecimalFormatInt(); - - if ( amount <= 0 ) { - - if ( !silent ) { - coreTokensAddInvalidAmountMsg( sender, amount ); -// String message = -// String.format( -// "Prison Tokens: Invalid amount: '%s'. Must be greater than zero.", -// dFmt.format( amount ) ); -// Output.get().logWarn( message ); - } - - return; - } - - Player player = getPlayer( playerName ); - - if ( player == null ) { - if ( !silent ) { - sender.sendMessage( - String.format( - "Prison Tokens add: Player name not found. [%s] (hardCodedMessag)", - playerName )); - } - return; - } - - - PlayerCachePlayerData pCache = player.getPlayerCachePlayerData(); - - long tokenBal = pCache.getTokens(); - - if ( forcePlayer ) { - - pCache.addTokens( amount ); - } - else { - - pCache.addTokensAdmin( amount ); - } - - if ( pCache.getTokens() != tokenBal + amount && Output.get().isDebug() ) { - Output.get().logError( - String.format( - "AddTokens failure: player: %s Tokens: %d Should have been: %d", - player.getName(), pCache.getTokens(), tokenBal + amount )); - } - - if ( !silent ) { - - String message = coreTokensAddedAmountMsg( player.getName(), - pCache.getTokens(), amount ); - -// String tokens = dFmt.format( player.getPlayerCachePlayerData().getTokens() ); -// -// String message = String.format( "&3%s now has &7%s &3tokens after adding &7%s&3.", -// player.getName(), tokens, dFmt.format( amount ) ); - - // The person adding the tokens, or console: - sender.sendMessage( message ); - - // The player getting the tokens, if they are online: - if ( player.isOnline() && !player.getName().equalsIgnoreCase( sender.getName() ) ) { - - player.sendMessage( message ); - } - } + boolean silent = options != null && options.toLowerCase().contains( "silent" ); + boolean forcePlayer = options != null && options.toLowerCase().contains( "forceplayer" ); + + if ( playerName == null || playerName.isEmpty() ) { + + if ( !silent ) { + coreTokensNameRequiredMsg(sender); + } + + return; + } + + + if ( amount <= 0 ) { + + if ( !silent ) { + coreTokensAddInvalidAmountMsg( sender, amount ); + } + + return; + } + + Player player = getPlayer( playerName ); + + if ( player == null ) { + if ( !silent ) { + sender.sendMessage( + String.format( + "Prison Tokens add: Player name not found. [%s] (hardCodedMessag)", + playerName )); + } + return; + } + + + PlayerCachePlayerData pCache = player.getPlayerCachePlayerData(); + + long tokenBal = pCache.getTokens(); + + if ( forcePlayer ) { + + pCache.addTokens( amount ); + } + else { + + pCache.addTokensAdmin( amount ); + } + + if ( pCache.getTokens() != tokenBal + amount && Output.get().isDebug() ) { + Output.get().logError( + String.format( + "AddTokens failure: player: %s Tokens: %d Should have been: %d", + player.getName(), pCache.getTokens(), tokenBal + amount )); + } + + if ( !silent ) { + + String message = coreTokensAddedAmountMsg( player.getName(), + pCache.getTokens(), amount ); + + // The person adding the tokens, or console: + sender.sendMessage( message ); + + // The player getting the tokens, if they are online: + if ( player.isOnline() && !player.getName().equalsIgnoreCase( sender.getName() ) ) { + + player.sendMessage( message ); + } + } } @@ -2389,78 +1807,66 @@ public void tokensRemove( CommandSender sender, def = "") String options ) { - boolean silent = options != null && options.toLowerCase().contains( "silent" ); - boolean forcePlayer = options != null && options.toLowerCase().contains( "forceplayer" ); - - if ( playerName == null || playerName.isEmpty() ) { - - if ( !silent ) { - coreTokensNameRequiredMsg(sender); -// String message = "Prison Tokens: A player's name is required."; -// Output.get().logWarn( message ); - } - - return; - } - -// DecimalFormat dFmt = Prison.get().getDecimalFormatInt(); - - if ( amount <= 0 ) { - - if ( !silent ) { - coreTokensAddInvalidAmountMsg( sender, amount ); -// String message = -// String.format( -// "Prison Tokens: Invalid amount: '%s'. Must be greater than zero.", -// dFmt.format( amount ) ); -// Output.get().logWarn( message ); - } - - return; - } - - 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 ); - } - else { - - player.getPlayerCachePlayerData().removeTokensAdmin( amount ); - } - - - if ( !silent ) { - - String message = coreTokensRemovedAmountMsg( player.getName(), - player.getPlayerCachePlayerData().getTokens(), amount ); -// String tokens = dFmt.format( player.getPlayerCachePlayerData().getTokens() ); -// -// String message = String.format( "&3%s now has &7%s &3tokens after removing &7%s&3.", -// player.getName(), tokens, dFmt.format( amount ) ); - - // The person adding the tokens, or console: - sender.sendMessage( message ); - - // The player getting the tokens, if they are online: - if ( player.isOnline() && !player.getName().equalsIgnoreCase( sender.getName() ) ) { - - player.sendMessage( message ); - } - } + boolean silent = options != null && options.toLowerCase().contains( "silent" ); + boolean forcePlayer = options != null && options.toLowerCase().contains( "forceplayer" ); + + if ( playerName == null || playerName.isEmpty() ) { + + if ( !silent ) { + coreTokensNameRequiredMsg(sender); + } + + return; + } + + + if ( amount <= 0 ) { + + if ( !silent ) { + coreTokensAddInvalidAmountMsg( sender, amount ); + } + + return; + } + + 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 ); + } + else { + + player.getPlayerCachePlayerData().removeTokensAdmin( amount ); + } + + + if ( !silent ) { + + String message = coreTokensRemovedAmountMsg( player.getName(), + player.getPlayerCachePlayerData().getTokens(), amount ); + + // The person adding the tokens, or console: + sender.sendMessage( message ); + + // The player getting the tokens, if they are online: + if ( player.isOnline() && !player.getName().equalsIgnoreCase( sender.getName() ) ) { + + player.sendMessage( message ); + } + } } @Command(identifier = "prison tokens set", @@ -2489,67 +1895,57 @@ public void tokensSet( CommandSender sender, def = "") String options ) { - boolean silent = options != null && options.toLowerCase().contains( "silent" ); - boolean forcePlayer = options != null && options.toLowerCase().contains( "forceplayer" ); - - if ( playerName == null || playerName.isEmpty() ) { - - if ( !silent ) { - coreTokensNameRequiredMsg(sender); -// String message = "Prison Tokens: A player's name is required."; -// Output.get().logWarn( message ); - } - - return; - } - -// 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(); -// player.getPlayerCachePlayerData().removeTokensAdmin( totalTokens ); - - if ( forcePlayer ) { - - player.getPlayerCachePlayerData().setTokens( amount ); - } - else { - - player.getPlayerCachePlayerData().setTokensAdmin( amount ); - } - - if ( !silent ) { - - String message = coreTokensSetAmountMsg( player.getName(), - player.getPlayerCachePlayerData().getTokens() ); - -// String tokens = dFmt.format( player.getPlayerCachePlayerData().getTokens() ); -// -// String message = String.format( "&3%s now has &7%s &3tokens.", -// player.getName(), tokens ); - - // The person adding the tokens, or console: - sender.sendMessage( message ); - - // The player getting the tokens, if they are online: - if ( player.isOnline() && !player.getName().equalsIgnoreCase( sender.getName() ) ) { - - player.sendMessage( message ); - } - } + boolean silent = options != null && options.toLowerCase().contains( "silent" ); + boolean forcePlayer = options != null && options.toLowerCase().contains( "forceplayer" ); + + if ( playerName == null || playerName.isEmpty() ) { + + if ( !silent ) { + coreTokensNameRequiredMsg(sender); + } + + return; + } + + + Player player = getPlayer( playerName ); + + + if ( player == null ) { + if ( !silent ) { + sender.sendMessage( + String.format( + "Prison Tokens set: Player name not found. [%s] (hardCodedMessag)", + playerName )); + } + return; + } + + + if ( forcePlayer ) { + + player.getPlayerCachePlayerData().setTokens( amount ); + } + else { + + player.getPlayerCachePlayerData().setTokensAdmin( amount ); + } + + if ( !silent ) { + + String message = coreTokensSetAmountMsg( player.getName(), + player.getPlayerCachePlayerData().getTokens() ); + + + // The person adding the tokens, or console: + sender.sendMessage( message ); + + // The player getting the tokens, if they are online: + if ( player.isOnline() && !player.getName().equalsIgnoreCase( sender.getName() ) ) { + + player.sendMessage( message ); + } + } } @@ -2572,7 +1968,6 @@ private Player getPlayer( String playerName ) { if ( player == null ) { player = Prison.get().getPlatform().getRankPlayer( null, playerName ); -// player = Prison.get().getPlatform().getOfflinePlayer( playerName ).orElse( null ); } return player; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/PrisonCommandMessages.java b/prison-core/src/main/java/tech/mcprison/prison/PrisonCommandMessages.java index cc6ebeae2..7b6322b6d 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/PrisonCommandMessages.java +++ b/prison-core/src/main/java/tech/mcprison/prison/PrisonCommandMessages.java @@ -87,10 +87,10 @@ protected String coreTokensRemovedAmountMsg( String amountMsg = dFmt.format( amount ); return Prison.get().getLocaleManager() - .getLocalizable( "core_tokens__removed_amount" ) - .setFailSilently() - .withReplacements( name, tokensMsg, amountMsg ) - .localize(); + .getLocalizable( "core_tokens__removed_amount" ) + .setFailSilently() + .withReplacements( name, tokensMsg, amountMsg ) + .localize(); } protected String coreTokensSetAmountMsg( @@ -118,9 +118,9 @@ protected void coreRunCommandNameRequiredMsg( CommandSender sender ) { protected void coreRunCommandCommandRequiredMsg( CommandSender sender ) { Prison.get().getLocaleManager() - .getLocalizable( "core_runCmd__command_required" ) - .setFailSilently() - .sendTo( sender ); + .getLocalizable( "core_runCmd__command_required" ) + .setFailSilently() + .sendTo( sender ); } diff --git a/prison-core/src/main/java/tech/mcprison/prison/alerts/AlertCommands.java b/prison-core/src/main/java/tech/mcprison/prison/alerts/AlertCommands.java index 004fac60d..0c44ddc99 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/alerts/AlertCommands.java +++ b/prison-core/src/main/java/tech/mcprison/prison/alerts/AlertCommands.java @@ -23,38 +23,33 @@ public AlertCommands() { @Command(identifier = "prison alerts", description = "Lists your alerts.", permissions = "prison.alerts", onlyPlayers = false ) public void prisonAlertsCommand(CommandSender sender) { -// if (!(sender instanceof Player)) { -// Prison.get().getLocaleManager().getLocalizable("cantAsConsole") -// .sendTo(sender, LogLevel.ERROR); -// return; -// } - List alerts = new ArrayList<>(); - - ChatDisplay display = new ChatDisplay("Alerts"); - - BulletedListComponent.BulletedListBuilder builder = - new BulletedListComponent.BulletedListBuilder(); + List alerts = new ArrayList<>(); + + ChatDisplay display = new ChatDisplay("Alerts"); + + BulletedListComponent.BulletedListBuilder builder = + new BulletedListComponent.BulletedListBuilder(); if ((sender instanceof Player)) { - Player player = (Player) sender; - - alerts = Alerts.getInstance().getAlertsFor(player.getUUID()); + Player player = (Player) sender; + + alerts = Alerts.getInstance().getAlertsFor(player.getUUID()); } alerts.forEach(alert -> builder.add(alert.message)); display.addComponent(builder.build()); if (alerts.size() == 0) { - Output.get().sendInfo(sender, "There are no alerts."); + Output.get().sendInfo(sender, "There are no alerts."); } else { - display.addText("&8Type /prison alerts clear to clear your alerts."); - display.addText("&8Type /prison alerts clearall to clear everyone's alerts."); - - display.send(sender); + display.addText("&8Type /prison alerts clear to clear your alerts."); + display.addText("&8Type /prison alerts clearall to clear everyone's alerts."); + + display.send(sender); } } @@ -63,11 +58,9 @@ public void prisonAlertsCommand(CommandSender sender) { public void prisonAlertsClearCommand(CommandSender sender) { if (!(sender instanceof Player)) { - // If console, then clear all since there is no "Player" to use: - prisonAlertsClearAllCommand( sender ); -// Prison.get().getLocaleManager().getLocalizable("cantAsConsole") -// .sendTo(sender, LogLevel.ERROR); - return; + // If console, then clear all since there is no "Player" to use: + prisonAlertsClearAllCommand( sender ); + return; } Player player = (Player) sender; @@ -85,12 +78,6 @@ public void prisonAlertsClearCommand(CommandSender sender) { description = "Clears the alerts for the whole server.", permissions = "prison.alerts.clear.all", onlyPlayers = false ) public void prisonAlertsClearAllCommand(CommandSender sender) { -// if (!(sender instanceof Player)) { -// Prison.get().getLocaleManager().getLocalizable("cantAsConsole") -// .sendTo(sender, LogLevel.ERROR); -// return; -// } -// Player player = (Player) sender; Alerts.getInstance().clearAll(); Output.get().sendInfo(sender, "All alerts have been cleared."); diff --git a/prison-core/src/main/java/tech/mcprison/prison/alerts/Alerts.java b/prison-core/src/main/java/tech/mcprison/prison/alerts/Alerts.java index 223bce9bc..3236814fe 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/alerts/Alerts.java +++ b/prison-core/src/main/java/tech/mcprison/prison/alerts/Alerts.java @@ -25,17 +25,10 @@ public class Alerts { public static final long DURATION_ONE_HOUR = DURATION_ONE_MINUTE * 60; - /* - * Variables & Constants - */ - private static Alerts instance; private List alerts; - /* - * Constructor - */ - + private Alerts() { alerts = new ArrayList<>(); @@ -43,9 +36,6 @@ private Alerts() { Prison.get().getEventBus().register(this); } - /* - * Methods - */ public static Alerts getInstance() { if (instance == null) { @@ -97,9 +87,6 @@ public void clearAll() { alerts.clear(); } - /* - * Listeners - */ public void showAlerts(Player player) { int alerts = Alerts.getInstance().getAlertsFor(player.getUUID()).size(); @@ -110,9 +97,6 @@ public void showAlerts(Player player) { } } - /* - * Getters - */ @Subscribe public void onPlayerJoin(PlayerJoinEvent e) { diff --git a/prison-core/src/main/java/tech/mcprison/prison/backpacks/BackpackCacheEvents.java b/prison-core/src/main/java/tech/mcprison/prison/backpacks/BackpackCacheEvents.java index 2b4e3a1c7..7a5691ae1 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/backpacks/BackpackCacheEvents.java +++ b/prison-core/src/main/java/tech/mcprison/prison/backpacks/BackpackCacheEvents.java @@ -20,8 +20,8 @@ public BackpackCacheEvents() { @Subscribe public void onPlayerJoin(PlayerJoinEvent event) { - Player player = event.getPlayer(); - BackpackCache.getInstance().submitAsyncLoadPlayer( player ); + Player player = event.getPlayer(); + BackpackCache.getInstance().submitAsyncLoadPlayer( player ); } @Subscribe @@ -34,7 +34,7 @@ public void onPlayerQuit(PlayerQuitEvent event) { @Subscribe public void onPlayerKicked(PlayerKickEvent event) { - Player player = event.getPlayer(); - BackpackCache.getInstance().submitAsyncUnloadPlayer( player ); + Player player = event.getPlayer(); + BackpackCache.getInstance().submitAsyncUnloadPlayer( player ); } } diff --git a/prison-core/src/main/java/tech/mcprison/prison/backpacks/BackpackCacheLoadPlayerTask.java b/prison-core/src/main/java/tech/mcprison/prison/backpacks/BackpackCacheLoadPlayerTask.java index 7d1de58a2..f341b07d6 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/backpacks/BackpackCacheLoadPlayerTask.java +++ b/prison-core/src/main/java/tech/mcprison/prison/backpacks/BackpackCacheLoadPlayerTask.java @@ -17,7 +17,7 @@ public BackpackCacheLoadPlayerTask( Player player ) { public void run() { BackpackCache bCache = BackpackCache.getInstance(); - + BackpackCachePlayerData playerData = bCache.getCacheFiles().fromJson( player ); if ( playerData != null ) { diff --git a/prison-core/src/main/java/tech/mcprison/prison/backpacks/BackpackCachePlayerData.java b/prison-core/src/main/java/tech/mcprison/prison/backpacks/BackpackCachePlayerData.java index 28d692698..ccb299b95 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/backpacks/BackpackCachePlayerData.java +++ b/prison-core/src/main/java/tech/mcprison/prison/backpacks/BackpackCachePlayerData.java @@ -17,13 +17,6 @@ public class BackpackCachePlayerData private transient File playerFile = null; -// /** -// * This Object lock is used to synchronized the public side of this class -// * and the protected side of this class which is the database transaction -// * side of things. -// */ -// @SuppressWarnings( "unused" ) -// private transient final Object lock = new Object(); private transient BackpackCacheRunnable task = null; diff --git a/prison-core/src/main/java/tech/mcprison/prison/backpacks/BackpackCacheSaveAllPlayersTask.java b/prison-core/src/main/java/tech/mcprison/prison/backpacks/BackpackCacheSaveAllPlayersTask.java index 6d2ba01be..5315cd4a0 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/backpacks/BackpackCacheSaveAllPlayersTask.java +++ b/prison-core/src/main/java/tech/mcprison/prison/backpacks/BackpackCacheSaveAllPlayersTask.java @@ -70,7 +70,7 @@ public void run() } } - + synchronized ( bCache.getPlayers() ) { for ( BackpackCachePlayerData playerData : purge ) { diff --git a/prison-core/src/main/java/tech/mcprison/prison/backpacks/BackpackCacheStats.java b/prison-core/src/main/java/tech/mcprison/prison/backpacks/BackpackCacheStats.java index d6ca4d846..2f671aa68 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/backpacks/BackpackCacheStats.java +++ b/prison-core/src/main/java/tech/mcprison/prison/backpacks/BackpackCacheStats.java @@ -57,7 +57,7 @@ public String displayStats() { .append( " synchronizeDatabase=" ).append( getSynchronizeBackpacks() ) ; - + return sb.toString(); } diff --git a/prison-core/src/main/java/tech/mcprison/prison/backpacks/BackpackCacheTask.java b/prison-core/src/main/java/tech/mcprison/prison/backpacks/BackpackCacheTask.java index 4c645d75d..972f2bc6e 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/backpacks/BackpackCacheTask.java +++ b/prison-core/src/main/java/tech/mcprison/prison/backpacks/BackpackCacheTask.java @@ -12,7 +12,7 @@ public BackpackCacheTask( BackpackCachePlayerData backpackData ) { this.backpackData = backpackData; } - + public BackpackCachePlayerData getBackpackData() { return backpackData; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/backpacks/BackpackCacheUnloadPlayerTask.java b/prison-core/src/main/java/tech/mcprison/prison/backpacks/BackpackCacheUnloadPlayerTask.java index d97829ff7..1e71430ea 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/backpacks/BackpackCacheUnloadPlayerTask.java +++ b/prison-core/src/main/java/tech/mcprison/prison/backpacks/BackpackCacheUnloadPlayerTask.java @@ -15,7 +15,7 @@ public void run() { // Remove from the player cache: BackpackCachePlayerData removed = null; - + synchronized ( bCache.getPlayers() ) { removed = bCache.removePlayerData( getBackpackData() ); diff --git a/prison-core/src/main/java/tech/mcprison/prison/backpacks/BackpackConverterOldPrisonBackpacks.java b/prison-core/src/main/java/tech/mcprison/prison/backpacks/BackpackConverterOldPrisonBackpacks.java index a0d41b08c..50b3e7812 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/backpacks/BackpackConverterOldPrisonBackpacks.java +++ b/prison-core/src/main/java/tech/mcprison/prison/backpacks/BackpackConverterOldPrisonBackpacks.java @@ -25,7 +25,6 @@ public void convertOldBackpacks() { Output.get().logInfo( " Old backpack size:", oldBackpacks.size() ); } - } } diff --git a/prison-core/src/main/java/tech/mcprison/prison/backpacks/BackpackEnums.java b/prison-core/src/main/java/tech/mcprison/prison/backpacks/BackpackEnums.java index ffccc9333..3498090bc 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/backpacks/BackpackEnums.java +++ b/prison-core/src/main/java/tech/mcprison/prison/backpacks/BackpackEnums.java @@ -6,7 +6,7 @@ public enum BackpackType { inventory, // Uses standard inventory object, up to 6 rows, 9 stacks each silo; // Up to 54 silos per backpack, which will use a chest to display } - + public enum BackpackFeatures { soulboundBackpack, // If player dies, they keep the backpack soulboundItems, // if soulboundBackpack is enabled, this will preserve items within diff --git a/prison-core/src/main/java/tech/mcprison/prison/backpacks/PlayerBackpack.java b/prison-core/src/main/java/tech/mcprison/prison/backpacks/PlayerBackpack.java index c31cc281d..cdb8e3e5b 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/backpacks/PlayerBackpack.java +++ b/prison-core/src/main/java/tech/mcprison/prison/backpacks/PlayerBackpack.java @@ -23,7 +23,6 @@ public class PlayerBackpack { private BackpackType backpackType; private List inventory; -// private Inventory inventory; private int inventorySize; diff --git a/prison-core/src/main/java/tech/mcprison/prison/backups/PrisonBackups.java b/prison-core/src/main/java/tech/mcprison/prison/backups/PrisonBackups.java index 45678bd39..4a806d03b 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/backups/PrisonBackups.java +++ b/prison-core/src/main/java/tech/mcprison/prison/backups/PrisonBackups.java @@ -196,7 +196,6 @@ public String startBackup( BackupTypes backupType, String notes ) { // The files in the zip file needs to be placed in a directory: -// SimpleDateFormat sdFmt = new SimpleDateFormat( "yyyy-MM-dd_kk-mm" ); String zipFilePrefix = "backup_" + sdFmt.format( backupStartDate ); this.zipFilePrefix = zipFilePrefix; @@ -264,14 +263,9 @@ public String startBackup( BackupTypes backupType, String notes ) { public String backupReport01() { -// DecimalFormat dFmt = Prison.get().getDecimalFormatDouble(); long stop = System.nanoTime(); double runTimeMs = ( stop - getStartTimeNanos() ) / 1000000.0d; -// long size = zipFile.length(); -// double sizeKb = size / 1024.0; - - String msg1 = String.format( "Prison backup:\n" + @@ -491,8 +485,6 @@ public File getNewBackupFile( BackupTypes backupType, String fileNameNotes ) { String prisonVersion = Prison.get().getPlatform().getPluginVersion(); -// SimpleDateFormat sdFmt = new SimpleDateFormat( "yyyy-MM-dd_hh-mm" ); - String fileName = "prison_" + sdFmt.format( new Date() ) + "_v" + prisonVersion + ( backupType == null ? "" : "_" + backupType.name()) + diff --git a/prison-core/src/main/java/tech/mcprison/prison/backups/PrisonSystemSettings.java b/prison-core/src/main/java/tech/mcprison/prison/backups/PrisonSystemSettings.java index 86563d77c..6b98903ac 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/backups/PrisonSystemSettings.java +++ b/prison-core/src/main/java/tech/mcprison/prison/backups/PrisonSystemSettings.java @@ -21,163 +21,10 @@ public class PrisonSystemSettings public static final String PRISON_SYSTEM_SETTING_FRIENDLY_PLAYER_FILE_NAMES = "prison-ranks.use-friendly-user-file-names"; -// private static PrisonSystemSettings instance = null; - -// private TreeMap> settings; - public enum SystemSettingsKey { PlayerFileNameUpdate ; } -// private PrisonSystemSettings() { -// super(); -// -// this.settings = new TreeMap<>(); -// } - - -// public static PrisonSystemSettings getInstance() { -// if ( instance == null ) { -// synchronized ( PrisonSystemSettings.class ) { -// if ( instance == null ) { -// -// instance = new PrisonSystemSettings(); -// } -// } -// } -// -// return instance; -// } - -// /** -// *

    This function should be used to add new root nodes to ensure -// * that they are of type SystemSettingKey values. This functional -// * also adds a TreeMap as it's value pair so it's ready to -// * take on values. -// *

    -// * -// * @param rootKey -// */ -// public void addRootSetting( SystemSettingsKey rootKey ) { -// if ( !getSettings().containsKey( rootKey.name()) ) { -// -// getSettings().put( rootKey.name(), new TreeMap<>() ); -// } -// } -// -// public TreeMap getRootSetting( SystemSettingsKey rootkey ) { -// TreeMap results = null; -// -// if ( getSettings() == null ) { -// load(); -// } -// -// // Try to add the rootKey just in case it does not exist: -// addRootSetting(rootkey); -// -// results = getSettings().get(rootkey.name()); -// -// return results; -// } -// -// private TreeMap> getSettings() { -// if ( settings == null ) { -// this.settings = new TreeMap<>(); -// } -// return settings; -// } -// private void setSettings(TreeMap> settings) { -// this.settings = settings; -// } - - -// public void save() { -// File file = getPrisonSystemSettingsFile(); -// -// JsonFileIO jfIo = new JsonFileIO(); -// -// jfIo.saveJsonFile(file, this); -// } - -// public void load() { -// File file = getPrisonSystemSettingsFile(); -// -// if ( file.exists() ) { -// JsonFileIO jfIo = new JsonFileIO(); -// -// PrisonSystemSettings settings = (PrisonSystemSettings) jfIo.readJsonFile(file, this); -// -// setSettings( settings.getSettings() ); -// -// } -// } - -// public void unload() { -// setSettings( null ); -// } - -// public File getPrisonSystemSettingsFile() { -// -// File dataStoragePath = new File( Prison.get().getDataFolder(), "data_storage" ); -// -// File systemPath = new File( dataStoragePath, "system" ); -// -// systemPath.mkdirs(); -// -// return new File( systemPath, PRISON_SYSTEM_FILENAME ); -// } - - -// /** -// *

    This function will check two things. First will be the config settings within -// * 'config.yml' to see if the new format is enabled. Secondly, it checks to see if -// * the PrisonSystemSettings has recorded if the conversion has taken place. -// * Both have to be true in order for this function to return a value of true., -// *

    -// * -// * @return -// */ -// public static boolean useFriendlyUserFileNames() { -// -// boolean useNewFormat = Prison.get().getPlatform() -// .getConfigBooleanFalse( PRISON_SYSTEM_SETTING_FRIENDLY_PLAYER_FILE_NAMES ); -// -// if ( useNewFormat ) { -// -// boolean converted = checkSystemFriendlyUserFileNamesConverted(); -// -// useNewFormat = converted; -// } -// -// return useNewFormat; -// } - -// /** -// *

    This function specifically returns the value of the 'converted' setting for the -// * 'playerFileNameUpdate' prison system key. -// *

    -// * -// *

    This does not perform any checks on the settings within 'config.yml'. For a full -// * check of both this 'converted' value, and the config settings use the -// * 'useFriendlyUserFileNames()' function instead of this function. -// *

    -// * -// * @return -// */ -// public static boolean checkSystemFriendlyUserFileNamesConverted() { -// -// TreeMap pfnUpdate = -// PrisonSystemSettings.getInstance().getRootSetting( SystemSettingsKey.PlayerFileNameUpdate ); -// -// // Unload the data: -//// PrisonSystemSettings.getInstance().unload(); -// -// boolean converted = !pfnUpdate.containsKey("converted") ? -// false : (Boolean) pfnUpdate.get("converted"); -// -// return converted; -// } - } diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/GeometricShapes.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/GeometricShapes.java index 5f8ced4df..e40ea2c38 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/GeometricShapes.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/GeometricShapes.java @@ -36,7 +36,6 @@ public static void drawCircle( PrisonBlock block, World world, int xi, int yi, i if ( (int) (getDistance( x, z, xi, zi )) == r ) { world.setBlock( block, x, yi, z ); -// world.setBlock( x, yi, z, Block.stone.blockID ); } } } @@ -52,7 +51,6 @@ public static void drawFilledCircle( PrisonBlock block, World world, int xi, int if ( (int) (getDistance( x, z, xi, zi )) <= r ) { world.setBlock( block, x, yi, z ); -// world.setBlock( x, yi, z, Block.stone.blockID ); } } } @@ -69,7 +67,6 @@ public static void drawDisk( PrisonBlock block, World world, int xi, int yi, int if ( dist < outerRadius && dist >= innerRadius ) { world.setBlock( block, x, yi, z ); -// world.setBlock( x, yi, z, Block.stone.blockID ); } } } @@ -160,10 +157,6 @@ public static void wireFrameCube( PrisonBlock block, World world, int xi, int yi world.setBlock( block, i, yi, zi + depth - 1 ); world.setBlock( block, i, yi + height - 1, zi + depth - 1 ); -// world.setBlock( i, yi, zi, id ); -// world.setBlock( i, yi + height - 1, zi, id ); -// world.setBlock( i, yi, zi + depth - 1, id ); -// world.setBlock( i, yi + height - 1, zi + depth - 1, id ); } for ( int i = yi; i < yi + height; i++ ) { @@ -172,10 +165,6 @@ public static void wireFrameCube( PrisonBlock block, World world, int xi, int yi world.setBlock( block, xi, i, zi + depth - 1 ); world.setBlock( block, xi + width - 1, i, zi + depth - 1 ); -// world.setBlock( xi, i, zi, id ); -// world.setBlock( xi + width - 1, i, zi, id ); -// world.setBlock( xi, i, zi + depth - 1, id ); -// world.setBlock( xi + width - 1, i, zi + depth - 1, id ); } for ( int i = zi; i < zi + depth; i++ ) { @@ -184,10 +173,6 @@ public static void wireFrameCube( PrisonBlock block, World world, int xi, int yi world.setBlock( block, xi + width - 1, yi, i ); world.setBlock( block, xi + width - 1, yi + height - 1, i ); -// world.setBlock( xi, yi, i, id ); -// world.setBlock( xi, yi + height - 1, i, id ); -// world.setBlock( xi + width - 1, yi, i, id ); -// world.setBlock( xi + width - 1, yi + height - 1, i, id ); } } @@ -233,34 +218,6 @@ public static void drawTorus( PrisonBlock block, World world, int xi, int yi, in } -// public class Point { -// private double x; -// private double y; -// private double z; -// public Point( double x, double y, double z ) { -// this.x = x; -// this.y = y; -// this.z = z; -// } -// public double getX() { -// return x; -// } -// public void setX(double x) { -// this.x = x; -// } -// public double getY() { -// return y; -// } -// public void setY(double y) { -// this.y = y; -// } -// public double getZ() { -// return z; -// } -// public void setZ(double z) { -// this.z = z; -// } -// } /** * This will calculate a new Vector based upon the degrees (angle), and the diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombCooldownException.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombCooldownException.java index a753417b4..360b4d62b 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombCooldownException.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombCooldownException.java @@ -12,9 +12,6 @@ public class MineBombCooldownException public MineBombCooldownException( int cooldownTicks ) { super( MineBombMessages.mineBombsCoolDownMsg( cooldownTicks ) ); -// super( "Bomb cooldown is in effect. Try again later. Seconds remaining: " + -// Prison.getDecimalFormatStaticDouble().format( cooldownTicks / 20.0d ) -// ); this.cooldownTicks = cooldownTicks; } 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 167fb84e5..92bce3549 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 @@ -24,12 +24,6 @@ public class MineBombData private String description; -// /** -// *

    The 'bombItemId' is first line of the bomb's item lore, and -// * it really needs to be unique and not match any other bomb's id. -// *

    -// */ -// private String loreBombItemId; private List lore; @@ -330,7 +324,6 @@ public MineBombData( String name, String itemType, String explosionShape, this.explosionShape = explosionShape; this.radius = radius; -// this.loreBombItemId = "PrisonMineBomb: " + name; this.lore = new ArrayList<>(); @@ -354,7 +347,6 @@ public MineBombData( String name, String itemType, String explosionShape, this.itemRemovalDelayTicks = 5; this.animationPattern = AnimationPattern.infinity; -// setAnimationPattern( AnimationPattern.infinity ); this.animationSpeed = 5.0; @@ -396,7 +388,6 @@ public MineBombData clone() { MineBombData cloned = new MineBombData( getName(), getItemType(), getExplosionShape(), getRadius() ); -// cloned.setLoreBombItemId( getLoreBombItemId() ); cloned.setDescription( getDescription() ); @@ -570,13 +561,6 @@ public void setDescription( String description ) { this.description = description; } -// public String getLoreBombItemId() { -// return loreBombItemId; -// } -// public void setLoreBombItemId( String loreBombItemId ) { -// this.loreBombItemId = loreBombItemId; -// } - public List getLore() { return lore; } 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 6ff2b14ea..b794ed91d 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 @@ -228,30 +228,6 @@ public static boolean addPlayerCooldown( Player player, int ticks ) { } -// /** -// *

    This finds a bomb with the given name, and returns a clone. The clone is -// * important since individual instances will set the isActivated() variable to -// * true if the bomb is active. If it's activated, then that indicates the -// * bomb will be used and the bomb was removed from the player's inventory. -// *

    -// * -// * @param bombName -// * @return -// */ -// public MineBombData findBomb( String bombName ) { -// MineBombData bombOriginal = null; -// -// if ( bombName != null ) { -// -// // Remove color codes from bomb's name for matching: -// bombName = Text.stripColor( bombName ); -// -// bombOriginal = getConfigData().getBombs().get( bombName.toLowerCase() ); -// } -// -// return bombOriginal.clone(); -// } - public MineBombData findBombByName( Player player, String bombName ) throws MineBombCooldownException { @@ -323,11 +299,6 @@ public MineBombData findBombByName( Player player, String bombName, // The player is still in a cooldown using minebombs, so // return a null instead of the bomb. - //String message = "A mine bomb with the name of %s does not exist."; - -// player.sendMessage( String.format( message, bombName ) ); - - dbug.append( "&3 CoolDownIsInEffect: " ) .append( cooldownTicks ).append( " ticks remaining" ).append(" &aRejected! &3 " ); @@ -541,24 +512,11 @@ public void validateMineBombs() { MineBombData bomb = config.getBombs().get( key ); - // bombItemId is the first line of the lore and should id the bomb: -// String cleanBombItemId = Text.stripColor( bomb.getBombItemId().replace( " ", "" )); -// if ( !cleanBombItemId.equalsIgnoreCase( bomb.getBombItemId() ) ) { -// -// errors.add( String.format( -// "Invalid bombItemId: was: [%s] fixed: [%s].", -// bomb.getBombItemId(), -// cleanBombItemId ) ); -// bomb.setBombItemId( cleanBombItemId ); -// isDirty = true; -// } - // Bomb names can contain color codes now, but not spaces, since that will // mess up commands related to bombs, since the commands would require the bomb names // to not have a space. String cleanName = bomb.getName().replace( " ", "_" ); -// String cleanName = Text.stripColor( bomb.getName().replace( " ", "_" )); if ( !cleanName.equalsIgnoreCase( bomb.getName() ) ) { errors.add( String.format( 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 27dfe96bb..9cd28575f 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 @@ -67,28 +67,6 @@ protected boolean validateMineBombEffects( boolean showWarnings ) { } -// // Check all lore, and if it contains `&#` then process the hex color codes: -// for ( int i = 0; i < bomb.getLore().size(); i++ ) { -// String lore = bomb.getLore().get( i ); -// -// if ( lore != null && lore.contains( "&#") ) { -// String hex = Text.translateAmpColorCodesAltHex2Code( lore ); -// bomb.getLore().set( i, hex ); -// } -// } -// -// // Convert hex colors for bomb names and tags:. -// if ( bomb.getName().contains( "&#" ) ) { -// String hex = Text.translateAmpColorCodesAltHex2Code( bomb.getName() ); -// bomb.setName( hex ); -// } -// if ( bomb.getNameTag().contains( "&#" ) ) { -// String hex = Text.translateAmpColorCodesAltHex2Code( bomb.getNameTag() ); -// bomb.setNameTag( hex ); -// } - - - } return results; diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationOrbital.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationOrbital.java index 0d5e2cf06..8dd5a5291 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationOrbital.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationOrbital.java @@ -78,12 +78,8 @@ else if ( spinValue < -360 ) { -// getArmorStand().get - - Vector vector = GeometricShapes.getPointsOnCircleXZ( angle, radi ); -// Vector vector = GeometricShapes.getPointsOnCircleXZ( angle, radius ); // Location.add() creates a new instance of a Location and does not change // the original value: diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationsTask.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationsTask.java index b20a2be79..c0980e13b 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationsTask.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/animations/BombAnimationsTask.java @@ -55,13 +55,6 @@ public void animatorFactory( // existing bomb configs are not messed up. location.setY( Math.floor( location.getY() + 2 ) ); - // The bomb y adjustments should have been made in this function: - // tech.mcprison.prison.spigot.utils.PrisonUtilsMineBombs.setBombInHand() -// if ( bomb.getPlacementAdjustmentY() != 0 ) { -// -// location.setY( location.getY() + bomb.getPlacementAdjustmentY() ); -// } - if ( Output.get().isDebug() ) { String msg = String.format( diff --git a/prison-core/src/main/java/tech/mcprison/prison/cache/CoreCacheFiles.java b/prison-core/src/main/java/tech/mcprison/prison/cache/CoreCacheFiles.java index 37de84347..e75b6f6ec 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/cache/CoreCacheFiles.java +++ b/prison-core/src/main/java/tech/mcprison/prison/cache/CoreCacheFiles.java @@ -30,7 +30,6 @@ public abstract class CoreCacheFiles { private File cacheDirectory = null; private Gson gson = null; -// private TreeMap playerFiles; public CoreCacheFiles( String cachePath ) { @@ -153,22 +152,6 @@ public CoreCacheData fromJson( Player player, Class cla File playerCacheFile = JsonFileIO.fileCache(player); -// String cacheFilename = JsonFileIO.filenameCache(player); -//// String playerId = player.getUUID().toString(); -// -// File playerCacheFile = getPlayerFile( cacheFilename ); - -// // This is the "target" file name for the player, based upon their -// // current name. The saved cache file may not be named exactly the same, -// // and if it's not, then their existing cache file will be renamed -// // within the function getCachedFileMatch() -// String playerFileName = getPlayerFileName( player ); - -// String uuidPrefix = JsonFileIO.getFileNameUUIDFragment(playerFileName) - -// File playerFile = getCachedFileMatch( playerId, cacheFilename ); - - if ( playerCacheFile.exists() ) { results = fromJsonFile( playerCacheFile, classOfT ); @@ -224,10 +207,6 @@ public void toJsonFile(CoreCacheData cacheData) { File playerFile = cacheData.getPlayerFile(); File outTemp = createTempFile( playerFile ); -// if ( !getPlayerFiles().containsKey( playerFile.getName() )) { -// getPlayerFiles().put( playerFile.getName(), playerFile ); -// } - if ( outTemp.getParentFile().mkdirs() ) { Output.get().logInfo( "CoreCacheFiles.toJsonFile(): Created missing directories: %s", outTemp.getParentFile().getAbsolutePath() ); @@ -293,54 +272,7 @@ public void toJsonFile(CoreCacheData cacheData) { } } -// /** -// *

    Constructs a File object for a specific player. -// *

    -// * -// * @param playerFileName -// * @return -// */ -// protected File getPlayerFile(String playerFileName) { -// return new File( getPlayerFilePath(), playerFileName ); -// } -// protected TreeMap getPlayerFiles() { -// // load the player's files: -// -// TreeMap playerFiles = new TreeMap<>(); -// -// FileFilter fileFilter = (file) -> { -// -// String fname = file.getName(); -// boolean isTemp = fname.startsWith( FILE_PREFIX_BACKUP ) || -// fname.endsWith( FILE_SUFFIX_BACKUP ) || -// fname.endsWith( FILE_SUFFIX_TEMP ) || -// fname.endsWith( FILE_SUFFIX_TXT ); -// -// return !file.isDirectory() && !isTemp && -// fname.endsWith( FILE_SUFFIX_JSON ); -// }; -// -// -// File[] files = getPlayerFilePath().listFiles( fileFilter ); -// for ( File f : files ) -// { -// String fName = f.getName(); -// -// String fileNamePrefix = JsonFileIO.getFileNameUUIDFragment( fName ); -// -// if ( fileNamePrefix != null && fileNamePrefix.length() > 0 ) { -// -// playerFiles.put( fileNamePrefix, f ); -// } -// } -// -// -// return playerFiles; -// } - - - /** *

    This function will take the project's data folder and construct the the path * to the directory, if it does not exist, to where the player cache files are stored. @@ -358,156 +290,4 @@ public File getPlayerFilePath() { return cacheDirectory; } -// /** -// *

    This function returns the file name which is constructed by -// * using the player's UUID and their name. The player's name is not -// * used in the selection of a player's file, only the UUID prefix. -// *

    -// * -// *

    The UUID prefix is based upon the HEX representation of the -// * the UUID, and includes the first 13 characters which includes one -// * hyphen. Since the minecraft UUID is based upon random numbers -// * (type 4 UUID), then odds are great that file name prefixes will -// * be unique, but they don't have to be. -// *

    -// * -// *

    Its a high importance that file names can be found based upon -// * Player information, hence the UUID prefix. Plus it's very important -// * to be able to have the files human readable so admins can find -// * specific player files if they need to; hence the player name suffix. -// *

    -// * -// * @param player -// * @return -// */ -// private String getPlayerFileName( Player player ) { -// -// return JsonFileIO.filenameCache( player ); -// -//// String UUIDString = player.getUUID().toString(); -//// String uuidFragment = getFileNamePrefix( UUIDString ); -//// -//// return uuidFragment + "_" + player.getName() + FILE_SUFFIX_JSON; -// } - -// /** -// *

    This function returns the first 13 characters of the supplied -// * file name, or UUID String. The hyphen is around the 12 or 13th position, -// * so it may or may not include it. -// *

    -// * -// * @param playerFileName -// * @return -// */ -// String getFileNamePrefix( String UUIDString ) { -// return UUIDString.substring( 0, 14 ); -// } - - - -// /** -// *

    This takes a playerId (their UUID) and tries to get their file name from the -// * playerFile collection. If it does not exist, a new file is created for their -// * user. If the saved file name does not match the playerFilename, then it indicates -// * there could have been a player name change, so update the saved file on the file -// * system and update what's stored in the playerFiles. -// *

    -// * -// * -// * @param playerFile -// * @param playerFileName -// * @return -// */ -// private File getCachedFileMatch( String playerId, String playerFileName ) -// { -// File results = null; -// -// if ( getPlayerFiles().containsKey( playerId ) ) { -// -// results = getPlayerFiles().get( playerId ); -// } -// else { -// // This is the "target" file name for the player, based upon their -// // current name. The saved cache file may not be named exactly the same, -// // and if it's not, then their existing cache file needs to be -// // renamed. -// results = getPlayerFile( playerFileName ); -// -// // NOTE: because the file was NOT found in the directory, then we can assume -// // this is a new player therefore we won't have an issue with the player's -// // name changing. -// getPlayerFiles().put( playerId, results ); -// } -// -// -// if ( results != null && !results.getName().equalsIgnoreCase(playerFileName) ) { -// // They player's name changed. Update the name of the file and save it: -// -// // File name changed!!! Need to rename the file in the file system, and -// // update what is in the playerFiles map!! -// -// File newFile = getPlayerFile( playerFileName ); -// -// if ( results.exists() ) { -// // rename what's on the file system: -// results.renameTo( newFile ); -// } -// -// // Replace what's in the map: -// getPlayerFiles().put( playerId, newFile ); -// -// results = newFile; -// } -// - -// String fileNamePrefix = JsonFileIO.getFileNameUUIDFragment( playerFileName ); -//// String fileNamePrefix = getFileNamePrefix( playerFileName ); -// -// if ( fileNamePrefix != null && fileNamePrefix.length() > 0 ) { -// results = getPlayerFiles().get( fileNamePrefix ); -// } -// -// if ( results == null ) { -// -// // This is the "target" file name for the player, based upon their -// // current name. The saved cache file may not be named exactly the same, -// // and if it's not, then their existing cache file needs to be -// // renamed. -// results = getPlayerFile( playerFileName ); -// -// // NOTE: because the file was NOT found in the directory, then we can assume -// // this is a new player therefore we won't have an issue with the player's -// // name changing. -// getPlayerFiles().put( fileNamePrefix, results ); -// } -// else if ( !playerFileName.equalsIgnoreCase( results.getName() )) { -// -// // File name changed!!! Need to rename the file in the file system, and -// // update what is in the playerFiles map!! -// -// File newFile = getPlayerFile( playerFileName ); -// -// if ( results.exists() ) { -// // rename what's on the file system: -// results.renameTo( newFile ); -// } -// -// // Replace what's in the map: -// getPlayerFiles().put( fileNamePrefix, newFile ); -// -// results = newFile; -// } - -// NavigableMap files = getPlayerFiles().tailMap( fileNamePrefix, true ); -// Set keys = files.keySet(); -// for ( String key : keys ) { -// if ( !key.startsWith( fileNamePrefix ) ) { -// break; -// } -// -// results.add( files.get( key ) ); -// } - -// return results; -// } } 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 c5ff1f92a..8d07958c3 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 @@ -333,8 +333,6 @@ else if ( loadIfNotInCache ) { // Save it to the cache: addPlayerData( playerData ); -// runLoadPlayerNow( player ); -// submitAsyncLoadPlayer( player ); } if ( playerData != null ) { @@ -365,29 +363,6 @@ protected void submitAsyncLoadPlayer( Player player ) { } -// /** -// *

    This loads the player cache object inline. It does not run it as a -// * task in another thread. -// *

    -// * -// *

    This is not used anywhere. -// *

    -// * -// * @param player -// */ -// protected void runLoadPlayerNow( Player player ) { -// -// if ( player != null ) { -// -// PlayerCacheLoadPlayerTask task = new PlayerCacheLoadPlayerTask( player ); -// -// task.run(); -//// // Submit task to run right away: -//// int taskId = PrisonTaskSubmitter.runTaskLaterAsync( task, 0 ); -//// task.setTaskId( taskId ); -// } -// } - protected void submitAsyncUnloadPlayer( Player player ) { @@ -429,18 +404,6 @@ public PlayerCacheRunnable submitCacheUpdatePlayerStats() { PlayerCacheRunnable task = PlayerCacheCheckTimersTask.submitPlayerStatsCacheUpdater(); -// 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, repeatTimeTicks ); -// task.setTaskId( taskId ); -// return task; } @@ -455,20 +418,11 @@ public void addPlayerBlocks( Player player, String mine, PrisonBlockStatusData b } } -// public void addPlayerBlocks( Player player, String mine, PrisonBlock block, int quantity ) { -// addPlayerBlocks( player, mine, block.getBlockName(), quantity ); -// } + + private void addPlayerBlocks( Player player, String mine, String blockName, int quantity ) { PlayerCachePlayerData playerData = getPlayer( player ); -// Output.get().logInfo( "### addPlayerBlock: mine= " + (mine == null ? "null" : mine) + -// " block= " + (block == null ? "null" : block.getBlockName()) + " qty= " + quantity + " playerData= " + -// (playerData == null ? "null" : playerData.toString() )); - -// if ( playerData != null && playerData.getBlocksTotal() % 20 == 0 ) { -// Output.get().logInfo( "#### PlayerCache: " + playerData.toString() ); -// } - playerData.addBlock( mine, blockName, quantity ); if ( player.isMinecraftStatisticsEnabled() ) { @@ -586,12 +540,10 @@ public void setStats( PlayerCacheStats stats ) { this.stats = stats; } - protected void log( String message ) { Output.get().logInfo( message ); } - public long getWriteDelay() { return writeDelay; @@ -609,5 +561,4 @@ public Map getTasks() { return tasks; } - } diff --git a/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheEvents.java b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheEvents.java index 920700444..e84977e94 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheEvents.java +++ b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheEvents.java @@ -50,29 +50,23 @@ public PlayerCacheEvents() { @Subscribe public void onPlayerJoin(PlayerJoinEvent event) { - Player player = event.getPlayer(); - - - // Change all player cache references of "Player" to PlayerRank: - -// RankPlayer rPlayer = player.getRankPlayer(); -// RankPlayer rPlayer = Prison.get().getPlatform() -// .getRankPlayer( player.getUUID(), player.getName() ); - - PlayerCache.getInstance().submitAsyncLoadPlayer( player ); + Player player = event.getPlayer(); + + + PlayerCache.getInstance().submitAsyncLoadPlayer( player ); } @Subscribe public void onPlayerQuit(PlayerQuitEvent event) { Player player = event.getPlayer(); - PlayerCache.getInstance().submitAsyncUnloadPlayer( player ); + PlayerCache.getInstance().submitAsyncUnloadPlayer( player ); } @Subscribe public void onPlayerKicked(PlayerKickEvent event) { - Player player = event.getPlayer(); - PlayerCache.getInstance().submitAsyncUnloadPlayer( player ); + Player player = event.getPlayer(); + PlayerCache.getInstance().submitAsyncUnloadPlayer( player ); } } diff --git a/prison-core/src/main/java/tech/mcprison/prison/chat/FancyMessage.java b/prison-core/src/main/java/tech/mcprison/prison/chat/FancyMessage.java index 9003b9c00..afdd006d8 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/chat/FancyMessage.java +++ b/prison-core/src/main/java/tech/mcprison/prison/chat/FancyMessage.java @@ -75,17 +75,17 @@ public FancyMessage(final FancyMessage... msgs) { } public FancyMessage(final List msgs) { - messageParts = new ArrayList<>(); - for(FancyMessage msg : msgs) { - messageParts.addAll(msg.messageParts); - } - jsonString = null; - dirty = false; + messageParts = new ArrayList<>(); + for(FancyMessage msg : msgs) { + messageParts.addAll(msg.messageParts); + } + jsonString = null; + dirty = false; } public void addFancy(FancyMessage fancyMessage) { - messageParts.addAll( fancyMessage.messageParts ); - dirty = true; + messageParts.addAll( fancyMessage.messageParts ); + dirty = true; } /** diff --git a/prison-core/src/main/java/tech/mcprison/prison/chat/MessagePart.java b/prison-core/src/main/java/tech/mcprison/prison/chat/MessagePart.java index 4d960ff7d..4e3140081 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/chat/MessagePart.java +++ b/prison-core/src/main/java/tech/mcprison/prison/chat/MessagePart.java @@ -97,7 +97,9 @@ boolean hasText() { return text != null; } - @Override @SuppressWarnings("unchecked") public MessagePart clone() + @Override + @SuppressWarnings("unchecked") + public MessagePart clone() throws CloneNotSupportedException { MessagePart obj = (MessagePart) super.clone(); obj.styles = (ArrayList) styles.clone(); diff --git a/prison-core/src/main/java/tech/mcprison/prison/chat/TextualComponent.java b/prison-core/src/main/java/tech/mcprison/prison/chat/TextualComponent.java index ebb75522f..6bccf7c0c 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/chat/TextualComponent.java +++ b/prison-core/src/main/java/tech/mcprison/prison/chat/TextualComponent.java @@ -115,7 +115,8 @@ public static TextualComponent objectiveScore(String scoreboardObjective) { * player, or {@code null} if an error occurs during JSON serialization. */ public static TextualComponent objectiveScore(String playerName, String scoreboardObjective) { - throwUnsupportedSnapshot(); // Remove this line when the feature is released to non-snapshot versions, in addition to updating ALL THE OVERLOADS documentation accordingly + throwUnsupportedSnapshot(); // Remove this line when the feature is released to + // non-snapshot versions, in addition to updating ALL THE OVERLOADS documentation accordingly return new ComplexTextTypeComponent("score", ImmutableMap.builder().put("name", playerName) @@ -134,12 +135,14 @@ public static TextualComponent objectiveScore(String playerName, String scoreboa * @return The text component representing the name of the entities captured by the selector. */ public static TextualComponent selector(String selector) { - throwUnsupportedSnapshot(); // Remove this line when the feature is released to non-snapshot versions, in addition to updating ALL THE OVERLOADS documentation accordingly + throwUnsupportedSnapshot(); // Remove this line when the feature is released to non-snapshot + // versions, in addition to updating ALL THE OVERLOADS documentation accordingly return new ArbitraryTextTypeComponent("selector", selector); } - @Override public String toString() { + @Override + public String toString() { return getReadableString(); } @@ -157,7 +160,8 @@ public static TextualComponent selector(String selector) { * Clones a textual component instance. The returned object should not reference this textual * component instance, but should maintain the same key and value. */ - @Override public abstract TextualComponent clone() throws CloneNotSupportedException; + @Override + public abstract TextualComponent clone() throws CloneNotSupportedException; /** * Writes the text data represented by this textual component to the specified JSON writer object. @@ -207,23 +211,27 @@ public void setValue(String value) { _value = value; } - @Override public TextualComponent clone() throws CloneNotSupportedException { + @Override + public TextualComponent clone() throws CloneNotSupportedException { // Since this is a private and final class, we can just reinstantiate this class instead of casting super.clone return new ArbitraryTextTypeComponent(getKey(), getValue()); } - @Override public void writeJson(JsonWriter writer) throws IOException { + @Override + public void writeJson(JsonWriter writer) throws IOException { writer.name(getKey()).value(getValue()); } - @SuppressWarnings({ "serial", "unused" }) public Map serialize() { + @SuppressWarnings("unused") + public Map serialize() { return new HashMap() {{ put("key", getKey()); put("value", getValue()); }}; } - @Override public String getReadableString() { + @Override + public String getReadableString() { return getValue(); } } @@ -257,7 +265,8 @@ public static ComplexTextTypeComponent deserialize(Map map) { return new ComplexTextTypeComponent(key, value); } - @Override public String getKey() { + @Override + public String getKey() { return _key; } @@ -276,12 +285,14 @@ public void setValue(Map value) { _value = value; } - @Override public TextualComponent clone() throws CloneNotSupportedException { + @Override + public TextualComponent clone() throws CloneNotSupportedException { // Since this is a private and final class, we can just reinstantiate this class instead of casting super.clone return new ComplexTextTypeComponent(getKey(), getValue()); } - @Override public void writeJson(JsonWriter writer) throws IOException { + @Override + public void writeJson(JsonWriter writer) throws IOException { writer.name(getKey()); writer.beginObject(); for (Map.Entry jsonPair : _value.entrySet()) { @@ -290,7 +301,8 @@ public void setValue(Map value) { writer.endObject(); } - @SuppressWarnings({ "serial", "unused" }) public Map serialize() { + @SuppressWarnings("unused") + public Map serialize() { return new HashMap() {{ put("key", getKey()); for (Entry valEntry : getValue().entrySet()) { @@ -299,7 +311,8 @@ public void setValue(Map value) { }}; } - @Override public String getReadableString() { + @Override + public String getReadableString() { return getKey(); } } From e213749641514fd5247995e89a83b3fe330c11d0 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 7 Mar 2026 04:34:12 -0500 Subject: [PATCH 312/323] Prison Cleanup: prison-core: Removed obsolete and unneeded comments and fix indentation where needed. Fifth part. --- docs/changelog_v3.3.x.md | 5 +- .../tech/mcprison/prison/TestPlatform.java | 33 +++---- .../java/tech/mcprison/prison/TestPlayer.java | 93 +++++++++++-------- .../tech/mcprison/prison/TestScheduler.java | 20 ++-- .../tech/mcprison/prison/chat/ChatTest.java | 4 +- .../placeholders/PlaceHolderKeyTest.java | 82 +--------------- .../prison/selection/SelectionTest.java | 6 +- .../util/BluesSemanticVersionDataTest.java | 3 - 8 files changed, 99 insertions(+), 147 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 41eea8107..b166a60b8 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.19j 2026-03-06 +# 3.3.0-alpha.19j 2026-03-07 + + +* **Prison Cleanup: prison-core: Removed obsolete and unneeded comments and fix indentation where needed.** Fifth part. * **Prison Cleanup: prison-core: Removed obsolete and unneeded comments and fix indentation where needed.** Fourth part. 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 39c80272d..3a86b57ca 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/TestPlatform.java +++ b/prison-core/src/test/java/tech/mcprison/prison/TestPlatform.java @@ -82,17 +82,17 @@ public void getWorldLoadErrors( ChatDisplay display ) { @Override public Player getPlatformPlayer(RankPlayer rankPlayer) { - return null; + return null; } @Override public RankPlayer getRankPlayer(UUID uuid, String name) { - return null; + return null; } @Override public boolean saveRankPlayer(RankPlayer rPlayer) { - return false; + return false; } @Override @@ -109,10 +109,11 @@ public Optional getPlayer(UUID uuid) { public List getOnlinePlayers() { return new ArrayList<>(); } + @Override public List getOfflinePlayers() { - List players = new ArrayList<>(); - return players; + List players = new ArrayList<>(); + return players; } @Override @@ -187,15 +188,15 @@ public void log(String message, Object... format) { @Override public void logCore( String message ) { - if (suppressOutput) { - return; - } - System.out.println(ChatColor.stripColor(message)); + if (suppressOutput) { + return; + } + System.out.println(ChatColor.stripColor(message)); } @Override public void logPlain( String message ) { - System.out.println(message); + System.out.println(message); } @Override @@ -245,24 +246,24 @@ public void identifyRegisteredPlugins() { public Map getPlaceholderDetailCounts() { - Map placeholderDetails = new TreeMap<>(); - - return placeholderDetails; + Map placeholderDetails = new TreeMap<>(); + + return placeholderDetails; } public int getPlaceholderCount() { - return 0; + return 0; } public int getPlaceholderRegistrationCount() { - return 0; + return 0; } @Override public Placeholders getPlaceholders() { - return null; + return null; } diff --git a/prison-core/src/test/java/tech/mcprison/prison/TestPlayer.java b/prison-core/src/test/java/tech/mcprison/prison/TestPlayer.java index 52098f0db..385587d00 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/TestPlayer.java +++ b/prison-core/src/test/java/tech/mcprison/prison/TestPlayer.java @@ -76,47 +76,58 @@ public String getPlayerFileName() { // return JsonFileIO.filenamePlayer( this ); } - @Override public void updateInventory() { + @Override + public void updateInventory() { } - @Override public void dispatchCommand(String command) { + @Override + public void dispatchCommand(String command) { } - @Override public boolean hasPermission(String perm) { + @Override + public boolean hasPermission(String perm) { return true; } - @Override public void sendMessage(String message) { + @Override + public void sendMessage(String message) { System.out.println(message); input.add(message); } - @Override public void sendMessage(String[] messages) { + @Override + public void sendMessage(String[] messages) { input.addAll(Arrays.asList(messages)); } - @Override public void sendRaw(String json) { + @Override + public void sendRaw(String json) { input.add(json); } - @Override public UUID getUUID() { + @Override + public UUID getUUID() { return null; } - @Override public String getDisplayName() { + @Override + public String getDisplayName() { return null; } - @Override public void setDisplayName(String newDisplayName) { + @Override + public void setDisplayName(String newDisplayName) { } - @Override public void give(ItemStack itemStack) { + @Override + public void give(ItemStack itemStack) { } - @Override public Location getLocation() { + @Override + public Location getLocation() { return null; } @@ -128,42 +139,49 @@ public Block getLineOfSightBlock() { @Override public List getLineOfSightBlocks() { - List results = new ArrayList<>(); - return results; + List results = new ArrayList<>(); + return results; } - @Override public boolean teleport(Location location) { - return false; + @Override + public boolean teleport(Location location) { + return false; } - @Override public boolean isOnline() { + @Override + public boolean isOnline() { return true; } - @Override public void setScoreboard(Scoreboard scoreboard) { + @Override + public void setScoreboard(Scoreboard scoreboard) { } - @Override public Gamemode getGamemode() { + @Override + public Gamemode getGamemode() { return null; } - @Override public void setGamemode(Gamemode gamemode) { + @Override + public void setGamemode(Gamemode gamemode) { } - @Override public Optional getLocale() { + @Override + public Optional getLocale() { return Optional.of("en_US"); } - @Override public boolean isOp() { + @Override + public boolean isOp() { return true; } @Override public boolean isPlayer() { - return false; + return false; } @Override public Inventory getInventory() { @@ -182,29 +200,29 @@ public void recalculatePermissions() { @Override public List getPermissions() { - List results = new ArrayList<>(); - - return results; + List results = new ArrayList<>(); + + return results; } @Override public List getPermissions( String prefix ) { - return getPermissions( prefix, getPermissions() ); + return getPermissions( prefix, getPermissions() ); } @Override public List getPermissions( String prefix, List perms ) { - List results = new ArrayList<>(); - - for ( String perm : perms ) { - if ( perm.startsWith( prefix ) ) { - results.add( perm ); - } - } - - return results; + List results = new ArrayList<>(); + + for ( String perm : perms ) { + if ( perm.startsWith( prefix ) ) { + results.add( perm ); + } + } + + return results; } @Override @@ -217,12 +235,12 @@ public List getPermissionsIntegrations( boolean detailed ) { @Override public double getSellAllMultiplier() { - return 1.0; + return 1.0; } @Override public double getSellAllMultiplierDebug() { - return 1.0; + return 1.0; } @Override @@ -301,6 +319,7 @@ public RankPlayer getRankPlayer() { public String getMiscText() { return null; } + @Override public void setMiscText( String text ) { } diff --git a/prison-core/src/test/java/tech/mcprison/prison/TestScheduler.java b/prison-core/src/test/java/tech/mcprison/prison/TestScheduler.java index b3182ee53..4058aaa8a 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/TestScheduler.java +++ b/prison-core/src/test/java/tech/mcprison/prison/TestScheduler.java @@ -7,19 +7,23 @@ * @author Faizaan A. Datoo */ public class TestScheduler implements Scheduler { - @Override public int runTaskLater(Runnable run, long delay) { + @Override + public int runTaskLater(Runnable run, long delay) { return 0; } - @Override public int runTaskLaterAsync(Runnable run, long delay) { + @Override + public int runTaskLaterAsync(Runnable run, long delay) { return 0; } - @Override public int runTaskTimer(Runnable run, long delay, long interval) { + @Override + public int runTaskTimer(Runnable run, long delay, long interval) { return 0; } - @Override public int runTaskTimerAsync(Runnable run, long delay, long interval) { + @Override + public int runTaskTimerAsync(Runnable run, long delay, long interval) { return 0; } @@ -33,16 +37,18 @@ public void performCommand(Player player, String command) { } - @Override public void cancelTask(int taskId) { + @Override + public void cancelTask(int taskId) { } - @Override public void cancelAll() { + @Override + public void cancelAll() { } @Override public boolean isPrimaryThread() { - return false; + return false; } } diff --git a/prison-core/src/test/java/tech/mcprison/prison/chat/ChatTest.java b/prison-core/src/test/java/tech/mcprison/prison/chat/ChatTest.java index 34befeafe..ad85ee0d0 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/chat/ChatTest.java +++ b/prison-core/src/test/java/tech/mcprison/prison/chat/ChatTest.java @@ -34,7 +34,9 @@ public class ChatTest { .color(ChatColor.BLACK); String expected = - "{\"text\":\"\",\"extra\":[{\"text\":\"Test\",\"color\":\"aqua\",\"clickEvent\":{\"action\":\"open_url\",\"value\":\"http://google.com\"}},{\"text\":\"ing\",\"color\":\"black\"}]}"; + "{\"text\":\"\",\"extra\":[{\"text\":\"Test\",\"color\":\"aqua\"," + + "\"clickEvent\":{\"action\":\"open_url\",\"value\":\"http://google.com\"}},." + + "{\"text\":\"ing\",\"color\":\"black\"}]}"; String actual = message.toJSONString(); assertEquals(expected, actual); diff --git a/prison-core/src/test/java/tech/mcprison/prison/placeholders/PlaceHolderKeyTest.java b/prison-core/src/test/java/tech/mcprison/prison/placeholders/PlaceHolderKeyTest.java index 87ec837a7..7446fc807 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/placeholders/PlaceHolderKeyTest.java +++ b/prison-core/src/test/java/tech/mcprison/prison/placeholders/PlaceHolderKeyTest.java @@ -2,6 +2,9 @@ import org.junit.Test; +/** + * @deprecated + */ public class PlaceHolderKeyTest //extends PlaceHolderKey { @@ -15,85 +18,8 @@ public PlaceHolderKeyTest() { @Test public void test() { - /** - [14:04:20] [Async Chat Thread - #0/INFO]: &8| &3Prison &8| &7 &cFailure to generate log message due to incorrect number of parameters: [Format specifier '%1$s'] :: Original raw message [### ChatHandler - before [\Q%s\E] after [\Q%s\E]] Arguments: [<{prison_rank_tag}{prison_rank}{prison_r}{prison_rank_default}{PRISON_RANK}{PRISON_RANK_TAG}[{prison_rc} {prison_rcp}]:%1$s>%2$s] [<{prison_rank_tag}{prison_rank}{prison_r}{prison_rank_default}{PRISON_RANK}{PRISON_RANK_TAG}[{prison_rc} {prison_rcp}]:%1$s>%2$s] - [14:04:20] [Async Chat Thread - #0/INFO]: <{prison_rank_tag}{prison_rank}{prison_r}{prison_rank_default}{PRISON_RANK}{PRISON_RANK_TAG}[{prison_rc} {prison_rcp}]:RoyalBlueRanger>hey - - */ - -// List placeHolderKeys = new ArrayList<>(); -// -// PlaceHolderKey key1 = new PlaceHolderKey( PrisonPlaceHolders.prison_rank.name(), PrisonPlaceHolders.prison_rank, true ); -// PlaceHolderKey key2 = new PlaceHolderKey( PrisonPlaceHolders.prison_rank_tag.name(), PrisonPlaceHolders.prison_rank_tag, true ); -// -// placeHolderKeys.add( key1 ); -// placeHolderKeys.add( key2 ); -// -// String testText1 = "<{prison_rank_tag}{prison_rank}>"; -// String testText2 = "<{prison_rank_tag}{prison_r}>"; -// String testText3 = "<{prison_rank_default}{prison_rank_tag}>"; -// -// String testText4 = "<{prison_rank_tag}{prison_rank::some:annotation:goes:here}>"; -// -// String testText5 = "<{prison_rank_tag}{Prison_Rank}>"; -// String testText6 = "<{prison_rank_tag}{PRISON_RANK}>"; - -// String testText7 = "<{prison_rank_tag}{prison_rank}{prison_r}{prison_rank_default}" + -// "{PRISON_RANK}{PRISON_RANK_TAG}[{prison_rc} {prison_rcp}"; - - -// PlaceholderResults results1 = key1.getIdentifier( testText1 ); -// PlaceholderResults results2 = key1.getIdentifier( testText2 ); -// PlaceholderResults results3 = key1.getIdentifier( testText3 ); -// -// assertTrue( results1.hasResults() ); -// assertEquals( "prison_rank", results1.getIdentifier() ); -// -// assertFalse( results2.hasResults() ); -// assertNull( results2.getIdentifier() ); -// -// assertFalse( results3.hasResults() ); -// assertNull( results3.getIdentifier() ); -// -// -// -// PlaceholderResults results4 = key2.getIdentifier( testText3 ); -// -// assertTrue( results4.hasResults() ); -// assertEquals( "prison_rank_tag", results4.getIdentifier() ); -// -// -// -// PlaceholderResults results5 = key1.getIdentifier( testText4 ); -// -// assertTrue( results5.hasResults() ); -// assertEquals( "prison_rank::some:annotation:goes:here", results5.getIdentifier() ); -// -// -// PlaceholderResults results6 = key1.getIdentifier( testText5 ); -// PlaceholderResults results7 = key1.getIdentifier( testText6 ); -// -// assertTrue( results6.hasResults() ); -// assertEquals( "Prison_Rank", results6.getIdentifier() ); -// -// assertTrue( results7.hasResults() ); -// assertEquals( "PRISON_RANK", results7.getIdentifier() ); -// -// -// -// String testText10 = "<{prison_rANk_tag}{prison_rank_default}{PRISON_RANK}[{prison_rc} {prison_rcp}]"; -// -// PlaceholderResults results10a = key1.getIdentifier( testText10 ); -// PlaceholderResults results10b = key2.getIdentifier( testText10 ); -// -// -// assertTrue( results10a.hasResults() ); -// assertEquals( "PRISON_RANK", results10a.getIdentifier() ); -// -// -// assertTrue( results10b.hasResults() ); -// assertEquals( "prison_rANk_tag", results10b.getIdentifier() ); + // NOTE: Commented out source has been purged. See github's history. Could be deleted soon. } diff --git a/prison-core/src/test/java/tech/mcprison/prison/selection/SelectionTest.java b/prison-core/src/test/java/tech/mcprison/prison/selection/SelectionTest.java index f22fb71dd..58738ae71 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/selection/SelectionTest.java +++ b/prison-core/src/test/java/tech/mcprison/prison/selection/SelectionTest.java @@ -60,7 +60,7 @@ public class SelectionTest { TestPlayer ourPlayer = new TestPlayer(); ItemStack coloredToolItemStack = ItemStack.SELECTION_WAND; -// ItemStack coloredToolItemStack = SelectionManager.SELECTION_TOOL; + coloredToolItemStack .setDisplayName(Text.translateAmpColorCodes(coloredToolItemStack.getDisplayName())); @@ -89,10 +89,8 @@ public void testSelectionToolCheck() throws Exception { Prison.get().getEventBus().post( new PrisonPlayerInteractEvent(ourPlayer, new ItemStack("test", 1, acaciaSapling ), PrisonPlayerInteractEvent.Action.LEFT_CLICK_BLOCK, new Location(ourWorld, 10, 20, 30))); -// Prison.get().getEventBus().post( -// new PrisonPlayerInteractEvent(ourPlayer, new ItemStack("test", 1, BlockType.ACACIA_SAPLING), -// PrisonPlayerInteractEvent.Action.LEFT_CLICK_BLOCK, new Location(ourWorld, 10, 20, 30))); + assertEquals(initialAmount, ourPlayer.getInput() .size()); // nothing should have happened because we have the wrong item in our hand diff --git a/prison-core/src/test/java/tech/mcprison/prison/util/BluesSemanticVersionDataTest.java b/prison-core/src/test/java/tech/mcprison/prison/util/BluesSemanticVersionDataTest.java index 28742b639..bf26ed0d4 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/util/BluesSemanticVersionDataTest.java +++ b/prison-core/src/test/java/tech/mcprison/prison/util/BluesSemanticVersionDataTest.java @@ -8,9 +8,6 @@ import org.junit.Test; -import tech.mcprison.prison.util.BluesSemanticVersionComparator; -import tech.mcprison.prison.util.BluesSemanticVersionData; - public class BluesSemanticVersionDataTest { From 1e58ba889de6d428d9f0172a5e8d59bbf59726d5 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 7 Mar 2026 05:39:39 -0500 Subject: [PATCH 313/323] Bug fix in the ChatTest Junit test. When I was cleaning up that source I accidentally introduced a stray '.'. --- docs/changelog_v3.3.x.md | 3 +++ .../src/test/java/tech/mcprison/prison/chat/ChatTest.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 b166a60b8..da604139e 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.19j 2026-03-07 +* **Bug fix in the ChatTest Junit test. When I was cleaning up that source I accidentally introduced a stray '.'.** + + * **Prison Cleanup: prison-core: Removed obsolete and unneeded comments and fix indentation where needed.** Fifth part. diff --git a/prison-core/src/test/java/tech/mcprison/prison/chat/ChatTest.java b/prison-core/src/test/java/tech/mcprison/prison/chat/ChatTest.java index ad85ee0d0..343ef08dd 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/chat/ChatTest.java +++ b/prison-core/src/test/java/tech/mcprison/prison/chat/ChatTest.java @@ -35,7 +35,7 @@ public class ChatTest { String expected = "{\"text\":\"\",\"extra\":[{\"text\":\"Test\",\"color\":\"aqua\"," - + "\"clickEvent\":{\"action\":\"open_url\",\"value\":\"http://google.com\"}},." + + "\"clickEvent\":{\"action\":\"open_url\",\"value\":\"http://google.com\"}}," + "{\"text\":\"ing\",\"color\":\"black\"}]}"; String actual = message.toJSONString(); From 8da73c5a07bed9767675f44ccc8fe56d1aef24ca Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 14 Mar 2026 13:50:51 -0400 Subject: [PATCH 314/323] Prison Cleanup: prison-spigot: Removed obsolete and unneeded comments and fix indentation where needed. First part. --- docs/changelog_v3.3.x.md | 5 +- .../spigot/permissions/LuckPermissions.java | 42 +- .../permissions/LuckPermissionsWrapper.java | 119 +- .../prison/spigot/permissions/LuckPerms5.java | 28 +- .../spigot/permissions/LuckPerms5Wrapper.java | 302 +- .../MVdWPlaceholderIntegration.java | 184 +- .../MVdWPlaceholderIntegrationWrapper.java | 11 +- ...eHolderAPIIntegrationUppercaseWrapper.java | 9 - .../PlaceHolderAPIIntegrationWrapper.java | 8 - .../placeholder/SpigotPlaceholders.java | 34 - .../prison/spigot/sellall/SellAllData.java | 84 +- .../prison/spigot/sellall/SellAllUtil.java | 3052 ++++++----------- .../spiget/PrisonSpigetUpdateCheckTask.java | 30 +- .../tasks/PrisonInitialStartupTask.java | 26 +- .../tasks/SpigotPrisonDelayedStartupTask.java | 42 +- .../prison/spigot/util/SpigotYamlFileIO.java | 56 +- .../spigot/utils/PrisonBombListener.java | 552 ++- .../prison/spigot/utils/PrisonUtils.java | 158 +- .../spigot/utils/PrisonUtilsHealing.java | 17 +- .../spigot/utils/PrisonUtilsListeners.java | 39 +- .../spigot/utils/PrisonUtilsMessages.java | 3 +- .../spigot/utils/PrisonUtilsMineBombs.java | 46 +- .../spigot/utils/PrisonUtilsMining.java | 2 - .../spigot/utils/PrisonUtilsModule.java | 15 +- .../spigot/utils/PrisonUtilsPotions.java | 42 - .../spigot/utils/PrisonUtilsRepair.java | 169 +- .../spigot/utils/PrisonUtilsTitles.java | 143 - .../spigot/utils/UnbreakableBlockData.java | 4 - .../worldguard/WorldGuard6Integration.java | 2 - .../spigot/worldguard/WorldGuardSettings.java | 2 - .../utils/PrisonUtilsMineBombsTest.java | 2 - 31 files changed, 1705 insertions(+), 3523 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index da604139e..650281e69 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.19j 2026-03-07 +# 3.3.0-alpha.19j 2026-03-14 + + +* **Prison Cleanup: prison-spigot: Removed obsolete and unneeded comments and fix indentation where needed.** First part. * **Bug fix in the ChatTest Junit test. When I was cleaning up that source I accidentally introduced a stray '.'.** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/permissions/LuckPermissions.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/permissions/LuckPermissions.java index 7b80a6102..144f86192 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/permissions/LuckPermissions.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/permissions/LuckPermissions.java @@ -36,7 +36,7 @@ public class LuckPermissions private LuckPermissionsWrapper permsWrapper; public LuckPermissions() { - super( "LuckPerms-Legacy", "LuckPerms" ); + super( "LuckPerms-Legacy", "LuckPerms" ); } @Override @@ -60,40 +60,40 @@ public void integrate() { @Override public void addPermission(Player holder, String permission) { - if ( permsWrapper != null ) { - permsWrapper.addPermission( holder, permission ); - } + if ( permsWrapper != null ) { + permsWrapper.addPermission( holder, permission ); + } } @Override public void removePermission(Player holder, String permission) { - if ( permsWrapper != null ) { - permsWrapper.removePermission( holder, permission ); - } + if ( permsWrapper != null ) { + permsWrapper.removePermission( holder, permission ); + } } @Override public void addGroupPermission(Player holder, String groupPermission) { - if ( permsWrapper != null ) { - permsWrapper.addGroupPermission( holder, groupPermission ); - } + if ( permsWrapper != null ) { + permsWrapper.addGroupPermission( holder, groupPermission ); + } } @Override public void removeGroupPermission(Player holder, String groupPermission) { - if ( permsWrapper != null ) { - permsWrapper.removeGroupPermission( holder, groupPermission ); - } + if ( permsWrapper != null ) { + permsWrapper.removeGroupPermission( holder, groupPermission ); + } } @Override public List getPermissions(Player holder, boolean detailed) { - List results = new ArrayList<>(); - - if ( permsWrapper != null ) { - results = permsWrapper.getPermissions(holder, detailed); - } - - return results; + List results = new ArrayList<>(); + + if ( permsWrapper != null ) { + results = permsWrapper.getPermissions(holder, detailed); + } + + return results; } @@ -105,7 +105,7 @@ public boolean hasIntegrated() { @Override public void disableIntegration() { - permsWrapper = null; + permsWrapper = null; } @Override diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/permissions/LuckPermissionsWrapper.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/permissions/LuckPermissionsWrapper.java index 39975c8e7..7c053f320 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/permissions/LuckPermissionsWrapper.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/permissions/LuckPermissionsWrapper.java @@ -45,10 +45,10 @@ protected void removePermission(Player holder, String permission) { editPermission(holder.getUUID(), permission, LPPermissionType.PERM_REMOVE ); } protected void addGroupPermission(Player holder, String permission) { - editPermission(holder.getUUID(), permission, LPPermissionType.PERM_GROUP_ADD ); + editPermission(holder.getUUID(), permission, LPPermissionType.PERM_GROUP_ADD ); } protected void removeGroupPermission(Player holder, String permission) { - editPermission(holder.getUUID(), permission, LPPermissionType.PERM_GROUP_REMOVE ); + editPermission(holder.getUUID(), permission, LPPermissionType.PERM_GROUP_REMOVE ); } @SuppressWarnings( "deprecation" ) @@ -91,11 +91,6 @@ protected void editPermission(UUID uuid, String permission, LPPermissionType per break; } -// if(add) { -// result = user.setPermission(node); -// } else { -// result = user.unsetPermission(node); -// } // wasn't successful. // they most likely already have (or didn't have if add = false) the permission @@ -119,64 +114,64 @@ protected void editPermission(UUID uuid, String permission, LPPermissionType per public List getPermissions(Player holder, boolean detailed) { - List results = new ArrayList<>(); - - UUID uuid = holder.getUUID(); - + List results = new ArrayList<>(); + + UUID uuid = holder.getUUID(); + // get the user User user = api.getUser(uuid); if (user != null) { - // user loaded - - SortedSet permNodes = user.getPermissions(); - - for ( Node node : permNodes ) { - String perm = node.getPermission(); - StringBuilder details = new StringBuilder(); - - if ( detailed ) { - - if ( node.isTemporary() ) { - long seconds = node.getSecondsTilExpiry(); - String expiry = PlaceholdersUtil.formattedTime( seconds ); - - details.append(expiry); - } - - if ( node.isGroupNode() ) { - if ( details.length() > 0 ) { - details.append( ":" ); - } - details.append( "group=" ).append( node.getGroupName() ); - } - - if ( node.isWorldSpecific() ) { - if ( details.length() > 0 ) { - details.append( ":" ); - } - details.append( "world=" ).append( node.getWorld() ); - } - - if ( node.isMeta() ) { - if ( details.length() > 0 ) { - details.append( ":" ); - } - - Entry meta = node.getMeta(); - - details.append( "meta={" ).append( meta.getKey() ) - .append( "=" ).append( meta.getValue() ).append( "}" ); - } - - if ( details.length() > 0 ) { - details.insert( 0, "::" ); - } - - } - details.insert( 0, perm ); - - results.add( details.toString() ); - } + // user loaded + + SortedSet permNodes = user.getPermissions(); + + for ( Node node : permNodes ) { + String perm = node.getPermission(); + StringBuilder details = new StringBuilder(); + + if ( detailed ) { + + if ( node.isTemporary() ) { + long seconds = node.getSecondsTilExpiry(); + String expiry = PlaceholdersUtil.formattedTime( seconds ); + + details.append(expiry); + } + + if ( node.isGroupNode() ) { + if ( details.length() > 0 ) { + details.append( ":" ); + } + details.append( "group=" ).append( node.getGroupName() ); + } + + if ( node.isWorldSpecific() ) { + if ( details.length() > 0 ) { + details.append( ":" ); + } + details.append( "world=" ).append( node.getWorld() ); + } + + if ( node.isMeta() ) { + if ( details.length() > 0 ) { + details.append( ":" ); + } + + Entry meta = node.getMeta(); + + details.append( "meta={" ).append( meta.getKey() ) + .append( "=" ).append( meta.getValue() ).append( "}" ); + } + + if ( details.length() > 0 ) { + details.insert( 0, "::" ); + } + + } + details.insert( 0, perm ); + + results.add( details.toString() ); + } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/permissions/LuckPerms5.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/permissions/LuckPerms5.java index 02c8ef482..813a26b77 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/permissions/LuckPerms5.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/permissions/LuckPerms5.java @@ -67,27 +67,27 @@ public void removePermission( Player holder, String permission ) { @Override public void addGroupPermission(Player holder, String groupPermission) { - if ( permsWrapper != null ) { - permsWrapper.addGroupPermission( holder, groupPermission ); - } + if ( permsWrapper != null ) { + permsWrapper.addGroupPermission( holder, groupPermission ); + } } @Override public void removeGroupPermission(Player holder, String groupPermission) { - if ( permsWrapper != null ) { - permsWrapper.removeGroupPermission( holder, groupPermission ); - } + if ( permsWrapper != null ) { + permsWrapper.removeGroupPermission( holder, groupPermission ); + } } @Override public List getPermissions(Player holder, boolean detailed) { - List results = new ArrayList<>(); - - if ( permsWrapper != null ) { - results = permsWrapper.getPermissions(holder, detailed); - } - - return results; + List results = new ArrayList<>(); + + if ( permsWrapper != null ) { + results = permsWrapper.getPermissions(holder, detailed); + } + + return results; } @Override @@ -97,7 +97,7 @@ public boolean hasIntegrated() { @Override public void disableIntegration() { - permsWrapper = null; + permsWrapper = null; } @Override diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/permissions/LuckPerms5Wrapper.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/permissions/LuckPerms5Wrapper.java index 1299f6072..9d07bbe3a 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/permissions/LuckPerms5Wrapper.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/permissions/LuckPerms5Wrapper.java @@ -51,7 +51,6 @@ private enum LPPermissionType { public LuckPerms5Wrapper(RegisteredServiceProvider provider) { super(); -// LuckPerms api = provider.getProvider(); api = provider.getProvider(); } @@ -62,19 +61,12 @@ protected void removePermission(Player holder, String permission) { editPermission(holder.getUUID(), permission, LPPermissionType.PERM_REMOVE ); } protected void addGroupPermission(Player holder, String permission) { - editPermission(holder.getUUID(), permission, LPPermissionType.PERM_GROUP_ADD ); + editPermission(holder.getUUID(), permission, LPPermissionType.PERM_GROUP_ADD ); } protected void removeGroupPermission(Player holder, String permission) { - editPermission(holder.getUUID(), permission, LPPermissionType.PERM_GROUP_REMOVE ); + editPermission(holder.getUUID(), permission, LPPermissionType.PERM_GROUP_REMOVE ); } -// public void addPermission( Player holder, String permission ) { -// editPermission(holder.getUUID(), permission, true); -// } -// -// public void removePermission( Player holder, String permission ) { -// editPermission(holder.getUUID(), permission, false); -// } /** *

    This function does not return anything, nor is there anything waiting for its @@ -95,179 +87,145 @@ protected void removeGroupPermission(Player holder, String permission) { * @param add */ private void editPermission(UUID uuid, String permission, LPPermissionType permissionType) { - if ( api != null ) { - - UserManager um = api.getUserManager(); - User user = um.getUser(uuid); - CompletableFuture userFuture = (user == null ? - um.loadUser(uuid) : CompletableFuture.completedFuture(user)); - - userFuture - .thenAcceptAsync(lpUser -> { - changePermission(lpUser, permission, permissionType); - }); - } + if ( api != null ) { + + UserManager um = api.getUserManager(); + User user = um.getUser(uuid); + CompletableFuture userFuture = (user == null ? + um.loadUser(uuid) : CompletableFuture.completedFuture(user)); + + userFuture + .thenAcceptAsync(lpUser -> { + changePermission(lpUser, permission, permissionType); + }); + } } private void changePermission( User user, String permission, LPPermissionType permissionType ) { - boolean dirty = false; - - // build a permission node now so we don't have to pass around - // the raw components, just this node. -// PermissionNode newNode = null; // PermissionNode.builder(permission).build(); - - Node newNode = null; - boolean enable = permissionType == LPPermissionType.PERM_ADD || - permissionType == LPPermissionType.PERM_GROUP_ADD; - - switch ( permissionType ) - { - case PERM_ADD: - case PERM_REMOVE: - newNode = PermissionNode.builder(permission).build(); - break; - - case PERM_GROUP_ADD: - case PERM_GROUP_REMOVE: - newNode = InheritanceNode.builder(permission).build(); - break; - - default: - break; - } - - - // Try to remove the perm if it exists. Even if adding a perm, try to remove it - // to prevent possible duplicates. - if ( user.data().remove( newNode ) == DataMutateResult.SUCCESS ) { - dirty = true; - } - - // If the node is to be added/enabled, then try to add it: - if ( enable && user.data().add( newNode ) == DataMutateResult.SUCCESS ) { - dirty = true; - } - + boolean dirty = false; + + // build a permission node now so we don't have to pass around + // the raw components, just this node. + // PermissionNode newNode = null; // PermissionNode.builder(permission).build(); + + Node newNode = null; + boolean enable = permissionType == LPPermissionType.PERM_ADD || + permissionType == LPPermissionType.PERM_GROUP_ADD; + + switch ( permissionType ) + { + case PERM_ADD: + case PERM_REMOVE: + newNode = PermissionNode.builder(permission).build(); + break; + + case PERM_GROUP_ADD: + case PERM_GROUP_REMOVE: + newNode = InheritanceNode.builder(permission).build(); + break; + + default: + break; + } + + + // Try to remove the perm if it exists. Even if adding a perm, try to remove it + // to prevent possible duplicates. + if ( user.data().remove( newNode ) == DataMutateResult.SUCCESS ) { + dirty = true; + } + + // If the node is to be added/enabled, then try to add it: + if ( enable && user.data().add( newNode ) == DataMutateResult.SUCCESS ) { + dirty = true; + } + if ( dirty ) { api.getUserManager().saveUser( user ); } } - - + + public List getPermissions(Player holder, boolean detailed) { - List results = new ArrayList<>(); - - UUID uuid = holder.getUUID(); - - if ( api != null ) { - + List results = new ArrayList<>(); + + UUID uuid = holder.getUUID(); + + if ( api != null ) { + UserManager um = api.getUserManager(); - User user = um.getUser(uuid); - - if (user != null) { - - SortedSet permNodes = user.resolveDistinctInheritedNodes( QueryOptions.nonContextual() ); -// SortedSet permNodes = user.getDistinctNodes(); - - for ( Node node : permNodes ) { - - String perm = node.getKey(); - -// String perm = node.getPermission(); - StringBuilder details = new StringBuilder(); - - if ( detailed ) { - - if ( node.hasExpiry() ) { - double seconds = (System.currentTimeMillis() - node.getExpiry().toEpochMilli()) / 1000.0; - String expiry = PlaceholdersUtil.formattedTime( seconds ); - - details.append(expiry); - } - - if ( node.hasExpired() ) { - if ( details.length() > 0 ) { - details.append( ":" ); - } - details.append( "expired" ); - } - - // Group node: Redundant since groups are prefixed with "group." - if ( node.getType() == NodeType.INHERITANCE ) { - //if ( details.length() > 0 ) { - // details.append( ":" ); - //} - //details.append( "group=" ).append( node.getKey() ); - } - -// // Permission node: -// if ( node.getType() == NodeType.PERMISSION ) { -// if ( details.length() > 0 ) { -// details.append( ":" ); -// } -// details.append( "permission=" ).append( node.getKey() ); -// } - - - // Weighted node: - if ( node.getType() == NodeType.WEIGHT ) { - if ( details.length() > 0 ) { - details.append( ":" ); - } - WeightNode weighted = (WeightNode) node; - - details.append( "weighted=" ).append( weighted.getWeight() ); - } - - // Weighted node: - if ( node.getContexts().containsKey( DefaultContextKeys.WORLD_KEY ) ) { - if ( details.length() > 0 ) { - details.append( ":" ); - } - details.append( "Worlds=" ).append( - String.join( ",", - node.getContexts().getValues( DefaultContextKeys.WORLD_KEY ) )); - } - -// if ( node.getType() == NodeType.PERMISSION ) { -// node.get -// } -// -// if ( node.isWorldSpecific() ) { -// if ( details.length() > 0 ) { -// details.append( ":" ); -// } -// details.append( "world=" ).append( node.getWorld() ); -// } -// -// if ( node.isMeta() ) { -// if ( details.length() > 0 ) { -// details.append( ":" ); -// } -// -// Entry meta = node.getMeta(); -// -// details.append( "meta={" ).append( meta.getKey() ) -// .append( "=" ).append( meta.getValue() ).append( "}" ); -// } - - if ( details.length() > 0 ) { - details.insert( 0, "::" ); - } - - } - details.insert( 0, perm ); - - results.add( details.toString() ); - } - } - } - - + User user = um.getUser(uuid); + + if (user != null) { + + SortedSet permNodes = user.resolveDistinctInheritedNodes( QueryOptions.nonContextual() ); + + for ( Node node : permNodes ) { + + String perm = node.getKey(); + + StringBuilder details = new StringBuilder(); + + if ( detailed ) { + + if ( node.hasExpiry() ) { + double seconds = (System.currentTimeMillis() - node.getExpiry().toEpochMilli()) / 1000.0; + String expiry = PlaceholdersUtil.formattedTime( seconds ); + + details.append(expiry); + } + + if ( node.hasExpired() ) { + if ( details.length() > 0 ) { + details.append( ":" ); + } + details.append( "expired" ); + } + + // Group node: Redundant since groups are prefixed with "group." + if ( node.getType() == NodeType.INHERITANCE ) { + //if ( details.length() > 0 ) { + // details.append( ":" ); + //} + //details.append( "group=" ).append( node.getKey() ); + } + + + + // Weighted node: + if ( node.getType() == NodeType.WEIGHT ) { + if ( details.length() > 0 ) { + details.append( ":" ); + } + WeightNode weighted = (WeightNode) node; + + details.append( "weighted=" ).append( weighted.getWeight() ); + } + + // Weighted node: + if ( node.getContexts().containsKey( DefaultContextKeys.WORLD_KEY ) ) { + if ( details.length() > 0 ) { + details.append( ":" ); + } + details.append( "Worlds=" ).append( + String.join( ",", + node.getContexts().getValues( DefaultContextKeys.WORLD_KEY ) )); + } + + + if ( details.length() > 0 ) { + details.insert( 0, "::" ); + } + + } + details.insert( 0, perm ); + + results.add( details.toString() ); + } + } + } - - return results; } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/MVdWPlaceholderIntegration.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/MVdWPlaceholderIntegration.java index 44c020524..1d99f8283 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/MVdWPlaceholderIntegration.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/MVdWPlaceholderIntegration.java @@ -18,186 +18,8 @@ */ public class MVdWPlaceholderIntegration // extends PlaceholderIntegration - { +{ + + // Purged commented out code. See github's history to see what it was. -// private MVdWPlaceholderIntegrationWrapper placeholderWrapper; -// -// public MVdWPlaceholderIntegration() { -// super( "MVdWPlaceholderAPI", "MVdWPlaceholderAPI" ); -// } - -// @Override -// public void integrate() { -// if ( isRegistered()) { -// try { -// if ( Bukkit.getPluginManager().isPluginEnabled(getProviderName())) { -// -// -// // The integration was written for MVdW v3.0.0, but if used with older versions -// // it will fail. -// -// // This will fail if the version of mvdw is v2.x.x, which is what we want: -// Class.forName("be.maximvdw.placeholderapi.PlaceholderAPI", false, getClass().getClassLoader()); -// -// MVdWPlaceholderIntegrationWrapper wrap = new MVdWPlaceholderIntegrationWrapper(getProviderName()); -// -// placeholderWrapper = wrap; -// -// PrisonAPI.getIntegrationManager().addDeferredInitialization( this ); -// } -// } -// catch ( NoClassDefFoundError e ) { -// // ignore this exception since it means the plugin was not loaded -// Output.get().logWarn( "Attempted to enable the MVdWPlaceholderIntegration but it failed to find the " + -// "class 'be.maximvdw.placeholderapi.PlaceholderAPI'. This could happen when using " + -// "MVdWPlaceholderApi v2.x.x. Prison ONLY support MVdW v3.x.x. " + -// "&c****&7 Try using PlaceholderAPI (papi) instead. &c****" ); -// } -// catch ( IllegalStateException e ) { -// // ignore ... plugin is not loaded -// } -// catch ( Exception e ) { -// e.printStackTrace(); -// } -// } -// } - - -// /** -// *

    Register both the player and mines placeholders with the MVdW plugin. -// *

    -// */ -// @Override -// public void deferredInitialization() -// { -// boolean registered = false; -// if ( PrisonRanks.getInstance() != null && PrisonRanks.getInstance().isEnabled() ) { -// -// PlayerManager pm = PrisonRanks.getInstance().getPlayerManager(); -// if ( pm != null ) { -// List placeholderPlayerKeys = pm.getTranslatedPlaceHolderKeys(); -// -// for ( PlaceHolderKey placeHolderKey : placeholderPlayerKeys ) { -// if ( !placeHolderKey.getPlaceholder().isSuppressed() ) { -// -// -// registerPlaceholder(placeHolderKey.getKey(), -// player -> { -// -// PlaceholderIdentifier identifier = new PlaceholderIdentifier( placeHolderKey.getPlaceholder().name() ); -// identifier.setPlayer( player.getUUID(), player.getName() ); -// -// if ( identifier.checkPlaceholderKey(placeHolderKey) ) { -// -// pm.getTranslatePlayerPlaceHolder( identifier ); -// } -// -// -// return Text.translateAmpColorCodes( identifier.getText() ); -// }); -// if ( !registered ) { -// registered = true; -// } -// } -// } -// } -// -// RankManager rm = PrisonRanks.getInstance().getRankManager(); -// if ( rm != null ) { -// List placeholderPlayerKeys = rm.getTranslatedPlaceHolderKeys(); -// -// for ( PlaceHolderKey placeHolderKey : placeholderPlayerKeys ) { -// if ( !placeHolderKey.getPlaceholder().isSuppressed() ) { -// -// -// registerPlaceholder(placeHolderKey.getKey(), -// player -> { -// -// PlaceholderIdentifier identifier = new PlaceholderIdentifier( placeHolderKey.getPlaceholder().name() ); -// identifier.setPlayer( player.getUUID(), player.getName() ); -// -// if ( identifier.checkPlaceholderKey(placeHolderKey) ) { -// -// rm.getTranslateRanksPlaceHolder( identifier ); -// } -// -// -// return Text.translateAmpColorCodes( identifier.getText() ); -// }); -// if ( !registered ) { -// registered = true; -// } -// } -// } -// } -// } -// -// -// if ( PrisonMines.getInstance() != null && PrisonMines.getInstance().isEnabled() ) { -// MineManager mm = PrisonMines.getInstance().getMineManager(); -// if ( mm != null ) { -// List placeholderMinesKeys = mm.getTranslatedPlaceHolderKeys(); -// -// for ( PlaceHolderKey placeHolderKey : placeholderMinesKeys ) { -// if ( !placeHolderKey.getPlaceholder().isSuppressed() ) { -// -// registerPlaceholder(placeHolderKey.getKey(), -// player -> { -// -// PlaceholderIdentifier identifier = new PlaceholderIdentifier( placeHolderKey.getPlaceholder().name() ); -// identifier.setPlayer( player.getUUID(), player.getName() ); -// -// if ( identifier.checkPlaceholderKey(placeHolderKey) ) { -// -// mm.getTranslateMinesPlaceholder( identifier ); -// } -// -// return Text.translateAmpColorCodes( identifier.getText() ); -// } ); -// if ( !registered ) { -// registered = true; -// } -// } -// } -// } -// } -// -//// if ( registered ) { -//// Output.get().logWarn( "Prison registered all placeholders with MVdWPlaceholderAPI, " + -//// "but unfortunately MVdWPlaceholderAPI does not support dynamic placeholders " + -//// "that are available for customizations within prison. Please try adding " + -//// "Vault and PlaceholderAPI (papi) to your setup, if they do not already exist, " + -//// "to enable these features."); -//// } -// } -// -// -// @Override -// public void registerPlaceholder(String placeholder, Function action) { -// if (placeholderWrapper != null) { -// placeholderWrapper.registerPlaceholder( placeholder, action ); -// } -// } -// -// @Override -// public boolean hasIntegrated() { -// return (placeholderWrapper != null); -// } -// -// @Override -// public void disableIntegration() { -// placeholderWrapper = null; -// } -// -// @Override -// public String getAlternativeInformation() { -// return null; -// } -// -// -// @Override -// public String getPluginSourceURL() { -// return "https://www.spigotmc.org/resources/mvdwplaceholderapi.11182/"; -// } - } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/MVdWPlaceholderIntegrationWrapper.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/MVdWPlaceholderIntegrationWrapper.java index 187005edc..7b9389c2e 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/MVdWPlaceholderIntegrationWrapper.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/MVdWPlaceholderIntegrationWrapper.java @@ -5,15 +5,6 @@ */ public class MVdWPlaceholderIntegrationWrapper { + // Purged commented out code. See github's history to see what it was. -// public MVdWPlaceholderIntegrationWrapper(String providerName) { -// super(); -// } -// -// public void registerPlaceholder(String placeholder, Function action) { -// PlaceholderAPI.registerPlaceholder( -// Bukkit.getPluginManager().getPlugin("Prison"), placeholder, -// e -> action.apply(new SpigotPlayer(e.getPlayer()))); -// } - } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/PlaceHolderAPIIntegrationUppercaseWrapper.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/PlaceHolderAPIIntegrationUppercaseWrapper.java index da133e074..2f16b20a1 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/PlaceHolderAPIIntegrationUppercaseWrapper.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/PlaceHolderAPIIntegrationUppercaseWrapper.java @@ -19,10 +19,6 @@ public PlaceHolderAPIIntegrationUppercaseWrapper() { } -// public void registerPlaceholder(String placeholder, Function action) { -// this.register(); -// } - /** * This method should always return true unless we * have a dependency we need to make sure is on the server @@ -78,14 +74,9 @@ public String getVersion(){ @Override public String onRequest(OfflinePlayer player, String identifier) { -// if ( !identifier.toLowerCase().startsWith( PlaceholderManager.PRISON_PLACEHOLDER_PREFIX_EXTENDED ) ) { -// identifier = PlaceholderManager.PRISON_PLACEHOLDER_PREFIX_EXTENDED + identifier; -// } - UUID playerUuid = player == null ? null : player.getUniqueId(); String results = Prison.get().getPlatform().getPlaceholders() .placeholderTranslate( playerUuid, player.getName(), identifier ); - return ChatColor.translateAlternateColorCodes( '&', results); } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/PlaceHolderAPIIntegrationWrapper.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/PlaceHolderAPIIntegrationWrapper.java index 48593a814..00670b018 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/PlaceHolderAPIIntegrationWrapper.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/PlaceHolderAPIIntegrationWrapper.java @@ -19,10 +19,6 @@ public PlaceHolderAPIIntegrationWrapper() { } -// public void registerPlaceholder(String placeholder, Function action) { -// this.register(); -// } - /** * This method should always return true unless we * have a dependency we need to make sure is on the server @@ -79,10 +75,6 @@ public String getVersion(){ public String onRequest(OfflinePlayer player, String identifier) { String results = null; -// if ( !identifier.toLowerCase().startsWith( PlaceholderManager.PRISON_PLACEHOLDER_PREFIX_EXTENDED ) ) { -// identifier = PlaceholderManager.PRISON_PLACEHOLDER_PREFIX_EXTENDED + identifier; -// } - if( player != null ) { UUID playerUuid = player.getUniqueId(); 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 0eb1ada54..5e8c2937d 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 @@ -267,21 +267,6 @@ public String placeholderTranslate( UUID playerUuid, String playerName, String p return processPlaceholderIdentifier( identifier ); } - // NOTE: This is obsolete since the player should always be included: -// /** -// *

    This function is used in this class's placeholderTranslateText() and -// * also in tech.mcprison.prison.mines.MinesChatHandler.onPlayerChat(). -// *

    -// * -// */ -// @Override -// public String placeholderTranslateText( String text) { -// PlaceholderIdentifier identifier = new PlaceholderIdentifier( text ); -// -// -// return placeholderTranslateText( identifier ); -// } - private String processPlaceholderIdentifier( PlaceholderIdentifier identifier ) { long nanoStart = System.nanoTime(); @@ -444,25 +429,6 @@ else if ( rm != null && return identifier.getText(); } -// /** -// * This provides for a case insensitive replacement of placeholders. -// * -// * String target = "FOOBar"; -// * target = target.replaceAll("(?i)foo", ""); -// * -// * @param text The full text that contains one or more placeholders. This is also the value that -// * will be returned, with the replacement of the contained placeholder. -// * @param placeholder The individual placeholder that should be replaced. This should be the -// * raw value of the identifier, including escape chaacters and placeholder attributes. -// * @param target The text that should replace the whole placeholder. -// * @return -// */ -// private String placeholderReplace( String text, String placeholder, String target ) { -// -// return text == null || placeholder == null || target == null ? -// text : text.replaceAll( "(?i)" + Pattern.quote(placeholder) , target ); -// } - /** *

    The rawText passed to this function may have zero, one, or more placeholders included 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 7f00c1fb6..16591013f 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 @@ -59,48 +59,48 @@ public static void debugItemsSold( List soldItems, SpigotPlayer sPl } public static String itemsSoldReport( List soldItems, SpigotPlayer sPlayer, double multiplier ) { - StringBuilder sb = new StringBuilder(); - StringBuilder sbItems = new StringBuilder(); - - double totalAmount = 0; - int itemCount = 0; - int stacks = soldItems.size(); - - // Add same blocks together: - soldItems = compressSoldItems( soldItems ); - - 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( stacks ) - .append( " ItemCount: " ) - .append( iFmt.format(itemCount) ) - .append( " TotalAmount: " ) - .append( dFmt.format( totalAmount )) - .append( " [" ) - .append( sbItems ) - .append("]"); - - return sb.toString(); + StringBuilder sb = new StringBuilder(); + StringBuilder sbItems = new StringBuilder(); + + double totalAmount = 0; + int itemCount = 0; + int stacks = soldItems.size(); + + // Add same blocks together: + soldItems = compressSoldItems( soldItems ); + + 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( stacks ) + .append( " ItemCount: " ) + .append( iFmt.format(itemCount) ) + .append( " TotalAmount: " ) + .append( dFmt.format( totalAmount )) + .append( " [" ) + .append( sbItems ) + .append("]"); + + return sb.toString(); } private static List compressSoldItems(List soldItems) { 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 5cf73c06a..13f8a5731 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 @@ -56,24 +56,18 @@ public class SellAllUtil private static SellAllUtil instance; - -// private final Compatibility compat = SpigotPrison.getInstance().getCompatibility(); - -// private final ItemStack lapisLazuli = compat.getLapisItemStack(); public Configuration sellAllConfig; private static Boolean isAutoSellEnabled = null; private HashMap sellAllItems; -// private HashMap sellAllBlocks; private HashMap sellAllPrestigeMultipliers; private HashMap autoSellEarningsNotificationWaiting = new HashMap<>(); private ArrayList sellAllItemTriggers; private ArrayList activePlayerDelay = new ArrayList<>(); -// private List sellAllDisabledWorlds; -// private MessagesConfig messages; + private double defaultMultiplier; private int defaultSellAllDelay; private int defaultAutoSellEarningNotificationDelay; @@ -135,13 +129,13 @@ public static SellAllUtil get() { } public static boolean isAutoSellEnabled() { - - if ( isAutoSellEnabled == null ) { - - isAutoSellEnabled = SpigotPrison.getInstance().isSellAllEnabled(); - } - - return isAutoSellEnabled == null ? false : isAutoSellEnabled; + + if ( isAutoSellEnabled == null ) { + + isAutoSellEnabled = SpigotPrison.getInstance().isSellAllEnabled(); + } + + return isAutoSellEnabled == null ? false : isAutoSellEnabled; } /** @@ -161,7 +155,6 @@ public Configuration initCachedData() { private void refreshClassVariablesFromConfig() { -// 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"); @@ -172,19 +165,15 @@ private void refreshClassVariablesFromConfig() { 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).get(); 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).get(); 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")); @@ -221,35 +210,35 @@ private void refreshClassVariablesFromConfig() { } private boolean getBooleanValue( String configName ) { - return getBooleanValue(configName, false); + 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; + 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; } @@ -265,9 +254,9 @@ public void setSellAllItemTriggers(ArrayList sellAllItemTriggers) { public PrisonBlock getSellallItem( PrisonBlock blockKey ) { - PrisonBlock pBlockSellAll = sellAllItems.get( blockKey.getBlockNameSearch() ); - - return pBlockSellAll; + PrisonBlock pBlockSellAll = sellAllItems.get( blockKey.getBlockNameSearch() ); + + return pBlockSellAll; } public void putSellallItem( PrisonBlock pBlockKey ) { sellAllItems.put( pBlockKey.getBlockNameSearch(), pBlockKey ); @@ -303,25 +292,16 @@ public HashMap getPrestigeMultipliers() { public PrisonBlock getSellAllPrisonBlockKey( String itemID ) { - PrisonBlock pBlockKey = Prison.get().getPlatform().getPrisonBlock( itemID ); - if ( pBlockKey == null ) { - Output.get().logDebug( "sellall add: invalid block name (%s)", itemID); - return null; - } - - return pBlockKey; + PrisonBlock pBlockKey = Prison.get().getPlatform().getPrisonBlock( itemID ); + if ( pBlockKey == null ) { + Output.get().logDebug( "sellall add: invalid block name (%s)", itemID); + return null; + } + + return pBlockKey; } -// /** -// * 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. * These items will trigger sellall when a player hold them and then do shift+right click in the air. @@ -332,141 +312,9 @@ public ArrayList getItemTriggerXMaterials(){ return sellAllItemTriggers; } -// /** -// * 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. -// * -// * Get an ArrayList of SellAllItemTriggers as Materials. -// * This will essentially do a conversion of the cached internal XMaterial ArrayList of SellAllItemTriggers. -// * -// * @return ArrayList of Materials. -// * */ -// public ArrayList getItemTriggerMaterials(){ -// if (sellAllItemTriggers == null || sellAllItemTriggers.isEmpty()){ -// return new ArrayList<>(); -// } -// -// ArrayList materials = new ArrayList<>(); -// -// for (XMaterial xMaterial : sellAllItemTriggers){ -// materials.add(xMaterial.parseMaterial()); -// } -// -// 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; -// } - -// /** -// * Return SellAll Blocks HashMap cached values. -// * -// * @return HashMap of XMaterial-Double. -// * */ -// public HashMap getSellAllBlocks() { -// return sellAllBlocks; -// } - - -// /** -// * 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. -// * */ -// 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. @@ -476,7 +324,7 @@ public ArrayList getItemTriggerXMaterials(){ * @return double. * */ public double getPlayerMultiplier( Player player ) { - return getPlayerMultiplier( new SpigotPlayer( player )); + return getPlayerMultiplier( new SpigotPlayer( player )); } public double getPlayerMultiplier( tech.mcprison.prison.internal.Player sPlayer ) { @@ -488,10 +336,6 @@ public double getPlayerMultiplier( tech.mcprison.prison.internal.Player sPlayer } -// long tPoint1 = System.nanoTime(); - -// SpigotPlayer sPlayer = new SpigotPlayer(p); - double multiplier = 0d; double rankMultiplers = 0; @@ -518,44 +362,12 @@ public double getPlayerMultiplier( tech.mcprison.prison.internal.Player sPlayer } if ( rankMultiplers == 0 ) { - multiplier = defaultMultiplier; + multiplier = defaultMultiplier; } else { multiplier = rankMultiplers; } - - - - -// long tPoint2 = System.nanoTime(); - - // Get multiplier depending on Player + Prestige. NOTE that prestige multiplier will replace - // the actual default multiplier. -// if (module != null) { -// PrisonRanks rankPlugin = (PrisonRanks) module; -// if (rankPlugin.getPlayerManager().getPlayer(sPlayer) != null) { -// String playerRankName; -// try { -// -// RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); -// -// RankPlayer rankPlayer = rankPlugin.getPlayerManager().getPlayer(sPlayer); -// PlayerRank pRank = rankPlayer == null ? null : rankPlayerFactory.getRank( rankPlayer, "prestiges"); -// Rank rank = pRank == null ? null : pRank.getRank(); -// -// playerRankName = rank == null ? null : rank.getName(); -// } catch (NullPointerException ex) { -// playerRankName = null; -// } -// if (playerRankName != null) { -// String multiplierRankString = sellAllConfig.getString("Multiplier." + playerRankName + ".MULTIPLIER"); -// if (multiplierRankString != null && sellAllPrestigeMultipliers.containsKey(playerRankName)){ -// multiplier = sellAllPrestigeMultipliers.get(playerRankName); -// } -// } -// } -// } // Get Multiplier from multipliers permission's if there's any. String permPattern = "prison.sellall.multiplier."; @@ -563,517 +375,378 @@ public double getPlayerMultiplier( tech.mcprison.prison.internal.Player sPlayer // If the player is off line, then try to use the snapshot of the last group of perms: - if ( perms.size() == 0 && sPlayer.getRankPlayer() != null ) { - perms.addAll( sPlayer.getPermissions( permPattern, sPlayer.getRankPlayer().getPermsSnapShot() )); - } + if ( perms.size() == 0 && sPlayer.getRankPlayer() != null ) { + perms.addAll( sPlayer.getPermissions( permPattern, sPlayer.getRankPlayer().getPermsSnapShot() )); + } double multiplierExtraByPerms = 0; for (String multByPerm : perms) { - String multStr = multByPerm.replace(permPattern, ""); - if ( multStr.contains( "_" ) ) { - multStr = multStr.substring( 0, multStr.indexOf("_") ); - } - + String multStr = multByPerm.replace(permPattern, ""); + if ( multStr.contains( "_" ) ) { + multStr = multStr.substring( 0, multStr.indexOf("_") ); + } + double multByPermDouble = Double.parseDouble( multStr ); boolean highest = multByPermDouble > multiplierExtraByPerms; - + if ( !isSellAllPermissionMultiplierOnlyHigherEnabled ) { multiplierExtraByPerms += multByPermDouble; } else { - - if ( highest ) { - multiplierExtraByPerms = multByPermDouble; - } + + if ( highest ) { + multiplierExtraByPerms = multByPermDouble; + } } } - multiplier += multiplierExtraByPerms; - -// long tPoint3 = System.nanoTime(); -// DecimalFormat dFmt = Prison.get().getDecimalFormat( "0.0000" ); -// String debugMsg = "{sellallMult::" + dFmt.format( multiplier ) + ":t1=" + -// dFmt.format( (tPoint2 - tPoint1)/1000000d ) + -// ":t2=" + dFmt.format( (tPoint3 - tPoint2)/1000000 ) + "}"; -// Output.get().logDebug( debugMsg ); - return multiplier; } public double getPlayerMultiplierDebug( tech.mcprison.prison.internal.Player sPlayer ) { - StringBuilder sb = new StringBuilder(); - - long tPoint1 = System.nanoTime(); - - sb.append( "&dCalculate Sellall Player Multipliers: &6" ) - .append( sPlayer.getName() ); - - if (!isSellAllMultiplierEnabled) { - - sb.append( " &cSellall Multipliers are disabled." ); - if ( Output.get().isDebug() ) { - Output.get().logInfo( sb.toString() ); - } - - return 1d; - } - - - sb.append( " &aEnabled &6DefaultMult: &c" ) - .append( defaultMultiplier ); - - if ( isSellAllPermissionMultiplierOnlyHigherEnabled ) { - sb.append( " &a(Use only the highest perm multiplier) " ); - } - - - - -// SpigotPlayer sPlayer = new SpigotPlayer(p); - - double multiplier = 0d; - double rankMultiplers = 0; - - sb.append( "&6RankMulipliers: &a[ &6" ); - - if ( PrisonRanks.getInstance() != null && PrisonRanks.getInstance().isEnabled() ) { - - - RankPlayer rPlayer = sPlayer.getRankPlayer(); - - Set keys = rPlayer.getLadderRanks().keySet(); - for (RankLadder ladderKey : keys) { - PlayerRank pRank = rPlayer.getLadderRanks().get(ladderKey); - String rankName = pRank.getRank().getName(); - - String multiplierRankString = sellAllConfig.getString("Multiplier." + rankName + ".MULTIPLIER"); - - if (multiplierRankString != null && sellAllPrestigeMultipliers.containsKey( rankName )){ - - double rankMult = sellAllPrestigeMultipliers.get( rankName ); - rankMultiplers += rankMult; - - sb.append( rankMult ).append( " " ); - } - } - } - - if ( rankMultiplers == 0 ) { - multiplier = defaultMultiplier; - sb.append( "&cnone " ); - } - else { - multiplier = rankMultiplers; - } - - sb.append( "&a] " ); - - - sb.append( "&6Base multiplier: &c" ) - .append( multiplier ).append( " " ); - - - - long tPoint2 = System.nanoTime(); - - // Get multiplier depending on Player + Prestige. NOTE that prestige multiplier will replace - // the actual default multiplier. -// if (module != null) { -// PrisonRanks rankPlugin = (PrisonRanks) module; -// if (rankPlugin.getPlayerManager().getPlayer(sPlayer) != null) { -// String playerRankName; -// try { -// -// RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); -// -// RankPlayer rankPlayer = rankPlugin.getPlayerManager().getPlayer(sPlayer); -// PlayerRank pRank = rankPlayer == null ? null : rankPlayerFactory.getRank( rankPlayer, "prestiges"); -// Rank rank = pRank == null ? null : pRank.getRank(); -// -// playerRankName = rank == null ? null : rank.getName(); -// } catch (NullPointerException ex) { -// playerRankName = null; -// } -// if (playerRankName != null) { -// String multiplierRankString = sellAllConfig.getString("Multiplier." + playerRankName + ".MULTIPLIER"); -// if (multiplierRankString != null && sellAllPrestigeMultipliers.containsKey(playerRankName)){ -// multiplier = sellAllPrestigeMultipliers.get(playerRankName); -// } -// } -// } -// } - - // Get Multiplier from multipliers permission's if there's any. - String permPattern = "prison.sellall.multiplier."; - List perms = sPlayer.getPermissions( permPattern ); - List debugRejected = new ArrayList<>(); - String debugHighest = null; - - if ( perms.size() == 0 && sPlayer.getRankPlayer() != null ) { - sb.append( "&cNoBukkkitPerms " ); - - perms.addAll( sPlayer.getPermissions( permPattern, sPlayer.getRankPlayer().getPermsSnapShot() )); - - if ( perms.size() > 0 ) { - - sb.append( "&c(Using &6" ); - sb.append( perms.size() ); - sb.append( " &csnapshotPerms) " ); - } - } - - sb.append( "&6PermissionMulipliers: &a[ &6" ); - - - double multiplierExtraByPerms = 0; - for (String multByPerm : perms) { - - String multStr = multByPerm.replace(permPattern, ""); - if ( multStr.contains( "_" ) ) { - multStr = multStr.substring( 0, multStr.indexOf("_") ); - } - - double multByPermDouble = Double.parseDouble( multStr ); - - boolean highest = multByPermDouble > multiplierExtraByPerms; - - String debugMult = multByPermDouble + ":" + multByPerm + "&r "; - - if ( !isSellAllPermissionMultiplierOnlyHigherEnabled ) { - multiplierExtraByPerms += multByPermDouble; - - sb.append( "&6" ) - .append( debugMult ); - } - else { - - if ( highest ) { - multiplierExtraByPerms = multByPermDouble; - - if ( debugHighest != null ) { - debugRejected.add( debugHighest ); - } - debugHighest = debugMult; - } - else { - debugRejected.add( debugMult ); - } - - } - - } - - if ( debugHighest != null ) { - sb.append( "&6" ) // Green - .append( debugHighest ); - } - - for (String rejected : debugRejected) { - sb.append( "&m&c" ) // Strike through & red - .append( rejected ); - } - - sb.append( " &a] " ); - - - multiplier += multiplierExtraByPerms; - - sb.append( "&6PermissionTotal: &a[ &6" ) - .append( multiplierExtraByPerms ) - .append( " &a] " ); - - sb.append( "&6TotalMultiplier: &a[ &6" ) - .append( multiplier ) - .append( " &a] " ); - - long tPoint3 = System.nanoTime(); - DecimalFormat dFmt = Prison.get().getDecimalFormat( "0.0000" ); - String debugMsg = " :t1=" + - dFmt.format( (tPoint2 - tPoint1)/1000000d ) + - " :t2=" + - dFmt.format( (tPoint3 - tPoint2)/1000000 ) + "}"; - - sb.append( debugMsg ); - - - Output.get().logInfo( sb.toString() ); - - return multiplier; + StringBuilder sb = new StringBuilder(); + + long tPoint1 = System.nanoTime(); + + sb.append( "&dCalculate Sellall Player Multipliers: &6" ) + .append( sPlayer.getName() ); + + if (!isSellAllMultiplierEnabled) { + + sb.append( " &cSellall Multipliers are disabled." ); + if ( Output.get().isDebug() ) { + Output.get().logInfo( sb.toString() ); + } + + return 1d; + } + + + sb.append( " &aEnabled &6DefaultMult: &c" ) + .append( defaultMultiplier ); + + if ( isSellAllPermissionMultiplierOnlyHigherEnabled ) { + sb.append( " &a(Use only the highest perm multiplier) " ); + } + + + + double multiplier = 0d; + double rankMultiplers = 0; + + sb.append( "&6RankMulipliers: &a[ &6" ); + + if ( PrisonRanks.getInstance() != null && PrisonRanks.getInstance().isEnabled() ) { + + + RankPlayer rPlayer = sPlayer.getRankPlayer(); + + Set keys = rPlayer.getLadderRanks().keySet(); + for (RankLadder ladderKey : keys) { + PlayerRank pRank = rPlayer.getLadderRanks().get(ladderKey); + String rankName = pRank.getRank().getName(); + + String multiplierRankString = sellAllConfig.getString("Multiplier." + rankName + ".MULTIPLIER"); + + if (multiplierRankString != null && sellAllPrestigeMultipliers.containsKey( rankName )){ + + double rankMult = sellAllPrestigeMultipliers.get( rankName ); + rankMultiplers += rankMult; + + sb.append( rankMult ).append( " " ); + } + } + } + + if ( rankMultiplers == 0 ) { + multiplier = defaultMultiplier; + sb.append( "&cnone " ); + } + else { + multiplier = rankMultiplers; + } + + sb.append( "&a] " ); + + + sb.append( "&6Base multiplier: &c" ) + .append( multiplier ).append( " " ); + + + long tPoint2 = System.nanoTime(); + + + // Get Multiplier from multipliers permission's if there's any. + String permPattern = "prison.sellall.multiplier."; + List perms = sPlayer.getPermissions( permPattern ); + List debugRejected = new ArrayList<>(); + String debugHighest = null; + + if ( perms.size() == 0 && sPlayer.getRankPlayer() != null ) { + sb.append( "&cNoBukkkitPerms " ); + + perms.addAll( sPlayer.getPermissions( permPattern, sPlayer.getRankPlayer().getPermsSnapShot() )); + + if ( perms.size() > 0 ) { + + sb.append( "&c(Using &6" ); + sb.append( perms.size() ); + sb.append( " &csnapshotPerms) " ); + } + } + + sb.append( "&6PermissionMulipliers: &a[ &6" ); + + + double multiplierExtraByPerms = 0; + for (String multByPerm : perms) { + + String multStr = multByPerm.replace(permPattern, ""); + if ( multStr.contains( "_" ) ) { + multStr = multStr.substring( 0, multStr.indexOf("_") ); + } + + double multByPermDouble = Double.parseDouble( multStr ); + + boolean highest = multByPermDouble > multiplierExtraByPerms; + + String debugMult = multByPermDouble + ":" + multByPerm + "&r "; + + if ( !isSellAllPermissionMultiplierOnlyHigherEnabled ) { + multiplierExtraByPerms += multByPermDouble; + + sb.append( "&6" ) + .append( debugMult ); + } + else { + + if ( highest ) { + multiplierExtraByPerms = multByPermDouble; + + if ( debugHighest != null ) { + debugRejected.add( debugHighest ); + } + debugHighest = debugMult; + } + else { + debugRejected.add( debugMult ); + } + + } + + } + + if ( debugHighest != null ) { + sb.append( "&6" ) // Green + .append( debugHighest ); + } + + for (String rejected : debugRejected) { + sb.append( "&m&c" ) // Strike through & red + .append( rejected ); + } + + sb.append( " &a] " ); + + + multiplier += multiplierExtraByPerms; + + sb.append( "&6PermissionTotal: &a[ &6" ) + .append( multiplierExtraByPerms ) + .append( " &a] " ); + + sb.append( "&6TotalMultiplier: &a[ &6" ) + .append( multiplier ) + .append( " &a] " ); + + long tPoint3 = System.nanoTime(); + DecimalFormat dFmt = Prison.get().getDecimalFormat( "0.0000" ); + String debugMsg = " :t1=" + + dFmt.format( (tPoint2 - tPoint1)/1000000d ) + + " :t2=" + + dFmt.format( (tPoint3 - tPoint2)/1000000 ) + "}"; + + sb.append( debugMsg ); + + + Output.get().logInfo( sb.toString() ); + + return multiplier; } public List getPlayerMultiplierList( Player p ) { - List results = new ArrayList<>(); - - - if (!isSellAllMultiplierEnabled) { - results.add( "1.0 - Sellall multipler is disabled. Default value." ); - - return results; - } - - DecimalFormat dFmt = Prison.getDecimalFormatStaticDouble(); - - SpigotPlayer sPlayer = new SpigotPlayer(p); - - if ( PrisonRanks.getInstance() != null && PrisonRanks.getInstance().isEnabled() ) { - - RankPlayer rPlayer = sPlayer.getRankPlayer(); - - Set keys = rPlayer.getLadderRanks().keySet(); - for (RankLadder ladderKey : keys) { - PlayerRank pRank = rPlayer.getLadderRanks().get(ladderKey); - String rankName = pRank.getRank().getName(); - - String multiplierRankString = sellAllConfig.getString("Multiplier." + rankName + ".MULTIPLIER"); - if (multiplierRankString != null && sellAllPrestigeMultipliers.containsKey( rankName )){ - double mult = sellAllPrestigeMultipliers.get( rankName ); - String msg = String.format( - "%s - %s rank Sellall multiplier", - dFmt.format(mult), rankName - ); - results.add( msg ); - } - } - } - - if ( results.size() == 0 ) { - String msg = String.format( - "%s - default Sellall multiplier - no rank mulitiplers", - dFmt.format(defaultMultiplier) - ); - results.add(msg); - } - - - // Get Multiplier from multipliers permission's if there's any. - List perms = sPlayer.getPermissions("prison.sellall.multiplier."); - double multiplierExtraByPerms = 0; - int count = 0; - String greatestPerm = ""; - for (String multByPerm : perms) { - - double multByPermDouble = Double.parseDouble(multByPerm.substring(26)); - - if ( !isSellAllPermissionMultiplierOnlyHigherEnabled ) { - multiplierExtraByPerms += multByPermDouble; - - String msg = String.format( - "%s - Sellall permission multiplier - %s", - dFmt.format(multByPermDouble), multByPerm - ); - results.add(msg); - } - else if (multByPermDouble > multiplierExtraByPerms) { - multiplierExtraByPerms = multByPermDouble; - count++; - greatestPerm = multByPerm; - } - } - - if ( isSellAllPermissionMultiplierOnlyHigherEnabled ) { - - String msg = String.format( - "%s - Sellall permission multiplier - greatest out of %d - %s", - dFmt.format(multiplierExtraByPerms), count, greatestPerm - ); - results.add(msg); - } - - return results; + List results = new ArrayList<>(); + + + if (!isSellAllMultiplierEnabled) { + results.add( "1.0 - Sellall multipler is disabled. Default value." ); + + return results; + } + + DecimalFormat dFmt = Prison.getDecimalFormatStaticDouble(); + + SpigotPlayer sPlayer = new SpigotPlayer(p); + + if ( PrisonRanks.getInstance() != null && PrisonRanks.getInstance().isEnabled() ) { + + RankPlayer rPlayer = sPlayer.getRankPlayer(); + + Set keys = rPlayer.getLadderRanks().keySet(); + for (RankLadder ladderKey : keys) { + PlayerRank pRank = rPlayer.getLadderRanks().get(ladderKey); + String rankName = pRank.getRank().getName(); + + String multiplierRankString = sellAllConfig.getString("Multiplier." + rankName + ".MULTIPLIER"); + if (multiplierRankString != null && sellAllPrestigeMultipliers.containsKey( rankName )){ + double mult = sellAllPrestigeMultipliers.get( rankName ); + String msg = String.format( + "%s - %s rank Sellall multiplier", + dFmt.format(mult), rankName + ); + results.add( msg ); + } + } + } + + if ( results.size() == 0 ) { + String msg = String.format( + "%s - default Sellall multiplier - no rank mulitiplers", + dFmt.format(defaultMultiplier) + ); + results.add(msg); + } + + + // Get Multiplier from multipliers permission's if there's any. + List perms = sPlayer.getPermissions("prison.sellall.multiplier."); + double multiplierExtraByPerms = 0; + int count = 0; + String greatestPerm = ""; + for (String multByPerm : perms) { + + double multByPermDouble = Double.parseDouble(multByPerm.substring(26)); + + if ( !isSellAllPermissionMultiplierOnlyHigherEnabled ) { + multiplierExtraByPerms += multByPermDouble; + + String msg = String.format( + "%s - Sellall permission multiplier - %s", + dFmt.format(multByPermDouble), multByPerm + ); + results.add(msg); + } + else if (multByPermDouble > multiplierExtraByPerms) { + multiplierExtraByPerms = multByPermDouble; + count++; + greatestPerm = multByPerm; + } + } + + if ( isSellAllPermissionMultiplierOnlyHigherEnabled ) { + + String msg = String.format( + "%s - Sellall permission multiplier - greatest out of %d - %s", + dFmt.format(multiplierExtraByPerms), count, greatestPerm + ); + results.add(msg); + } + + return results; } -// /** -// * 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; -// } - -// /** -// * 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 = sPlayer.getSellAllMultiplier(); - - SpigotPlayerInventory spInventory = sPlayer.getSpigotPlayerInventory(); - - List soldItems = valueOfInventoryItems( spInventory, multiplier ); - for (SellAllData soldItem : soldItems) { - value += soldItem.getTransactionAmount(); - } - - return value; + double value = 0; + + double multiplier = sPlayer.getSellAllMultiplier(); + + SpigotPlayerInventory spInventory = sPlayer.getSpigotPlayerInventory(); + + List soldItems = valueOfInventoryItems( spInventory, multiplier ); + for (SellAllData soldItem : soldItems) { + value += soldItem.getTransactionAmount(); + } + + return value; } public String getPlayerInventoryValueReport( SpigotPlayer sPlayer ) { - double multiplier = sPlayer.getSellAllMultiplier(); - - SpigotPlayerInventory spInventory = sPlayer.getSpigotPlayerInventory(); - - List soldItems = valueOfInventoryItems( spInventory, multiplier ); - - String report = SellAllData.itemsSoldReport(soldItems, sPlayer, multiplier); - - return report; + double multiplier = sPlayer.getSellAllMultiplier(); + + SpigotPlayerInventory spInventory = sPlayer.getSpigotPlayerInventory(); + + List soldItems = valueOfInventoryItems( spInventory, multiplier ); + + String report = SellAllData.itemsSoldReport(soldItems, sPlayer, multiplier); + + return report; } public List getPlayerInventoryValueTransactions( SpigotPlayer sPlayer ) { - double multiplier = sPlayer.getSellAllMultiplier(); -// double multiplier = getPlayerMultiplier(sPlayer.getWrapper()); - - SpigotPlayerInventory spInventory = sPlayer.getSpigotPlayerInventory(); - - List soldItems = valueOfInventoryItems( spInventory, multiplier ); - - return soldItems; + double multiplier = sPlayer.getSellAllMultiplier(); + + SpigotPlayerInventory spInventory = sPlayer.getSpigotPlayerInventory(); + + List soldItems = valueOfInventoryItems( spInventory, multiplier ); + + return soldItems; } public double getItemStackValue( SpigotPlayer sPlayer, SpigotItemStack itemStack ) { - double multiplier = sPlayer.getSellAllMultiplier(); - - SellAllData sad = sellItemStack( itemStack, multiplier ); - - return sad == null ? 0 : sad.getTransactionAmount(); + double multiplier = sPlayer.getSellAllMultiplier(); + + SellAllData sad = sellItemStack( itemStack, multiplier ); + + return sad == null ? 0 : sad.getTransactionAmount(); } public String getItemStackValueReport( SpigotPlayer sPlayer, SpigotItemStack itemStack ) { - double multiplier = sPlayer.getSellAllMultiplier(); - - List soldItems = new ArrayList<>(); - - SellAllData sad = sellItemStack( itemStack, multiplier ); - if ( sad != null ) { - - soldItems.add( sad ); - } - - String report = SellAllData.itemsSoldReport(soldItems, sPlayer, multiplier); - - return report; + double multiplier = sPlayer.getSellAllMultiplier(); + + List soldItems = new ArrayList<>(); + + SellAllData sad = sellItemStack( itemStack, multiplier ); + if ( sad != null ) { + + soldItems.add( sad ); + } + + String report = SellAllData.itemsSoldReport(soldItems, sPlayer, multiplier); + + return report; } public List getItemStackValueTransactions( SpigotPlayer sPlayer, SpigotItemStack itemStack ) { - double multiplier = sPlayer.getSellAllMultiplier(); - - List soldItems = new ArrayList<>(); - - SellAllData sad = sellItemStack( itemStack, multiplier ); - if ( sad != null ) { - - soldItems.add( sad ); - } - - return soldItems; + double multiplier = sPlayer.getSellAllMultiplier(); + + List soldItems = new ArrayList<>(); + + SellAllData sad = sellItemStack( itemStack, multiplier ); + if ( sad != null ) { + + soldItems.add( sad ); + } + + return soldItems; } /** @@ -1086,62 +759,62 @@ public List getItemStackValueTransactions( SpigotPlayer sPlayer, Sp */ public List sellPlayerItems(Player p) { - SpigotPlayer sPlayer = new SpigotPlayer( p ); - - double multiplier = sPlayer.getSellAllMultiplier(); - - - // Remove player's off-hand and helmet slots since those don't always sell correctly: - boolean invDirty = false; - ItemStack offHandItemStack = SpigotCompatibility.getInstance().getItemInOffHandStrict( p ); - - if ( offHandItemStack != null ) { - // 1.8 will always be null, so it will never hit this. - ItemStack itemStack = null; - SpigotCompatibility.getInstance().setItemStackInOffHandStrict( p, itemStack ); - - invDirty = true; - } - - ItemStack helmetItemStack = p.getInventory().getHelmet(); - - if ( helmetItemStack != null ) { - p.getInventory().setHelmet( null ); - - invDirty = true; - } - - - - SpigotPlayerInventory spInventory = sPlayer.getSpigotPlayerInventory(); - - - List soldData = sellInventoryItems( spInventory, multiplier ); - - - - // Since the inventory is done being sold, add back the offHand and helmet: - if ( offHandItemStack != null ) { - // 1.8 will always be null, so it will never hit this. - SpigotCompatibility.getInstance().setItemStackInOffHandStrict( p, offHandItemStack ); - } - - if ( helmetItemStack != null ) { - p.getInventory().setHelmet( helmetItemStack ); - } - - if ( invDirty ) { - p.updateInventory(); - } - - - if ( isSellAllBackpackItemsEnabled && BackpacksUtil.getInstance().isEnabled() ) { - BackpacksUtil bpUtil = BackpacksUtil.get(); - - soldData.addAll( bpUtil.sellInventoryItems( p, multiplier ) ); - } - - // Enable sellall for the Minepacks plugin: + SpigotPlayer sPlayer = new SpigotPlayer( p ); + + double multiplier = sPlayer.getSellAllMultiplier(); + + + // Remove player's off-hand and helmet slots since those don't always sell correctly: + boolean invDirty = false; + ItemStack offHandItemStack = SpigotCompatibility.getInstance().getItemInOffHandStrict( p ); + + if ( offHandItemStack != null ) { + // 1.8 will always be null, so it will never hit this. + ItemStack itemStack = null; + SpigotCompatibility.getInstance().setItemStackInOffHandStrict( p, itemStack ); + + invDirty = true; + } + + ItemStack helmetItemStack = p.getInventory().getHelmet(); + + if ( helmetItemStack != null ) { + p.getInventory().setHelmet( null ); + + invDirty = true; + } + + + + SpigotPlayerInventory spInventory = sPlayer.getSpigotPlayerInventory(); + + + List soldData = sellInventoryItems( spInventory, multiplier ); + + + + // Since the inventory is done being sold, add back the offHand and helmet: + if ( offHandItemStack != null ) { + // 1.8 will always be null, so it will never hit this. + SpigotCompatibility.getInstance().setItemStackInOffHandStrict( p, offHandItemStack ); + } + + if ( helmetItemStack != null ) { + p.getInventory().setHelmet( helmetItemStack ); + } + + if ( invDirty ) { + p.updateInventory(); + } + + + if ( isSellAllBackpackItemsEnabled && BackpacksUtil.getInstance().isEnabled() ) { + BackpacksUtil bpUtil = BackpacksUtil.get(); + + soldData.addAll( bpUtil.sellInventoryItems( p, multiplier ) ); + } + + // Enable sellall for the Minepacks plugin: if ( isSellAllMinesBackpacksPluginEnabled && IntegrationMinepacksPlugin.getInstance().isEnabled() ) { soldData.addAll( IntegrationMinepacksPlugin.getInstance().sellInventoryItems( p, multiplier ) ); } @@ -1151,7 +824,7 @@ public List sellPlayerItems(Player p) { soldData.addAll( IntegrationBackpackAPI.getInstance().sellInventoryItems( p, multiplier ) ); } - return soldData; + return soldData; } /** @@ -1171,37 +844,37 @@ public List sellPlayerItems(Player p) { 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 ); - } - } + 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; } @@ -1209,56 +882,56 @@ public List sellPlayerItemStacks(Player p, public List sellInventoryItems( tech.mcprison.prison.internal.inventory.Inventory inventory, double multiplier ) { - List soldItems = new ArrayList<>(); - - if ( inventory != 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 ( tech.mcprison.prison.internal.ItemStack inv : inventory.getItems() ) { - - SellAllData sad = sellItemStack( (SpigotItemStack)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) { - inventory.removeItem( itemStack ); - } - } + List soldItems = new ArrayList<>(); + + if ( inventory != 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 ( tech.mcprison.prison.internal.ItemStack inv : inventory.getItems() ) { + + SellAllData sad = sellItemStack( (SpigotItemStack)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) { + inventory.removeItem( itemStack ); + } + } return soldItems; } private List valueOfInventoryItems( tech.mcprison.prison.internal.inventory.Inventory inventory, double multiplier ) { - List soldItems = new ArrayList<>(); - - 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; + List soldItems = new ArrayList<>(); + + 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; } /** @@ -1275,257 +948,54 @@ private List valueOfInventoryItems( * @return */ private SellAllData sellItemStack( SpigotItemStack iStack, double multiplier ) { - SellAllData soldItem = null; - - if ( iStack != null ) { - - // This converts a bukkit ItemStack to a PrisonBlock, and it also sets up the - // displayName if that is set on the itemStack. - PrisonBlock pBlockInv = iStack.getMaterial(); - - PrisonBlock pBlockSellAll = getSellallItem( pBlockInv ); - - if ( pBlockSellAll != null ) { - - if ( iStack != null && iStack.getEnchantments() != null && iStack.getEnchantments().size() > 0 ) { - // Cannot sell enchanted items: - if ( Output.get().isDebug() ) { - String msg = String.format( - "Sellall: Cannot sell item '%s' (qty %s) because it has enchantments which is not allowed. ", - (iStack.getDisplayName() != null ? iStack.getDisplayName() : iStack.getName() ), - Integer.toString( iStack.getAmount() ) - ); - Output.get().logInfo( msg ); - } - } - - else if ( !pBlockSellAll.isLoreAllowed() && iStack.getLore().size() > 0 ) { - if ( Output.get().isDebug() ) { - String msg = String.format( - "Sellall: Cannot sell item '%s' (qty %s) because it has lore which is not allowed. ", - (iStack.getDisplayName() != null ? iStack.getDisplayName() : iStack.getName() ), - Integer.toString( iStack.getAmount() ) - ); - Output.get().logInfo( msg ); - } - - } - else { - - double amount = iStack.getAmount() * pBlockSellAll.getSalePrice() * multiplier; - soldItem = new SellAllData( pBlockSellAll, iStack.getAmount(), amount ); - } - } - } - - return soldItem; + SellAllData soldItem = null; + + if ( iStack != null ) { + + // This converts a bukkit ItemStack to a PrisonBlock, and it also sets up the + // displayName if that is set on the itemStack. + PrisonBlock pBlockInv = iStack.getMaterial(); + + PrisonBlock pBlockSellAll = getSellallItem( pBlockInv ); + + if ( pBlockSellAll != null ) { + + if ( iStack != null && iStack.getEnchantments() != null && iStack.getEnchantments().size() > 0 ) { + // Cannot sell enchanted items: + if ( Output.get().isDebug() ) { + String msg = String.format( + "Sellall: Cannot sell item '%s' (qty %s) because it has enchantments which is not allowed. ", + (iStack.getDisplayName() != null ? iStack.getDisplayName() : iStack.getName() ), + Integer.toString( iStack.getAmount() ) + ); + Output.get().logInfo( msg ); + } + } + + else if ( !pBlockSellAll.isLoreAllowed() && iStack.getLore().size() > 0 ) { + if ( Output.get().isDebug() ) { + String msg = String.format( + "Sellall: Cannot sell item '%s' (qty %s) because it has lore which is not allowed. ", + (iStack.getDisplayName() != null ? iStack.getDisplayName() : iStack.getName() ), + Integer.toString( iStack.getAmount() ) + ); + Output.get().logInfo( msg ); + } + + } + else { + + double amount = iStack.getAmount() * pBlockSellAll.getSalePrice() * multiplier; + soldItem = new SellAllData( pBlockSellAll, iStack.getAmount(), amount ); + } + } + } + + 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; -// -// // 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 ); -// } -// } -// -// -// 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); -// } -// } -// -// 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; -// } - -// /** -// * 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. -// * -// * @param p - Player. -// * -// * @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; -//// } -// -//// return getBooleanValue("Users." + p.getUniqueId() + ".isEnabled"); -// return results; -// } /** *

    This function only checks to see if the user can toggle autosell @@ -1562,30 +1032,7 @@ public boolean isSellallPlayerUserToggleEnabled( Player p ) { 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 -// * 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. @@ -1624,16 +1071,6 @@ public boolean isValidItem(String item){ return XMaterial.matchXMaterial(item).isPresent(); } -// /** -// * Update SellAll Cached config. -// * */ -// public void updateConfig(){ -// -// initCachedData(); -// -//// sellAllConfig = SpigotPrison.getInstance().updateSellAllConfig(); -// } - /** @@ -1644,9 +1081,8 @@ public boolean isValidItem(String item){ * */ public HashMap initSellAllItems(){ - HashMap sellAllItems = new HashMap<>(); + HashMap sellAllItems = new HashMap<>(); -// HashMap sellAllXMaterials = new HashMap<>(); if (sellAllConfig.getConfigurationSection("Items") == null){ return sellAllItems; @@ -1662,77 +1098,64 @@ public HashMap initSellAllItems(){ PrisonBlock pBlock = Prison.get().getPlatform().getPrisonBlock(itemID); if ( pBlock == null ) { - // create a prison block for this sellall item: - pBlock = new PrisonBlock( key.trim().toLowerCase() ); - - - // Prevent this item from being used within mines: - pBlock.setSellallOnly( true ); - - // Add it: - List newBlockTypes = new ArrayList<>(); - newBlockTypes.add( pBlock ); - Prison.get().getPlatform().getPrisonBlockTypes().addBlockTypes( newBlockTypes ); + // create a prison block for this sellall item: + pBlock = new PrisonBlock( key.trim().toLowerCase() ); + + + // Prevent this item from being used within mines: + pBlock.setSellallOnly( true ); + + // Add it: + List newBlockTypes = new ArrayList<>(); + newBlockTypes.add( pBlock ); + Prison.get().getPlatform().getPrisonBlockTypes().addBlockTypes( newBlockTypes ); } if ( pBlock != null ) { - String itemDisplayName = sellAllConfig.getString( itemPrefix + ".ITEM_DISPLAY_NAME"); - if ( itemDisplayName != null ) { - pBlock.setDisplayName( itemDisplayName ); - } - - String saleValueString = sellAllConfig.getString( itemPrefix + ".ITEM_VALUE"); - if ( saleValueString != null ) { - - try { - double value = Double.parseDouble(saleValueString); - pBlock.setSalePrice( value ); - } catch (NumberFormatException ignored) { - } - } - - String purchaseValueString = sellAllConfig.getString( itemPrefix + ".PURCHASE_PRICE"); - if ( purchaseValueString != null ) { - - try { - double value = Double.parseDouble(purchaseValueString); - pBlock.setPurchasePrice( value ); - } - catch (NumberFormatException ignored) { - } - } - - String isLoreAllowedString = sellAllConfig.getString( itemPrefix + ".IS_LORE_ALLOWED"); - boolean isLoreAllowed = false; - if ( isLoreAllowedString != null ) { - - try { - isLoreAllowed = Boolean.parseBoolean(isLoreAllowedString); - } - catch (NumberFormatException ignored) { - } - } - pBlock.setLoreAllowed( isLoreAllowed ); - - - sellAllItems.put( pBlock.getBlockNameSearch(), pBlock ); + String itemDisplayName = sellAllConfig.getString( itemPrefix + ".ITEM_DISPLAY_NAME"); + if ( itemDisplayName != null ) { + pBlock.setDisplayName( itemDisplayName ); + } + + String saleValueString = sellAllConfig.getString( itemPrefix + ".ITEM_VALUE"); + if ( saleValueString != null ) { + + try { + double value = Double.parseDouble(saleValueString); + pBlock.setSalePrice( value ); + } catch (NumberFormatException ignored) { + } + } + + String purchaseValueString = sellAllConfig.getString( itemPrefix + ".PURCHASE_PRICE"); + if ( purchaseValueString != null ) { + + try { + double value = Double.parseDouble(purchaseValueString); + pBlock.setPurchasePrice( value ); + } + catch (NumberFormatException ignored) { + } + } + + String isLoreAllowedString = sellAllConfig.getString( itemPrefix + ".IS_LORE_ALLOWED"); + boolean isLoreAllowed = false; + if ( isLoreAllowedString != null ) { + + try { + isLoreAllowed = Boolean.parseBoolean(isLoreAllowedString); + } + catch (NumberFormatException ignored) { + } + } + pBlock.setLoreAllowed( isLoreAllowed ); + + + sellAllItems.put( pBlock.getBlockNameSearch(), 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 sellAllItems; } @@ -1784,13 +1207,6 @@ 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"); -// } /** * Add a block to SellAll config. @@ -1803,7 +1219,7 @@ public ArrayList initSellAllItemTrigger(){ * @return boolean. * */ public boolean addSellAllBlock(XMaterial xMaterial, double value) { - return addSellAllBlock( xMaterial.name(), null, value ); + return addSellAllBlock( xMaterial.name(), null, value ); } /** @@ -1819,41 +1235,40 @@ public boolean addSellAllBlock(XMaterial xMaterial, double value) { */ public boolean addSellAllBlock( String itemID, String displayName, double value) { - PrisonBlock pBlockKey = Prison.get().getPlatform().getPrisonBlock( itemID ); - if ( pBlockKey == null ) { - Output.get().logDebug( "sellall add: invalid block name (%s)", itemID); - return false; - } - - // Add the displayName to the block on it can be properly setup in sellall: - if ( displayName != null && displayName.trim().length() > 0 ) { - pBlockKey.setDisplayName( displayName ); - } - - PrisonBlock pBlock = getSellallItem( pBlockKey ); - - // If that is an invalid PrisonBlock, then exit - if ( pBlock != null ) { - Output.get().logDebug( "sellall add: block already exists (%s)", itemID); - return false; - } - - - // pBlock is null, but it's being used below. So clone the key: - pBlock = pBlockKey.clone(); - + PrisonBlock pBlockKey = Prison.get().getPlatform().getPrisonBlock( itemID ); + if ( pBlockKey == null ) { + Output.get().logDebug( "sellall add: invalid block name (%s)", itemID); + return false; + } + + // Add the displayName to the block on it can be properly setup in sellall: + if ( displayName != null && displayName.trim().length() > 0 ) { + pBlockKey.setDisplayName( displayName ); + } + + PrisonBlock pBlock = getSellallItem( pBlockKey ); + + // If that is an invalid PrisonBlock, then exit + if ( pBlock != null ) { + Output.get().logDebug( "sellall add: block already exists (%s)", itemID); + return false; + } + + + // pBlock is null, but it's being used below. So clone the key: + pBlock = pBlockKey.clone(); + try { - File sellAllFile = new File(SpigotPrison.getInstance().getDataFolder() + "/SellAllConfig.yml"); - FileConfiguration conf = YamlConfiguration.loadConfiguration(sellAllFile); - - String itemName = pBlockKey.getBlockNameSearch().toUpperCase(); - String confKey = "Items." + itemName; - -// String itemName = pBlockKey.getBlockName().toUpperCase(); // BUG!! - - conf.set( confKey + ".ITEM_ID", itemID ); - conf.set( confKey + ".ITEM_VALUE", value); + File sellAllFile = new File(SpigotPrison.getInstance().getDataFolder() + "/SellAllConfig.yml"); + FileConfiguration conf = YamlConfiguration.loadConfiguration(sellAllFile); + + String itemName = pBlockKey.getBlockNameSearch().toUpperCase(); + String confKey = "Items." + itemName; + + + conf.set( confKey + ".ITEM_ID", itemID ); + conf.set( confKey + ".ITEM_VALUE", value); conf.set( confKey + ".IS_LORE_ALLOWED", pBlock.isLoreAllowed() ); if ( displayName != null ) { @@ -1869,7 +1284,6 @@ public boolean addSellAllBlock( String itemID, String displayName, double value) pBlockKey.setSalePrice( value ); putSellallItem( pBlockKey ); -// sellAllItems.put( pBlockKey.getBlockNameSearch(), pBlockKey ); } catch (IOException e) { @@ -1879,7 +1293,6 @@ public boolean addSellAllBlock( String itemID, String displayName, double value) } -// sellAllBlocks.put(xMaterial, value); return true; } @@ -1900,109 +1313,83 @@ public boolean addSellAllBlock( String itemID, String displayName, double value) */ public boolean addSellAllBlock( String itemNameSearch, double value, PrisonBlock pBlock ) { - PrisonBlock pBlockKey = getPrisonBlock( itemNameSearch ); - - PrisonBlock pBlockSellall = pBlockKey == null ? null : getSellallItem( pBlockKey ); - - // If that is an invalid PrisonBlock, then exit - if ( pBlockSellall != null ) { - Output.get().logDebug( "sellall add: block already exists (%s)", itemNameSearch ); - return false; - } - - - // pBlock is null, but it's being used below. So clone the key: -// pBlock = pBlockKey.clone(); - - try { - - if ( pBlockSellall == null ) { - - pBlockSellall = pBlock.clone(); - } - -// String itemName = itemNameSearch.toUpperCase(); - String displayName = pBlockSellall.getDisplayName(); - - - File sellAllFile = new File(SpigotPrison.getInstance().getDataFolder() + "/SellAllConfig.yml"); - FileConfiguration conf = YamlConfiguration.loadConfiguration(sellAllFile); - - String itemName = pBlockSellall.getBlockNameSearch().toUpperCase(); - String confKey = "Items." + itemName; - - conf.set(confKey + ".ITEM_ID", pBlockSellall.getBlockNameSearch() ); - conf.set(confKey + ".ITEM_VALUE", value); - conf.set(confKey + ".IS_LORE_ALLOWED", pBlockSellall.isLoreAllowed() ); - - if ( displayName != null ) { - conf.set(confKey + ".ITEM_DISPLAY_NAME", displayName ); - } - - if (getBooleanValue("Options.Sell_Per_Block_Permission_Enabled")) { - conf.set(confKey + ".ITEM_PERMISSION", sellAllConfig.getString("Options.Sell_Per_Block_Permission") + itemNameSearch ); - } - - conf.save(sellAllFile); - refreshClassVariablesFromConfig(); - - pBlockSellall.setSalePrice( value ); - - - // NOTE: If PrisonBlock Key was null, then that means that prison does not have this setup as a - // valid block, so we must create a new prison block and add it. -// PrisonBlock pBlockKey = Prison.get().getPlatform().getPrisonBlock( itemNameSearch ); - if ( pBlockKey == null ) { - List pbList = new ArrayList<>(); - -// pBlockKey = pBlockSellall.clone(); - - pbList.add( pBlockSellall.clone() ); - - Prison.get().getPlatform().getPrisonBlockTypes().addBlockTypes( pbList ); - } - - putSellallItem( pBlockSellall ); -// sellAllItems.put( itemNameSearch, pBlock ); - - } - catch (IOException e) { - - String msg = String.format( - "SellAllUtil.addSellAllBlock: Failed to add a new block to SellAll. " + - "itemSearch: [%s] value: %s PrisonBlock: %s [%s]", - itemNameSearch, Prison.get().getDecimalFormatDouble().format( value ), - pBlock.getBlockNameSearch(), e.getMessage() ); - Output.get().logWarn( msg ); - - return false; - } - - -// sellAllBlocks.put(xMaterial, value); - return true; + PrisonBlock pBlockKey = getPrisonBlock( itemNameSearch ); + + PrisonBlock pBlockSellall = pBlockKey == null ? null : getSellallItem( pBlockKey ); + + // If that is an invalid PrisonBlock, then exit + if ( pBlockSellall != null ) { + Output.get().logDebug( "sellall add: block already exists (%s)", itemNameSearch ); + return false; + } + + + try { + + if ( pBlockSellall == null ) { + + pBlockSellall = pBlock.clone(); + } + + String displayName = pBlockSellall.getDisplayName(); + + + File sellAllFile = new File(SpigotPrison.getInstance().getDataFolder() + "/SellAllConfig.yml"); + FileConfiguration conf = YamlConfiguration.loadConfiguration(sellAllFile); + + String itemName = pBlockSellall.getBlockNameSearch().toUpperCase(); + String confKey = "Items." + itemName; + + conf.set(confKey + ".ITEM_ID", pBlockSellall.getBlockNameSearch() ); + conf.set(confKey + ".ITEM_VALUE", value); + conf.set(confKey + ".IS_LORE_ALLOWED", pBlockSellall.isLoreAllowed() ); + + if ( displayName != null ) { + conf.set(confKey + ".ITEM_DISPLAY_NAME", displayName ); + } + + if (getBooleanValue("Options.Sell_Per_Block_Permission_Enabled")) { + conf.set(confKey + ".ITEM_PERMISSION", sellAllConfig.getString("Options.Sell_Per_Block_Permission") + itemNameSearch ); + } + + conf.save(sellAllFile); + refreshClassVariablesFromConfig(); + + pBlockSellall.setSalePrice( value ); + + + // NOTE: If PrisonBlock Key was null, then that means that prison does not have this setup as a + // valid block, so we must create a new prison block and add it. + if ( pBlockKey == null ) { + List pbList = new ArrayList<>(); + + pbList.add( pBlockSellall.clone() ); + + Prison.get().getPlatform().getPrisonBlockTypes().addBlockTypes( pbList ); + } + + putSellallItem( pBlockSellall ); + + } + catch (IOException e) { + + String msg = String.format( + "SellAllUtil.addSellAllBlock: Failed to add a new block to SellAll. " + + "itemSearch: [%s] value: %s PrisonBlock: %s [%s]", + itemNameSearch, Prison.get().getDecimalFormatDouble().format( value ), + pBlock.getBlockNameSearch(), e.getMessage() ); + Output.get().logWarn( msg ); + + return false; + } + + + return true; } -// /** -// * -// * 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. -// * -// * Add a block to SellAll config. -// * -// * Return True if no error occurred, false if error. -// * -// * @param material - Material of block to add. -// * @param value - Value of the block to add. -// * -// * @return boolean. -// * */ -// public boolean addSellAllBlock(Material material, double value){ -// return addSellAllBlock(XMaterial.matchXMaterial(material), value); -// } public boolean addSellallRankMultiplier(String rankName, double multiplier){ - return addSellallRankMultiplier(rankName, multiplier, false); + return addSellallRankMultiplier(rankName, multiplier, false); } /** @@ -2040,25 +1427,25 @@ public boolean addSellallRankMultiplier(String rankName, double multiplier, bool if ( applyToHigherRanks ) { - Rank nextRank = rank.getRankNext(); - while ( nextRank != null && !getPrestigeMultipliers().containsKey(nextRank.getName()) ) { - - setRankMultiplier(nextRank, multiplier, conf); - nextRank = nextRank.getRankNext(); - } + Rank nextRank = rank.getRankNext(); + while ( nextRank != null && !getPrestigeMultipliers().containsKey(nextRank.getName()) ) { + + setRankMultiplier(nextRank, multiplier, conf); + nextRank = nextRank.getRankNext(); + } } conf.save(sellAllFile); } catch (IOException e) { - String msg = String.format( - "SellAllUtil.addSellAllMultiplier: Failed to add a new rank multiplier to SellAll. " + - "rankName: [%s] multiplier: %s applyToHigherRanks: %s [%s]", - rankName, Prison.get().getDecimalFormatDouble().format( multiplier ), - Boolean.toString( applyToHigherRanks ), - e.getMessage() ); - Output.get().logWarn( msg ); + String msg = String.format( + "SellAllUtil.addSellAllMultiplier: Failed to add a new rank multiplier to SellAll. " + + "rankName: [%s] multiplier: %s applyToHigherRanks: %s [%s]", + rankName, Prison.get().getDecimalFormatDouble().format( multiplier ), + Boolean.toString( applyToHigherRanks ), + e.getMessage() ); + Output.get().logWarn( msg ); return false; } @@ -2109,21 +1496,6 @@ public boolean addItemTrigger(XMaterial xMaterial){ return true; } -// /** -// * BUG: With Spigot versions less than 1.13 bukkit's Material will not work on all Materials since -// * variant data is stored in the ItemStack. SO must use the XMaterial version of this function. -// * -// * Add SellAll Item Trigger. -// * -// * Return true if success, false if error or already added item. -// * -// * @param material - Material to add. -// * -// * @return boolean. -// * */ -// public boolean addItemTrigger(Material material){ -// return addItemTrigger(XMaterial.matchXMaterial(material)); -// } /** * Add Player to active delay. @@ -2178,54 +1550,7 @@ 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()){ -//// 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. @@ -2250,10 +1575,6 @@ public boolean canPlayerSell(Player p, boolean isUsingSign){ return false; } -// if (isPlayerInDisabledWorld(p)){ -// return false; -// } - if (isSellAllSignEnabled && isSellAllBySignOnlyEnabled && !isUsingSign && !p.hasPermission(permissionBypassSign)){ return false; } @@ -2277,226 +1598,130 @@ public boolean canPlayerSell(Player p, boolean isUsingSign){ * @return boolean. * */ public boolean editPrice(XMaterial xMaterial, double value) { - return editPrice( xMaterial, null, value ); + return editPrice( xMaterial, null, value ); } public boolean editPrice(XMaterial xMaterial, String displayName, double value) { - return editPrice( xMaterial.name(), displayName, value ); - -// PrisonBlock pBlockKey = Prison.get().getPlatform().getPrisonBlock( xMaterial.name() ); -// String key = pBlockKey.getBlockNameSearch(); -// -// 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 ( 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); -// -// String itemName = key.toUpperCase(); -// conf.set("Items." + itemName + ".ITEM_ID", key ); -// conf.set("Items." + itemName + ".ITEM_VALUE", value); -// conf.set("Items." + itemName + ".IS_LORE_ALLOWED", pBlock.isLoreAllowed() ); -// -// if ( displayName != null ) { -// conf.set("Items." + itemName + ".ITEM_DISPLAY_NAME", value); -// } -// else { -// //conf.set("Items." + itemName + ".ITEM_DISPLAY_NAME", null); -// } -// -// -// if ( pBlock.getPurchasePrice() != null ) { -// -// conf.set("Items." + itemName + ".PURCHASE_PRICE", pBlock.getPurchasePrice().doubleValue() ); -// } -// -// if (getBooleanValue("Options.Sell_Per_Block_Permission_Enabled")) { -// conf.set("Items." + itemName + ".ITEM_PERMISSION", sellAllConfig.getString("Options.Sell_Per_Block_Permission") + itemName ); -// } -// conf.save(sellAllFile); -// -// // Update only if successful -// refreshClassVariablesFromConfig(); -// } catch (IOException e) { -// e.printStackTrace(); -// return false; -// } -// -// // pBlock is still in the sellAllItems collection so no need to readd it -//// sellAllBlocks.put(xMaterial, value); -// -// return true; + return editPrice( xMaterial.name(), displayName, value ); } public boolean editPrice( String itemID, String displayName, double value) { - PrisonBlock pBlockKey = getPrisonBlock( itemID ); - PrisonBlock pBlock = getSellallItem( pBlockKey ); - -// PrisonBlock pBlockKey = Prison.get().getPlatform().getPrisonBlock( itemID ); -// String key = pBlockKey.getBlockNameSearch(); -// -// 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 ( 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); - - String itemName = pBlockKey.getBlockNameSearch().toUpperCase(); - String confKey = "Items." + itemName; - -// ConfigurationSection confSection = conf.getConfigurationSection( confKey ); - - - conf.set( confKey + ".ITEM_ID", pBlockKey.getBlockNameSearch() ); - conf.set( confKey + ".ITEM_VALUE", value); - conf.set( confKey + ".IS_LORE_ALLOWED", pBlock.isLoreAllowed() ); - - if ( displayName != null && displayName.trim().length() > 0 ) { - conf.set( confKey + ".ITEM_DISPLAY_NAME", displayName.trim() ); - } - else { - //confSection.set("ITEM_DISPLAY_NAME", null); - } - - - if ( pBlock.getPurchasePrice() != null ) { - - conf.set( confKey + ".PURCHASE_PRICE", pBlock.getPurchasePrice().doubleValue() ); - } - - if (getBooleanValue("Options.Sell_Per_Block_Permission_Enabled")) { - conf.set( confKey + ".ITEM_PERMISSION", sellAllConfig.getString("Options.Sell_Per_Block_Permission") + itemName ); - } - conf.save(sellAllFile); - - // Update only if successful - refreshClassVariablesFromConfig(); - } - catch (IOException e) { - - String msg = String.format( - "SellAllUtil.editPrice: Failed to edit an item price. " + - "itemID: [%s] DisplayName: %s&r value: %s [%s]", - itemID, (displayName == null ? "" : displayName ), - Prison.get().getDecimalFormatDouble().format( value ), - e.getMessage() ); - Output.get().logWarn( msg ); - - return false; - } - - // pBlock is still in the sellAllItems collection so no need to readd it -// sellAllBlocks.put(xMaterial, value); - - return true; + PrisonBlock pBlockKey = getPrisonBlock( itemID ); + PrisonBlock pBlock = getSellallItem( pBlockKey ); + + + // Do not allow an edit price if the material does not exist, or if the value has not changed: + 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); + + String itemName = pBlockKey.getBlockNameSearch().toUpperCase(); + String confKey = "Items." + itemName; + + conf.set( confKey + ".ITEM_ID", pBlockKey.getBlockNameSearch() ); + conf.set( confKey + ".ITEM_VALUE", value); + conf.set( confKey + ".IS_LORE_ALLOWED", pBlock.isLoreAllowed() ); + + if ( displayName != null && displayName.trim().length() > 0 ) { + conf.set( confKey + ".ITEM_DISPLAY_NAME", displayName.trim() ); + } + else { + //confSection.set("ITEM_DISPLAY_NAME", null); + } + + + if ( pBlock.getPurchasePrice() != null ) { + + conf.set( confKey + ".PURCHASE_PRICE", pBlock.getPurchasePrice().doubleValue() ); + } + + if (getBooleanValue("Options.Sell_Per_Block_Permission_Enabled")) { + conf.set( confKey + ".ITEM_PERMISSION", sellAllConfig.getString("Options.Sell_Per_Block_Permission") + itemName ); + } + conf.save(sellAllFile); + + // Update only if successful + refreshClassVariablesFromConfig(); + } + catch (IOException e) { + + String msg = String.format( + "SellAllUtil.editPrice: Failed to edit an item price. " + + "itemID: [%s] DisplayName: %s&r value: %s [%s]", + itemID, (displayName == null ? "" : displayName ), + Prison.get().getDecimalFormatDouble().format( value ), + e.getMessage() ); + Output.get().logWarn( msg ); + + return false; + } + + return true; } public boolean editAllowLore( PrisonBlock pBlock, boolean value) { -// public boolean editAllowLore(XMaterial xMaterial, boolean value) { - -// PrisonBlock pBlockKey = Prison.get().getPlatform().getPrisonBlock( xMaterial.name() ); -// String key = pBlockKey.getBlockNameSearch(); - -// PrisonBlock pBlock = sellAllItems.get( key ); - - // Use the block that is stored in sellall: - pBlock = getSellallItem( pBlock ); - - // Do not allow an edit price if the material does not exist, or if the value has not changed: - if ( pBlock == null ) { - - Output.get().logDebug( "sellall edit: item does not exist in shop so it cannot be edited (%s)", pBlock.getBlockNameSearch() ); - return false; - } - if ( pBlock.isLoreAllowed() == value ){ - Output.get().logDebug( "sellall edit: No change in 'allow lore' (%s %s)", - pBlock.getBlockName(), Boolean.toString( pBlock.isLoreAllowed() ) ); - return false; - } - - pBlock.setLoreAllowed( value ); - - try { - File sellAllFile = new File(SpigotPrison.getInstance().getDataFolder() + "/SellAllConfig.yml"); - FileConfiguration conf = YamlConfiguration.loadConfiguration(sellAllFile); - - String itemName = pBlock.getBlockNameSearch().toUpperCase(); -// conf.set("Items." + itemName + ".ITEM_ID", key ); - conf.set("Items." + itemName + ".IS_LORE_ALLOWED", pBlock.isLoreAllowed() ); - - conf.save(sellAllFile); - - // Update only if successful - refreshClassVariablesFromConfig(); - } - catch (IOException e) { - - String msg = String.format( - "SellAllUtil.editAllowLore: Failed to edit the allow lore setting. " + - "itemID: [%s] allow Lore?: %s [%s]", - pBlock.getBlockNameSearch(), - Boolean.toString( value ), - e.getMessage() ); - Output.get().logWarn( msg ); - - return false; - } - - // pBlock is still in the sellAllItems collection so no need to readd it -// sellAllBlocks.put(xMaterial, value); - - return true; + // Use the block that is stored in sellall: + PrisonBlock saBlock = getSellallItem( pBlock ); + + // Do not allow an edit price if the material does not exist, or if the value has not changed: + if ( saBlock == null ) { + + Output.get().logDebug( "sellall edit: item does not exist in shop so it cannot be edited (%s)", pBlock.getBlockNameSearch() ); + return false; + } + if ( saBlock.isLoreAllowed() == value ){ + Output.get().logDebug( "sellall edit: No change in 'allow lore' (%s %s)", + saBlock.getBlockName(), Boolean.toString( saBlock.isLoreAllowed() ) ); + return false; + } + + saBlock.setLoreAllowed( value ); + + try { + File sellAllFile = new File(SpigotPrison.getInstance().getDataFolder() + "/SellAllConfig.yml"); + FileConfiguration conf = YamlConfiguration.loadConfiguration(sellAllFile); + + String itemName = saBlock.getBlockNameSearch().toUpperCase(); + conf.set("Items." + itemName + ".IS_LORE_ALLOWED", saBlock.isLoreAllowed() ); + + conf.save(sellAllFile); + + // Update only if successful + refreshClassVariablesFromConfig(); + } + catch (IOException e) { + + String msg = String.format( + "SellAllUtil.editAllowLore: Failed to edit the allow lore setting. " + + "itemID: [%s] allow Lore?: %s [%s]", + saBlock.getBlockNameSearch(), + Boolean.toString( value ), + e.getMessage() ); + Output.get().logWarn( msg ); + + return false; + } + + return true; } -// /** -// * 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. -// * -// * Edit price of a block using Material. -// * -// * Return true if edited with success, false if error or not found. -// * -// * @param material - Material. -// * @param value - New price as a double. -// * -// * @return boolean, -// * */ -// public boolean editPrice(Material material, double value){ -// return editPrice(XMaterial.matchXMaterial(material), value); -// } /** * Edit Prestige Multiplier value. @@ -2515,10 +1740,6 @@ public boolean editPrestigeMultiplier(String prestigeName, double multiplier) { return addSellallRankMultiplier(prestigeName, multiplier); } -// public boolean removeSellAllBlock(XMaterial xMaterial){ -// -// return removeSellAllBlock( xMaterial.name() ); -// } /** * Remove block by XMaterial name. @@ -2531,12 +1752,7 @@ public boolean editPrestigeMultiplier(String prestigeName, double multiplier) { * */ public boolean removeSellAllBlock( String itemID ) { - PrisonBlock pBlockKey = getSellallItem( getPrisonBlock( itemID )); - -// PrisonBlock pBlockKey = Prison.get().getPlatform().getPrisonBlock( itemID ); -// String key = pBlockKey.getBlockNameSearch(); -// -// PrisonBlock pBlock = sellAllItems.get( key ); + PrisonBlock pBlockKey = getSellallItem( getPrisonBlock( itemID )); if ( pBlockKey == null ){ @@ -2557,25 +1773,9 @@ public boolean removeSellAllBlock( String itemID ) { } getSellAllItems().remove( pBlockKey.getBlockNameSearch() ); -// sellAllBlocks.remove(xMaterial); return true; } -// /** -// * 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. -// * -// * Remove block by XMaterial name. -// * -// * Return true if removed with success, false if not found or error. -// * -// * @param material - XMaterial to remove. -// * -// * @return boolean. -// * */ -// public boolean removeSellAllBlock(Material material){ -// return removeSellAllBlock(XMaterial.matchXMaterial(material)); -// } /** * Remove a Rank Multiplier by name. @@ -2637,270 +1837,7 @@ public boolean removeItemTrigger(XMaterial xMaterial){ return true; } -// /** -// * 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. -// * -// * Delete SellAll Item Trigger. -// * -// * Return true if success, false if error or item not found. -// * -// * @param material - Material to remove. -// * -// * @return boolean. -// * */ -// public boolean removeItemTrigger(Material material){ -// 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 (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; -// } - -// /** -// * 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; -// } - -// /** -// * 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. -// * */ -// 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. @@ -2919,24 +1856,22 @@ public void removeFromDelay(Player p){ public void removeFromAutoSellDelayAndNotify(Player p){ if (autoSellEarningsNotificationWaiting.containsKey(p) && autoSellEarningsNotificationWaiting.get(p) > 0.00){ - DecimalFormat fFmt = Prison.get().getDecimalFormat("#,##0.00"); - String amt = fFmt.format( autoSellEarningsNotificationWaiting.get(p) ); + DecimalFormat fFmt = Prison.get().getDecimalFormat("#,##0.00"); + String amt = fFmt.format( autoSellEarningsNotificationWaiting.get(p) ); + + String message = sellallAmountEarnedMsg( amt ); + + SpigotPlayer sPlayer = new SpigotPlayer(p); + + if ( isSellAllNotificationByActionBar ) { + + sPlayer.setActionBar( message ); + } + else { + + Output.get().send( sPlayer, message ); + } - 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 ); } autoSellEarningsNotificationWaiting.remove(p); } @@ -3001,15 +1936,15 @@ public boolean setAutoSell(Boolean isEnabled){ } catch (IOException e) { - String msg = String.format( - "SellAllUtil.setAutoSell: Failed to set 'Options.Full_Inv_AutoSell' to a value of %s since " + - "there was a problem trying to save the SellAllConfig.yml file. " + - "[%s]", - Boolean.toString( isAutoSellEnabled() ), - e.getMessage() ); - Output.get().logWarn( msg ); - - return false; + String msg = String.format( + "SellAllUtil.setAutoSell: Failed to set 'Options.Full_Inv_AutoSell' to a value of %s since " + + "there was a problem trying to save the SellAllConfig.yml file. " + + "[%s]", + Boolean.toString( isAutoSellEnabled() ), + e.getMessage() ); + Output.get().logWarn( msg ); + + return false; } isAutoSellEnabled = isEnabled; @@ -3046,14 +1981,14 @@ public boolean setAutoSellPlayer(Player p, boolean enable){ } catch (IOException e) { - String msg = String.format( - "SellAllUtil.setAutoSellPlayer: Failed to set user %s autoSell Per Bbock toggle to a value " + - "of %s since there was a problem trying to save the SellAllConfig.yml file. " + - "[%s]", - p.getName(), - Boolean.toString( enable ), - e.getMessage() ); - Output.get().logWarn( msg ); + String msg = String.format( + "SellAllUtil.setAutoSellPlayer: Failed to set user %s autoSell Per Bbock toggle to a value " + + "of %s since there was a problem trying to save the SellAllConfig.yml file. " + + "[%s]", + p.getName(), + Boolean.toString( enable ), + e.getMessage() ); + Output.get().logWarn( msg ); return false; } @@ -3197,44 +2132,45 @@ 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) { - return sellAllSell( p, isUsingSign, completelySilent, - notifyPlayerEarned, notifyPlayerDelay, - notifyPlayerEarningDelay, playSoundOnSellAll, - true, - null ); + boolean isUsingSign, + boolean completelySilent, + boolean notifyPlayerEarned, + boolean notifyPlayerDelay, + boolean notifyPlayerEarningDelay, + boolean playSoundOnSellAll) { + + return sellAllSell( p, isUsingSign, completelySilent, + notifyPlayerEarned, notifyPlayerDelay, + notifyPlayerEarningDelay, playSoundOnSellAll, + true, + null ); } public boolean sellAllSell(Player p, - boolean isUsingSign, - boolean completelySilent, - boolean notifyPlayerEarned, - boolean notifyPlayerDelay, - boolean notifyPlayerEarningDelay, - boolean playSoundOnSellAll, - List amounts ) { - - return sellAllSell( p, isUsingSign, completelySilent, - notifyPlayerEarned, notifyPlayerDelay, - notifyPlayerEarningDelay, playSoundOnSellAll, - true, - amounts ); + boolean isUsingSign, + boolean completelySilent, + boolean notifyPlayerEarned, + 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 ) { + 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) { @@ -3262,8 +2198,8 @@ public boolean sellAllSell(Player p, - double money = 0; - double multiplier = getPlayerMultiplier(p); + double money = 0; + double multiplier = getPlayerMultiplier(p); List soldItems = sellPlayerItems(p); @@ -3297,7 +2233,6 @@ public boolean sellAllSell(Player p, if ( PrisonRanks.getInstance() != null && PrisonRanks.getInstance().isEnabled() ) { RankPlayer rankPlayer = sPlayer.getRankPlayer(); -// RankPlayer rankPlayer = PrisonRanks.getInstance().getPlayerManager().getPlayer(sPlayer.getUUID(), sPlayer.getName()); rankPlayer.addBalance(sellAllCurrency, money); @@ -3379,21 +2314,14 @@ else if (notifyPlayerEarned) { public double sellAllSell(Player p, SpigotItemStack itemStack, boolean completelySilent, boolean notifyPlayerEarned, boolean notifyPlayerEarningDelay){ -// long tPoint1 = System.nanoTime(); -// long tPoint2 = tPoint1; -// long tPoint3 = tPoint1; -// long tPoint4 = tPoint1; -// long tPoint5 = tPoint1; - - - double money = 0; - double multiplier = getPlayerMultiplier(p); + double money = 0; + double multiplier = getPlayerMultiplier(p); List soldItems = new ArrayList<>(); SellAllData sad = sellItemStack( itemStack, multiplier ); if ( sad != null ) { - soldItems.add(sad); + soldItems.add(sad); } for (SellAllData soldItem : soldItems) { @@ -3402,77 +2330,53 @@ public double sellAllSell(Player p, SpigotItemStack itemStack, SellAllData.debugItemsSold(soldItems, new SpigotPlayer(p), multiplier); -// double money = getSellMoney(p, itemStack); - -// tPoint2 = System.nanoTime(); - - if (money != 0) { - - SpigotPlayer sPlayer = new SpigotPlayer(p); - RankPlayer rankPlayer = PrisonRanks.getInstance().getPlayerManager().getPlayer(sPlayer.getUUID(), sPlayer.getName()); - -// tPoint3 = System.nanoTime(); - - if (sellAllCurrency != null && sellAllCurrency.equalsIgnoreCase("default")) { - sellAllCurrency = null; - } - rankPlayer.addBalance(sellAllCurrency, money); - -// tPoint4 = System.nanoTime(); - - if (!completelySilent) { - - if (notifyPlayerEarningDelay // && isAutoSellEarningNotificationDelayEnabled - ){ - - if (!isPlayerWaitingAutoSellNotification(p)){ - // Initialize && Force delayed notifications, even if delayed is disabled: - autoSellEarningsNotificationWaiting.put(p, 0.00); - - Bukkit.getScheduler().scheduleSyncDelayedTask( - SpigotPrison.getInstance(), () -> - removeFromAutoSellDelayAndNotify(p), 20L * defaultAutoSellEarningNotificationDelay); - - } - - addDelayedEarningAutoSellNotification(p, money); - } - else if (notifyPlayerEarned){ - DecimalFormat fFmt = Prison.get().getDecimalFormat("#,##0.00"); - String amt = fFmt.format( money ); - - 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( sPlayer, message ); - - } - } - -// tPoint5 = System.nanoTime(); - } - - -// DecimalFormat dFmt = Prison.get().getDecimalFormat( "0.0000" ); -// String debugMsg = "{sellAllSell::" + dFmt.format( money ) + -// ":t1=" + dFmt.format( (tPoint2 - tPoint1)/1000000d ) + -// ":t2=" + dFmt.format( (tPoint3 - tPoint2)/1000000d ) + -// ":t3=" + dFmt.format( (tPoint4 - tPoint3)/1000000d ) + -// ":t4=" + dFmt.format( (tPoint5 - tPoint4)/1000000d ) + -// "}"; -// Output.get().logDebug( debugMsg ); - - return money; + if (money != 0) { + + SpigotPlayer sPlayer = new SpigotPlayer(p); + RankPlayer rankPlayer = PrisonRanks.getInstance().getPlayerManager().getPlayer(sPlayer.getUUID(), sPlayer.getName()); + + if (sellAllCurrency != null && sellAllCurrency.equalsIgnoreCase("default")) { + sellAllCurrency = null; + } + rankPlayer.addBalance(sellAllCurrency, money); + + if (!completelySilent) { + + if (notifyPlayerEarningDelay // && isAutoSellEarningNotificationDelayEnabled + ){ + + if (!isPlayerWaitingAutoSellNotification(p)){ + // Initialize && Force delayed notifications, even if delayed is disabled: + autoSellEarningsNotificationWaiting.put(p, 0.00); + + Bukkit.getScheduler().scheduleSyncDelayedTask( + SpigotPrison.getInstance(), () -> + removeFromAutoSellDelayAndNotify(p), 20L * defaultAutoSellEarningNotificationDelay); + + } + + addDelayedEarningAutoSellNotification(p, money); + } + else if (notifyPlayerEarned){ + DecimalFormat fFmt = Prison.get().getDecimalFormat("#,##0.00"); + String amt = fFmt.format( money ); + + String message = sellallAmountEarnedMsg( amt ) ; + + if ( isSellAllNotificationByActionBar ) { + sPlayer.setActionBar( message ); + } + else { + + Output.get().send( sPlayer, message ); + } + + } + } + } + + return money; } @@ -3517,7 +2421,6 @@ public ArrayList sellAllSell(Player p, ArrayList itemStack if (!completelySilent) { sellallCanOnlyUseSignsMsg( new SpigotCommandSender(p) ); -// Output.get().sendWarn(new SpigotPlayer(p), messages.getString(MessagesConfig.StringID.spigot_message_sellall_sell_sign_only)); } return itemStacks; } @@ -3526,7 +2429,6 @@ public ArrayList sellAllSell(Player p, ArrayList itemStack if (notifyPlayerDelay && !completelySilent) { sellallRateLimitExceededMsg( new SpigotCommandSender(p) ); -// Output.get().sendWarn(new SpigotPlayer(p), messages.getString(MessagesConfig.StringID.spigot_message_sellall_delay_wait)); } return itemStacks; } @@ -3535,14 +2437,13 @@ public ArrayList sellAllSell(Player p, ArrayList itemStack if (!completelySilent){ sellallShopIsEmptyMsg( new SpigotCommandSender(p) ); -// Output.get().sendWarn(new SpigotPlayer(p), messages.getString(MessagesConfig.StringID.spigot_message_sellall_sell_empty)); } return itemStacks; } - double money = 0; - double multiplier = getPlayerMultiplier(p); + double money = 0; + double multiplier = getPlayerMultiplier(p); List soldItems = new ArrayList<>(); @@ -3550,13 +2451,13 @@ public ArrayList sellAllSell(Player p, ArrayList itemStack for (ItemStack itemStack : itemStacks ) { - SellAllData sad = sellItemStack( new SpigotItemStack( itemStack ), multiplier ); - if ( sad != null ) { - soldItems.add(sad); - } - else { - itemsNotSold.add( itemStack ); - } + SellAllData sad = sellItemStack( new SpigotItemStack( itemStack ), multiplier ); + if ( sad != null ) { + soldItems.add(sad); + } + else { + itemsNotSold.add( itemStack ); + } } // "return" all items not sold: @@ -3566,7 +2467,7 @@ public ArrayList sellAllSell(Player p, ArrayList itemStack // Sell the player's inventory if requested if ( !sellInputArrayListOnly ) { - soldItems.addAll( sellPlayerItems(p) ); + soldItems.addAll( sellPlayerItems(p) ); } for (SellAllData soldItem : soldItems) { @@ -3577,31 +2478,12 @@ public ArrayList sellAllSell(Player p, ArrayList itemStack 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){ SpigotPlayer sPlayer = new SpigotPlayer(p); RankPlayer rankPlayer = PrisonRanks.getInstance().getPlayerManager().getPlayer(sPlayer.getUUID(), sPlayer.getName()); if (sellAllCurrency != null && sellAllCurrency.equalsIgnoreCase("default")) sellAllCurrency = null; -// if (!sellInputArrayListOnly) { -// removeSellableItems(p); -// } rankPlayer.addBalance(sellAllCurrency, money); if (isSellAllDelayEnabled){ @@ -3620,22 +2502,19 @@ public ArrayList sellAllSell(Player p, ArrayList itemStack addDelayedEarningAutoSellNotification(p, money); } } else if (notifyPlayerEarned){ - DecimalFormat fFmt = Prison.get().getDecimalFormat("#,##0.00"); - String amt = fFmt.format( money ); - - String message = sellallAmountEarnedMsg( amt ); - - if ( isSellAllNotificationByActionBar ) { - sPlayer.setActionBar( message ); - } - else { - - Output.get().send( sPlayer, message ); - } + DecimalFormat fFmt = Prison.get().getDecimalFormat("#,##0.00"); + String amt = fFmt.format( money ); + + 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 ); - } } } else { @@ -3645,7 +2524,6 @@ public ArrayList sellAllSell(Player p, ArrayList itemStack } sellallYouHaveNothingToSellMsg( new SpigotCommandSender(p) ); -// Output.get().sendInfo(new SpigotPlayer(p), messages.getString(MessagesConfig.StringID.spigot_message_sellall_sell_nothing_sellable)); } } return itemStacks; @@ -3689,4 +2567,4 @@ public boolean openSellAllGUI( Player p, int page, String cmdPage, String cmdRet gui.open(); return true; } -} \ No newline at end of file +} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/spiget/PrisonSpigetUpdateCheckTask.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/spiget/PrisonSpigetUpdateCheckTask.java index 1a53424bf..5591d2e15 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/spiget/PrisonSpigetUpdateCheckTask.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/spiget/PrisonSpigetUpdateCheckTask.java @@ -29,32 +29,14 @@ public void run() { SpigotPrison plugin = SpigotPrison.getInstance(); - SpigetUpdate updater = new SpigetUpdate( plugin, Prison.SPIGOTMC_ORG_PROJECT_ID); -// SpigetUpdate updater = new SpigetUpdate(this, 1223); - - - BluesSpigetSemVerComparator aRealSemVerComparator = new BluesSpigetSemVerComparator(); - updater.setVersionComparator( aRealSemVerComparator ); -// updater.setVersionComparator(VersionComparator.EQUAL); + SpigetUpdate updater = new SpigetUpdate( plugin, Prison.SPIGOTMC_ORG_PROJECT_ID); + + + BluesSpigetSemVerComparator aRealSemVerComparator = new BluesSpigetSemVerComparator(); + updater.setVersionComparator( aRealSemVerComparator ); - updater.checkForUpdate( new PrisonSpigetUpdateCallback() ); + updater.checkForUpdate( new PrisonSpigetUpdateCallback() ); - -// updater.checkForUpdate(new UpdateCallback() { -// @Override -// public void updateAvailable(String newVersion, String downloadUrl, -// boolean hasDirectDownload) { -// Alerts.getInstance().sendAlert( -// "&3%s is now available. &7Go to the &lSpigot&r&7 page to download the latest release with new features and fixes :)", -// newVersion); -// } -// -// @Override -// public void upToDate() { -// // Plugin is up-to-date -// } -// }); - } public long getDelayTicks() { diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/tasks/PrisonInitialStartupTask.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/tasks/PrisonInitialStartupTask.java index a817a6335..a7dd36f32 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/tasks/PrisonInitialStartupTask.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/tasks/PrisonInitialStartupTask.java @@ -77,22 +77,22 @@ public void run() { if ( firstPass ) { - display.sendtoOutputLogInfo(); - - firstPass = false; - - resubmit(); + display.sendtoOutputLogInfo(); + + firstPass = false; + + resubmit(); } else { - display.addText("Please see the prison startup messages within the console."); - - List onlinePlayers = Prison.get().getPlatform().getOnlinePlayers(); - - for ( Player player : onlinePlayers ) { - - display.send( player ); - } + display.addText("Please see the prison startup messages within the console."); + + List onlinePlayers = Prison.get().getPlatform().getOnlinePlayers(); + + for ( Player player : onlinePlayers ) { + + display.send( player ); + } } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/tasks/SpigotPrisonDelayedStartupTask.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/tasks/SpigotPrisonDelayedStartupTask.java index c1a8604cf..d38bf6f29 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/tasks/SpigotPrisonDelayedStartupTask.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/tasks/SpigotPrisonDelayedStartupTask.java @@ -103,36 +103,36 @@ public boolean isVaultEconomyIntegrated() { public String inspectVaultEconomy() { - String results = null; + String results = null; if ( econName == null && Bukkit.getPluginManager().getPlugin("Vault") != null && Bukkit.getServicesManager().getRegistration(Economy.class) != null ) { - econ = Bukkit.getServicesManager().getRegistration(Economy.class).getProvider(); - - if ( econ != null ) { - econName = econ.getClass().getSimpleName(); - results = econName; - - if ( prison.getConfig().isBoolean( "delayedPrisonStartup.inspect-vault" ) ) { - - String message = String.format( - "Inspect Vault Economy: %s Use '%s' with " + - "'delayedPrisonStartup.triggers-vault-economy-name' ", - econ.isEnabled() ? "enabled" : "disabled", - econ.getClass().getSimpleName() - ); - - Output.get().logInfo( message ); - } - } + econ = Bukkit.getServicesManager().getRegistration(Economy.class).getProvider(); + + if ( econ != null ) { + econName = econ.getClass().getSimpleName(); + results = econName; + + if ( prison.getConfig().isBoolean( "delayedPrisonStartup.inspect-vault" ) ) { + + String message = String.format( + "Inspect Vault Economy: %s Use '%s' with " + + "'delayedPrisonStartup.triggers-vault-economy-name' ", + econ.isEnabled() ? "enabled" : "disabled", + econ.getClass().getSimpleName() + ); + + Output.get().logInfo( message ); + } + } } else if ( econName != null ) { - results = econName; + results = econName; } if ( results == null ) { - Output.get().logInfo( "Inspect Vault Economy: Failed." ); + Output.get().logInfo( "Inspect Vault Economy: Failed." ); } return results; diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/util/SpigotYamlFileIO.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/util/SpigotYamlFileIO.java index aa9bce412..62d4806d5 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/util/SpigotYamlFileIO.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/util/SpigotYamlFileIO.java @@ -43,8 +43,8 @@ protected boolean loadYaml() { } try { - yamlConfig.load(getYamlFile()); - results = true; + yamlConfig.load(getYamlFile()); + results = true; } catch (IOException | InvalidConfigurationException e) { e.printStackTrace(); } @@ -93,60 +93,8 @@ protected void createSection( String key ) { } -// @Override -// protected boolean getBoolean( String key ) { -// return yamlConfig.getBoolean( key ) ; -// } -// @Override -// protected boolean getBoolean( String key, boolean defaultValue ) { -// return yamlConfig.getBoolean( key, defaultValue ) ; -// } -// -// @Override -// protected String getString( String key ) { -// return yamlConfig.getString( key ) ; -// } -// @Override -// protected String getString( String key, String defaultValue ) { -// return yamlConfig.getString( key, defaultValue ) ; -// } -// -// @Override -// protected double getDouble( String key ) { -// return yamlConfig.getDouble( key ) ; -// } -// @Override -// protected double getDouble( String key, double defaultValue ) { -// return yamlConfig.getDouble( key, defaultValue ) ; -// } -// -// @Override -// protected int getInteger( String key ) { -// return yamlConfig.getInt( key ) ; -// } -// @Override -// protected int getInteger( String key, int defaultValue ) { -// return yamlConfig.getInt( key, defaultValue ) ; -// } -// -// @Override -// protected long getLong( String key ) { -// return yamlConfig.getLong( key ) ; -// } -// @Override -// protected long getLong( String key, long defaultValue ) { -// return yamlConfig.getLong( key, defaultValue ) ; -// } - - public void test( ) { -// yamlConfig. ; - - } - - - } 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 9933dbd44..4ce3344e4 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 @@ -22,7 +22,6 @@ import tech.mcprison.prison.bombs.MineBombCooldownException; import tech.mcprison.prison.bombs.MineBombData; import tech.mcprison.prison.bombs.MineBombs; -import tech.mcprison.prison.bombs.MineBombs.AnimationArmorStandItemLocation; import tech.mcprison.prison.mines.data.Mine; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.spigot.SpigotPrison; @@ -79,57 +78,50 @@ public void mineBombPlacementEvent( BlockPlaceEvent event ) { if ( iStack != null && iStack.getType() != Material.AIR ) { - String bombName = checkMineBombItemStack( iStack ); - - if ( bombName != null ) { - - Player player = event.getPlayer(); - SpigotPlayer sPlayer = new SpigotPlayer( player ); - - MineBombData mineBomb = null; - - try { - // Placing minebombs: Use cooldowns: - mineBomb = MineBombs.getInstance().findBombByName( sPlayer, bombName); - } - catch (MineBombCooldownException e) { - String msg = e.getLocalizedMessage(); - - sPlayer.sendMessage(msg); - - return; - } - -// MineBombData mineBomb = MineBombs.getInstance().findBombByName( sPlayer, bombName ); - - String thrower = player.getUniqueId().toString(); - String owner = PrisonNBTUtil.getNBTString(iStack, MineBombs.MINE_BOMBS_NBT_OWNER_UUID); - - PrisonNBTUtil.setNBTString(iStack, - MineBombs.MINE_BOMBS_NBT_KEY, - bombName ); - PrisonNBTUtil.setNBTString(iStack, - MineBombs.MINE_BOMBS_NBT_THROWER_UUID, - thrower ); - - Block targetBlock = event.getBlockAgainst(); - -// SpigotBlock lsBlock = sPlayer.getLineOfSightBlock(); - -// Output.get().logInfo( -// "### Place mine bomb: mineBombPlacementEvent: block: %s sight: %s", -// targetBlock.getLocation().toString(), -// lsBlock.getLocation().toString() ); - - EquipmentSlot hand = SpigotCompatibility.getInstance().getHand(event); - - boolean canceled = processBombTriggerEvent( player, mineBomb, - targetBlock, hand, thrower, owner ); - - if ( canceled ) { - event.setCancelled( canceled ); - } - } + String bombName = checkMineBombItemStack( iStack ); + + if ( bombName != null ) { + + Player player = event.getPlayer(); + SpigotPlayer sPlayer = new SpigotPlayer( player ); + + MineBombData mineBomb = null; + + try { + // Placing minebombs: Use cooldowns: + mineBomb = MineBombs.getInstance().findBombByName( sPlayer, bombName); + } + catch (MineBombCooldownException e) { + String msg = e.getLocalizedMessage(); + + sPlayer.sendMessage(msg); + + return; + } + + + String thrower = player.getUniqueId().toString(); + String owner = PrisonNBTUtil.getNBTString(iStack, MineBombs.MINE_BOMBS_NBT_OWNER_UUID); + + PrisonNBTUtil.setNBTString(iStack, + MineBombs.MINE_BOMBS_NBT_KEY, + bombName ); + PrisonNBTUtil.setNBTString(iStack, + MineBombs.MINE_BOMBS_NBT_THROWER_UUID, + thrower ); + + Block targetBlock = event.getBlockAgainst(); + + + EquipmentSlot hand = SpigotCompatibility.getInstance().getHand(event); + + boolean canceled = processBombTriggerEvent( player, mineBomb, + targetBlock, hand, thrower, owner ); + + if ( canceled ) { + event.setCancelled( canceled ); + } + } } @@ -157,210 +149,210 @@ public void mineBombThrowEvent( PlayerInteractEvent event ) { String bombName = checkMineBombItemStack( iStack ); - if ( bombName != null ) { - - // We do not know if the bomb will be in a mine, but we know - // it's a mine bomb so no other listener should handle it. - event.setCancelled( true ); - - Player player = event.getPlayer(); - SpigotPlayer sPlayer = new SpigotPlayer( player ); - - // If the player is on a mine bomb cooldown, then mineBomb will be null: - - final MineBombData mineBomb; - - try { - // Throw minebombs: Use cooldowns: - mineBomb = MineBombs.getInstance().findBombByName( sPlayer, bombName); - } - catch (MineBombCooldownException e) { - String msg = e.getLocalizedMessage(); - - sPlayer.sendMessage(msg); - - return; - } - -// MineBombData mineBomb = MineBombs.getInstance().findBombByName( sPlayer, bombName ); - - if ( mineBomb != null ) { - - EquipmentSlot hand = SpigotCompatibility.getInstance().getHand(event); - - - - final String thrower = sPlayer.getName(); -// final String thrower = PrisonNBTUtil.getNBTString( iStack, MineBombs.MINE_BOMBS_NBT_THROWER_UUID ); - - final String owner = PrisonNBTUtil.getNBTString( iStack, MineBombs.MINE_BOMBS_NBT_OWNER_UUID); - - - - - PrisonNBTUtil.setNBTString(iStack, - MineBombs.MINE_BOMBS_NBT_KEY, - bombName ); - PrisonNBTUtil.setNBTString(iStack, - MineBombs.MINE_BOMBS_NBT_THROWER_UUID, - thrower ); - - SpigotLocation loc = new SpigotLocation( - player.getEyeLocation().add( player.getLocation().getDirection() )); - - - ArmorStand armorStand = player.getWorld().spawn( - loc.getBukkitLocation(), - ArmorStand.class); - - armorStand.setVisible( false ); - armorStand.setItemInHand( iStack ); - - - SpigotArmorStand sArmorStand = new SpigotArmorStand(armorStand); - - sArmorStand.setNbtString( MineBombs.MINE_BOMBS_NBT_KEY, bombName ); - sArmorStand.setNbtString( MineBombs.MINE_BOMBS_NBT_THROWER_UUID, thrower ); - sArmorStand.setNbtString( MineBombs.MINE_BOMBS_NBT_OWNER_UUID, owner ); - - - if ( Output.get().isDebug() ) { - String nbtJson = Text.translateAmpColorCodes( - PrisonNBTUtil.getNBTData( - sArmorStand.getBukkitEntity() )); - Output.get().logInfo( "PrisonBombListener.mineBombThrowEvent ntb: %s", - nbtJson ); - } - - - Vector velocity = player.getLocation().getDirection().multiply( - mineBomb.getThrowVelocity() ); - - armorStand.setVelocity( velocity ); - - armorStand.setRemoveWhenFarAway(false); - - - - - // Remove the unused armorStand in 120 seconds: - final int taskId = SpigotPrison.getInstance().getScheduler() - .runTaskLater( - new Runnable() { - public void run() { - armorStand.remove(); - } - }, 120 * 20); - - - // Run the following every tick to detect when the armor stand has - // come to rest for 4 ticks, then trigger the animation. - final SpigotArmorStand aStnd = sArmorStand; - - - // Save the taskId so this task can be canceled: - mineBomb.setTaskId( - SpigotPrison.getInstance().getScheduler() - .runTaskTimer( - new Runnable() { - private List locs = new ArrayList<>(); - private int checks = 0; - - /** - *

    Remove the bomb. - *

    - */ - private void removeBomb() { - - // Cancel this task: - SpigotPrison.getInstance().getScheduler().cancelTask( mineBomb.getTask() ); - - // Cancel the cancellation task: - SpigotPrison.getInstance().getScheduler().cancelTask(taskId); - - - // remove armor stand: - aStnd.remove(); - } - - public void run() { - Location loc = aStnd.getLocation(); - locs.add(loc); - - // Only keep no more than 4 locations in the list. Purge the oldest. - if ( locs.size() > 4 ) { - locs.remove(0); - } - -// String msg = String.format( -// "### MineBomb: tracking minebomb movements. count=%s locs=%s current: %s", -// Integer.toString(checks++), -// Integer.toString(locs.size()), -// loc.toWorldCoordinates() ); -// Output.get().logInfo( msg ); - - // If mine bomb does not land it may have fallen in the void.. so remove it: - if ( checks > 100 ) { - removeBomb(); - } - - if ( locs.size() == 4 ) { - - // When there are four locations, then check to ensure the mine - // bomb is no longer moving... - if ( locs.get(0).equals(locs.get(1)) && - locs.get(1).equals(locs.get(2)) && - locs.get(2).equals(locs.get(3)) - ) { - - // Set the mine bomb's location where the item has landed: - mineBomb.setPlacedBombLocation( loc ); - - removeBomb(); - -// // Cancel this task: -// SpigotPrison.getInstance().getScheduler().cancelTask( mineBomb.getTask() ); -// -// // Cancel the cancellation task: -// SpigotPrison.getInstance().getScheduler().cancelTask(taskId); -// -// -// // remove armor stand: -// aStnd.remove(); - - // Start mine bomb animation: -// loc.setY( loc.getY() ); - SpigotBlock targetBlock = (SpigotBlock) loc.getBlockAt(); - - Mine mine = getMine(sPlayer, mineBomb, targetBlock ); - - if ( mine != null ) { - // It landed within a mine... subtract one from the player's inventory, - // if it's used up, then remove from the inventory: -// iStack.setAmount( iStack.getAmount() - 1); -// if ( iStack.getAmount() == 0 ) { -// player.getInventory().removeItem( iStack ); -// } - - processBombTriggerEvent( sPlayer, mine, mineBomb, targetBlock, - hand, thrower, owner ); - } - - } - } - } - - }, 2, 1)); - } - else { - int cooldownTicks = MineBombs.checkPlayerCooldown(sPlayer); - - getPrisonUtilsMineBombs().mineBombsCoolDownMsg( sPlayer, cooldownTicks ); - } - - - - + if ( bombName != null ) { + + // We do not know if the bomb will be in a mine, but we know + // it's a mine bomb so no other listener should handle it. + event.setCancelled( true ); + + Player player = event.getPlayer(); + SpigotPlayer sPlayer = new SpigotPlayer( player ); + + // If the player is on a mine bomb cooldown, then mineBomb will be null: + + final MineBombData mineBomb; + + try { + // Throw minebombs: Use cooldowns: + mineBomb = MineBombs.getInstance().findBombByName( sPlayer, bombName); + } + catch (MineBombCooldownException e) { + String msg = e.getLocalizedMessage(); + + sPlayer.sendMessage(msg); + + return; + } + + + if ( mineBomb != null ) { + + EquipmentSlot hand = SpigotCompatibility.getInstance().getHand(event); + + + + final String thrower = sPlayer.getName(); + + // final String thrower = PrisonNBTUtil.getNBTString( iStack, MineBombs.MINE_BOMBS_NBT_THROWER_UUID ); + + final String owner = PrisonNBTUtil.getNBTString( iStack, MineBombs.MINE_BOMBS_NBT_OWNER_UUID); + + + + + PrisonNBTUtil.setNBTString(iStack, + MineBombs.MINE_BOMBS_NBT_KEY, + bombName ); + PrisonNBTUtil.setNBTString(iStack, + MineBombs.MINE_BOMBS_NBT_THROWER_UUID, + thrower ); + + SpigotLocation loc = new SpigotLocation( + player.getEyeLocation().add( player.getLocation().getDirection() )); + + + ArmorStand armorStand = player.getWorld().spawn( + loc.getBukkitLocation(), + ArmorStand.class); + + armorStand.setVisible( false ); + armorStand.setItemInHand( iStack ); + + + SpigotArmorStand sArmorStand = new SpigotArmorStand(armorStand); + + sArmorStand.setNbtString( MineBombs.MINE_BOMBS_NBT_KEY, bombName ); + sArmorStand.setNbtString( MineBombs.MINE_BOMBS_NBT_THROWER_UUID, thrower ); + sArmorStand.setNbtString( MineBombs.MINE_BOMBS_NBT_OWNER_UUID, owner ); + + + if ( Output.get().isDebug() ) { + String nbtJson = Text.translateAmpColorCodes( + PrisonNBTUtil.getNBTData( + sArmorStand.getBukkitEntity() )); + Output.get().logInfo( "PrisonBombListener.mineBombThrowEvent ntb: %s", + nbtJson ); + } + + + Vector velocity = player.getLocation().getDirection().multiply( + mineBomb.getThrowVelocity() ); + + armorStand.setVelocity( velocity ); + + armorStand.setRemoveWhenFarAway(false); + + + + + // Remove the unused armorStand in 120 seconds: + final int taskId = SpigotPrison.getInstance().getScheduler() + .runTaskLater( + new Runnable() { + public void run() { + armorStand.remove(); + } + }, 120 * 20); + + + // Run the following every tick to detect when the armor stand has + // come to rest for 4 ticks, then trigger the animation. + final SpigotArmorStand aStnd = sArmorStand; + + + // Save the taskId so this task can be canceled: + mineBomb.setTaskId( + SpigotPrison.getInstance().getScheduler() + .runTaskTimer( + new Runnable() { + private List locs = new ArrayList<>(); + private int checks = 0; + + /** + *

    Remove the bomb. + *

    + */ + private void removeBomb() { + + // Cancel this task: + SpigotPrison.getInstance().getScheduler().cancelTask( mineBomb.getTask() ); + + // Cancel the cancellation task: + SpigotPrison.getInstance().getScheduler().cancelTask(taskId); + + + // remove armor stand: + aStnd.remove(); + } + + public void run() { + Location loc = aStnd.getLocation(); + locs.add(loc); + + // Only keep no more than 4 locations in the list. Purge the oldest. + if ( locs.size() > 4 ) { + locs.remove(0); + } + + // String msg = String.format( + // "### MineBomb: tracking minebomb movements. count=%s locs=%s current: %s", + // Integer.toString(checks++), + // Integer.toString(locs.size()), + // loc.toWorldCoordinates() ); + // Output.get().logInfo( msg ); + + // If mine bomb does not land it may have fallen in the void.. so remove it: + if ( checks > 100 ) { + removeBomb(); + } + + if ( locs.size() == 4 ) { + + // When there are four locations, then check to ensure the mine + // bomb is no longer moving... + if ( locs.get(0).equals(locs.get(1)) && + locs.get(1).equals(locs.get(2)) && + locs.get(2).equals(locs.get(3)) + ) { + + // Set the mine bomb's location where the item has landed: + mineBomb.setPlacedBombLocation( loc ); + + removeBomb(); + + // // Cancel this task: + // SpigotPrison.getInstance().getScheduler().cancelTask( mineBomb.getTask() ); + // + // // Cancel the cancellation task: + // SpigotPrison.getInstance().getScheduler().cancelTask(taskId); + // + // + // // remove armor stand: + // aStnd.remove(); + + // Start mine bomb animation: + // loc.setY( loc.getY() ); + SpigotBlock targetBlock = (SpigotBlock) loc.getBlockAt(); + + Mine mine = getMine(sPlayer, mineBomb, targetBlock ); + + if ( mine != null ) { + // It landed within a mine... subtract one from the player's inventory, + // if it's used up, then remove from the inventory: + // iStack.setAmount( iStack.getAmount() - 1); + // if ( iStack.getAmount() == 0 ) { + // player.getInventory().removeItem( iStack ); + // } + + processBombTriggerEvent( sPlayer, mine, mineBomb, targetBlock, + hand, thrower, owner ); + } + + } + } + } + + }, 2, 1)); + } + else { + int cooldownTicks = MineBombs.checkPlayerCooldown(sPlayer); + + getPrisonUtilsMineBombs().mineBombsCoolDownMsg( sPlayer, cooldownTicks ); + } + + + + // player.launchProjectile( armorStand, velocity ); @@ -385,7 +377,7 @@ public void run() { //iStack.setAmount(iStack.getAmount()-1); - } + } } } @@ -400,9 +392,6 @@ public void run() { */ @EventHandler( priority = EventPriority.LOW ) public void bombPlacementEvent( PlayerInteractEvent event ) { -// if ( !event.getPlayer().hasPermission("prison.minebombs.use") ) { -// return; -// } //Output.get().logInfo( "### PrisonBombListener: PlayerInteractEvent 01 " ); @@ -566,8 +555,6 @@ private boolean processBombTriggerEvent( Player player, SpigotBlock sBlock = null; -// SpigotPlayer sPlayer = new SpigotPlayer( player ); - // If clicking AIR, then event.getClickedBlock() will be null... // so if null, then use the player's location for placing the bomb. if ( targetBlock == null ) { @@ -680,7 +667,6 @@ else if ( !mine.hasMiningAccess( sPlayer ) ) { mine.getTag() ); sPlayer.setActionBar( msg ); -// sPlayer.sendMessage( msg ); mine = null; } @@ -700,18 +686,11 @@ public void onBlockPlace( PlayerDropItemEvent event ) { // event.getItemDrop().getMetadata( "prisonMineBomb" ); -// event.getItemDrop(). - - event.setCancelled( false ); + event.setCancelled( false ); } } -// @EventHandler( priority = EventPriority.HIGHEST, ignoreCancelled = false ) -// public void onBlockPlace2( PlayerInteractEvent event ) { -// -// Output.get().logInfo( "### PrisonBombListener: PlayerInteractEvent - oof" ); -// } //// @EventHandler( priority = EventPriority.HIGHEST, ignoreCancelled = false ) // public void onBlockPlace3( BlockPlaceEvent event ) { @@ -746,13 +725,6 @@ public void onBlockPlace( PlayerDropItemEvent event ) { // } // } -//// @EventHandler( priority = EventPriority.HIGHEST, ignoreCancelled = false ) -// public void onBlockPlace3( PlayerInteractEvent event ) { -// -// Output.get().logInfo( "### PrisonBombListener: PlayerInteractEvent " ); -// -// -// } public PrisonUtilsMineBombs getPrisonUtilsMineBombs() { return prisonUtilsMineBombs; @@ -761,28 +733,4 @@ public void setPrisonUtilsMineBombs( PrisonUtilsMineBombs prisonUtilsMineBombs ) this.prisonUtilsMineBombs = prisonUtilsMineBombs; } -// @EventHandler( priority = EventPriority.HIGHEST, ignoreCancelled = false ) -// public void onBlockPlace3( BlockDropItemEvent event ) { -// -// Output.get().logInfo( "### PrisonBombListener: PlayerInteractEvent " ); -// -// -// } - -// @EventHandler( priority = EventPriority.HIGHEST ) -// public void onBlockPlace2( Player event ) { -// -// -// if ( event.isCancelled() && event.getItemDrop().hasMetadata( "prisonMineBomb" ) ) { -// -//// event.getItemDrop().getMetadata( "prisonMineBomb" ); -// -//// event.getItemDrop(). -// -// event.setCancelled( false ); -// } -// -// } - - } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtils.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtils.java index 7b08ac753..769a75e6f 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtils.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtils.java @@ -5,10 +5,8 @@ import tech.mcprison.prison.Prison; import tech.mcprison.prison.internal.CommandSender; import tech.mcprison.prison.internal.Player; -import tech.mcprison.prison.output.Output; import tech.mcprison.prison.ranks.data.RankPlayer; import tech.mcprison.prison.spigot.game.SpigotPlayer; -import tech.mcprison.prison.spigot.game.SpigotPlayerException; public abstract class PrisonUtils implements PrisonUtilsInterface { @@ -49,11 +47,11 @@ private void pluginInitialize() { setPluginRegistered( Bukkit.getPluginManager().isPluginEnabled( getPluginName() ) ); - setPluginVersion( isPluginRegistered() ? - Bukkit.getPluginManager().getPlugin( getPluginName() ) - .getDescription().getVersion() : null ); - - this.enabled = initialize(); + setPluginVersion( isPluginRegistered() ? + Bukkit.getPluginManager().getPlugin( getPluginName() ) + .getDescription().getVersion() : null ); + + this.enabled = initialize(); } @Override @@ -72,10 +70,6 @@ public boolean isEnabled() { */ abstract protected Boolean initialize(); -// protected SpigotPlayer checkPlayerPerms( CommandSender sender, String playerName, -// String permsSelf, String permsOthers ) { -// return checkPlayerPerms(sender, playerName, permsSelf, permsOthers, false ); -// } /** *

    This function checks the perms of the player. If the CommandSender has no @@ -100,49 +94,49 @@ protected SpigotPlayer checkPlayerPerms( CommandSender sender, String playerName boolean isConsole = !(sender instanceof org.bukkit.entity.Player); - SpigotPlayer player = getSpigotPlayer( playerName ); - - // Player's name was not found then it's either being ran from console, or on self. - if ( player == null ) { - - // Ran from console, so if player is null, then playerName was either not - // specified or was invalid: - if ( isConsole ) { - sender.sendMessage( String.format( - "&3PlayerName is incorrect or they are not online. [&7%s&3]", - (playerName == null ? "null" : playerName) )); - } - else if ( !sender.isOp() && !sender.hasPermission( permsSelf ) ) { - sender.sendMessage( String.format( - "&3You do not have the permission to use on another player. [&7%s&3]", - (playerName == null ? "null" : playerName) )); - - } - else { - - // sender is able to use the command on their self: - player = new SpigotPlayer( (org.bukkit.entity.Player) sender); - } - - } - else { - - // The provided playerName was valid. - - // Need to confirm the sender is either console, OP, or has perms to - // use command on someone else, if none of these apply, then reject - // the request to run the command. - if ( !isConsole && !sender.isOp() && !sender.hasPermission( permsOthers ) ) { - sender.sendMessage( String.format( - "&3You do not have the permission to use on another player. [%s]", - (playerName == null ? "null" : playerName) )); - - // Set player to null to indicate authentication failed: - player = null; - } - } - - return player; + SpigotPlayer player = getSpigotPlayer( playerName ); + + // Player's name was not found then it's either being ran from console, or on self. + if ( player == null ) { + + // Ran from console, so if player is null, then playerName was either not + // specified or was invalid: + if ( isConsole ) { + sender.sendMessage( String.format( + "&3PlayerName is incorrect or they are not online. [&7%s&3]", + (playerName == null ? "null" : playerName) )); + } + else if ( !sender.isOp() && !sender.hasPermission( permsSelf ) ) { + sender.sendMessage( String.format( + "&3You do not have the permission to use on another player. [&7%s&3]", + (playerName == null ? "null" : playerName) )); + + } + else { + + // sender is able to use the command on their self: + player = new SpigotPlayer( (org.bukkit.entity.Player) sender); + } + + } + else { + + // The provided playerName was valid. + + // Need to confirm the sender is either console, OP, or has perms to + // use command on someone else, if none of these apply, then reject + // the request to run the command. + if ( !isConsole && !sender.isOp() && !sender.hasPermission( permsOthers ) ) { + sender.sendMessage( String.format( + "&3You do not have the permission to use on another player. [%s]", + (playerName == null ? "null" : playerName) )); + + // Set player to null to indicate authentication failed: + player = null; + } + } + + return player; } @@ -163,10 +157,6 @@ protected SpigotPlayer getSpigotPlayer( String playerName ) { RankPlayer rPlayer = Prison.get().getPlatform().getRankPlayer( null, playerName ); -// // First try to get the bukkit online player: -// if ( rPlayer != null ) { -// org.bukkit.entity.Player playerBukkit = Bukkit.getPlayer( rPlayer.getUUID() ); -// } if ( rPlayer == null ) { @@ -186,66 +176,14 @@ protected SpigotPlayer getSpigotPlayer( String playerName ) { rPlayer = rp; } - - } if ( rPlayer != null ) { result = SpigotPlayer.getSpigotPlayer( rPlayer ); -// try { -// } -// catch (SpigotPlayerException e) { -// -//// String msg = String.format( -//// "SpigotPlayer: Could not get a bukkit player object for '%s'. " -//// + "Is their name spelled correctly? " -//// + "Have they been removed or banned from spigot?", -//// playerName -//// ); -// -// Output.get().logInfo( e.getMessage() ); -// -// } - -// Player player = Prison.get().getPlatform().getPlayer( rPlayer.getUUID() ).orElse(null); -// -// if ( player != null ) { -// result = (SpigotPlayer) player; -// } -// else if ( useOfflinePlayer ) { -// -// -//// Player offLinePlayer = Prison.get().getPlatform().getOfflinePlayer( rPlayer.getUUID() ).orElse( null ); -//// -//// if ( offLinePlayer != null ) { -//// -//// SpigotOfflinePlayer offlinePlayer = (SpigotOfflinePlayer) offLinePlayer; -//// -//// result = new SpigotPlayer( offlinePlayer.getWrapper().getPlayer() ); -// } -// } } -// if ( playerName != null ) { -// Optional opt = Prison.get().getPlatform().getPlayer( playerName ); -// -// if ( opt.isPresent() ) { -// result = (SpigotPlayer) opt.get(); -// } -// else if ( useOfflinePlayer ) { -// Optional optOLP = Prison.get().getPlatform().getOfflinePlayer( playerName ); -// -// if ( optOLP.isPresent() ) { -// -// SpigotOfflinePlayer offlinePlayer = (SpigotOfflinePlayer) optOLP.get(); -// -// result = new SpigotPlayer( offlinePlayer.getWrapper().getPlayer() ); -// } -// } -// -// } return result; } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsHealing.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsHealing.java index 7cee5351e..7cc0f5011 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsHealing.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsHealing.java @@ -52,9 +52,10 @@ public void utilHealingHeal(CommandSender sender, "'-' then that is what the player's health will be set to.") String amount ){ - if( !enableHealingHeal ){ + if ( !enableHealingHeal ) { Output.get().logInfo("Prison's utils command heal is disabled in modules.yml."); - } else { + } + else { SpigotPlayer player = checkPlayerPerms( sender, playerName, "prison.utils.healing.heal", "prison.utils.healing.heal.others" ); @@ -82,9 +83,10 @@ public void utilHealingFeed(CommandSender sender, "'-' then that is what the player's hunger will be set to." ) String amount ){ - if( !enableHealingFeed ){ + if ( !enableHealingFeed ) { Output.get().logInfo("Prison's utils command feed is disabled in modules.yml."); - } else { + } + else { SpigotPlayer player = checkPlayerPerms( sender, playerName, "prison.utils.healing.feed", "prison.utils.healing.feed.others" ); @@ -111,9 +113,10 @@ public void utilHealingBreath(CommandSender sender, "'-' then that is what the player's hunger will be set to.") String amount ){ - if( !enableHealingBreath ){ + if ( !enableHealingBreath ) { Output.get().logInfo("Prison's utils command breath is disabled in modules.yml."); - } else { + } + else { SpigotPlayer player = checkPlayerPerms( sender, playerName, "prison.utils.healing.breath", "prison.utils.healing.breath.others" ); @@ -123,7 +126,7 @@ public void utilHealingBreath(CommandSender sender, } private void utilHealingHeal( SpigotPlayer player, String amount ) { - if(player == null){ + if (player == null) { return; } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsListeners.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsListeners.java index 9b70cdf6b..b4e4286e0 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsListeners.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsListeners.java @@ -11,8 +11,6 @@ public class PrisonUtilsListeners implements Listener { -// private HashMap unbreakableBlockList; - public PrisonUtilsListeners() { super(); @@ -20,26 +18,8 @@ public PrisonUtilsListeners() { // Force it to be setup and ready: BlockUtils.getInstance(); -// this.unbreakableBlockList = new HashMap<>(); } - // Runtime exception for some reasons here. -// @EventHandler( priority=EventPriority.LOWEST ) -// public void rainbowDecayBlockEvent(PrisonMinesBlockEventEvent e) { - -// if ( !e.isCancelled() && e.getParameter() != null && -// e.getParameter().startsWith("rainbow-decay" ) ) { -// -// PrisonUtilsRainbowDecay rainbow = new PrisonUtilsRainbowDecay( -// e, getUnbreakableBlockList()); -// -// PrisonUtilsTask runableTask = new PrisonUtilsTask( rainbow.getTasks() ); -// -// // submit: -// runableTask.submit(); -// } - -// } /** *

    This event prevents any block that is within the unbreakableBlockList @@ -52,18 +32,13 @@ public PrisonUtilsListeners() { @EventHandler( priority=EventPriority.LOWEST ) public void unbreakableBlock( BlockBreakEvent e ) { - if ( !e.isCancelled() ) { - PrisonBlock block = SpigotBlock.getSpigotBlock( e.getBlock() ).getPrisonBlock(); - - if ( BlockUtils.getInstance().isUnbreakable( block ) ) { - e.setCancelled( true ); - } - } + if ( !e.isCancelled() ) { + PrisonBlock block = SpigotBlock.getSpigotBlock( e.getBlock() ).getPrisonBlock(); + + if ( BlockUtils.getInstance().isUnbreakable( block ) ) { + e.setCancelled( true ); + } + } } - -// public HashMap getUnbreakableBlockList() { -// return unbreakableBlockList; -// } - } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMessages.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMessages.java index 5469bee41..3d7693ac5 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMessages.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMessages.java @@ -19,7 +19,6 @@ public class PrisonUtilsMessages public PrisonUtilsMessages() { super(); - } /** @@ -79,7 +78,7 @@ public void utilMessageMsg(CommandSender sender, public void utilMessageBroadcast(CommandSender sender, @Wildcard(join=true) - @Arg(name = "msg", description = "The message to send", def = "") String msg ) { + @Arg(name = "msg", description = "The message to send", def = "") String msg ) { if ( !isEnableMessageMsg() ) { 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 70067e3bb..857633891 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 @@ -103,8 +103,6 @@ public static PrisonUtilsMineBombs getInstance() { @Override protected Boolean initialize() { - //validateMineBombs(); - return true; } @@ -242,7 +240,7 @@ public void utilsFindMineBombsArmorStands( CommandSender sender, // actions: if ( show ) { -// sEntity.getWrapper(). + } if ( list ) { // Do nothing: @@ -286,20 +284,8 @@ else if ( removeAll || sender.sendMessage( "&3-= No ArmmorStands were located with the selected filters =-"); } -// Location EntityArea = new Location(Bukkit.getWorld("world"),125,71,105); -// World world = Bukkit.getServer().getWorld("world"); -// List entList = world.getEntities(); -// -// for(Entity current : entList){ -// if(current instanceof Item){ -// current.remove(); -// } -// } - } - } - } @@ -597,9 +583,10 @@ public void utilsMineBombsList( CommandSender sender, visuals.add( p.name() ); } Collections.sort( visuals ); -// for ( Particle p : Particle.values() ) { -// visuals.add( p.name() ); -// } + +// for ( Particle p : Particle.values() ) { +// visuals.add( p.name() ); +// } messages.add( "&7Visual Effects (bukkit 1.8.x: Effect):" ); for ( String line : Text.formatColumnsFromList( visuals, 4 ) ) { @@ -613,9 +600,10 @@ public void utilsMineBombsList( CommandSender sender, visuals.add( p.name() ); } Collections.sort( visuals ); -// for ( Particle p : Particle.values() ) { -// visuals.add( p.name() ); -// } + +// for ( Particle p : Particle.values() ) { +// visuals.add( p.name() ); +// } messages.add( "&7Visual Effects (Particle):" ); for ( String line : Text.formatColumnsFromList( visuals, 4 ) ) { @@ -747,6 +735,8 @@ public void utilsMineBombsList( CommandSender sender, messageShape = " &4(no shape defined)"; } } + + if ( messageShape != null && !messageShape.isEmpty() ) { messages.add( messageShape ); @@ -916,13 +906,13 @@ public void utilsMineBombsGive( CommandSender sender, // MineBombs mBombs = MineBombs.getInstance(); - MineBombData bomb = null; - - try { - // Give command. Do not enable cooldowns: - bomb = MineBombs.getInstance().findBombByName( player, bombName, false ); - } - catch (MineBombCooldownException e) { + MineBombData bomb = null; + + try { + // Give command. Do not enable cooldowns: + bomb = MineBombs.getInstance().findBombByName( player, bombName, false ); + } + catch (MineBombCooldownException e) { String msg = e.getLocalizedMessage(); player.sendMessage(msg); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMining.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMining.java index 70c880546..a3de30b66 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMining.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMining.java @@ -65,7 +65,6 @@ public void utilMiningSmelt(CommandSender sender, if ( Output.get().isDebug() ) { Output.get().logInfo( debugInfo.toString() ); } -// SpigotPrison.getInstance().getAutoFeatures().playerSmelt( player ); } } } @@ -100,7 +99,6 @@ public void utilMiningBlock(CommandSender sender, Output.get().logInfo( debugInfo.toString() ); } -// SpigotPrison.getInstance().getAutoFeatures().playerBlock( player ); } } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsModule.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsModule.java index 068ba12d8..91395c5c4 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsModule.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsModule.java @@ -88,7 +88,6 @@ public void enable() { PrisonUtilsPotions utils = new PrisonUtilsPotions(); utils.setEnablePotionEffects( isEnabled( "utils.potions.potionEffects", true ) ); - // utils.setEnablePotions( isEnabled( "utils.potions.potions.enabled", true ) ); Prison.get().getCommandHandler().registerCommands( utils ); @@ -186,13 +185,13 @@ private boolean isEnabled( String configPath, boolean defaultValue ) { * @return */ public int getElementCount() { - int results = isEnabled() ? 0 : -1; - - if ( isEnabled() ) { - results = getModulesEnabled(); - } - - return results; + int results = isEnabled() ? 0 : -1; + + if ( isEnabled() ) { + results = getModulesEnabled(); + } + + return results; } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsPotions.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsPotions.java index 303affc24..344f4b3c8 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsPotions.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsPotions.java @@ -19,7 +19,6 @@ public class PrisonUtilsPotions { private boolean enablePotionEffects = false; -// private boolean enablePotions = false; private List potionEffectsList; @@ -103,12 +102,6 @@ public void utilPotionEffects( CommandSender sender, sb.append( pType.name().toLowerCase() ).append( ' ' ); } -// for ( PotionEffectType effect : PotionEffectType.values() ) { -// if ( effect != null && effect.getName() != null ) { -// sb.append( effect.getName().toLowerCase() ).append( ' ' ); -// } -// } - sender.sendMessage( String.format( "&7Valid potion names: %s", sb.toString() ) ); return; @@ -164,26 +157,6 @@ public void utilPotionEffects( CommandSender sender, int ampliferValue = intValue( amplifier, -256, 0, 1024 ); -// List effects = new ArrayList<>(); -// -// if ( options != null && options.trim().isEmpty() ) { -// String[] opts = options.trim().split( " " ); -// for ( String opt : opts ) { -// PotionEffectOptions effect = PotionEffectOptions.fromString( opt ); -// -// if ( effect != null ) { -// effects.add( effect ); -// } -// } -// } -// - - -// boolean isAmbient = effects.contains( PotionEffectOptions.ambient ); -// boolean isParticles = effects.contains( PotionEffectOptions.particles ); -// boolean isIcon = effects.contains( PotionEffectOptions.icon ); - -// boolean isForceConfictRemoval = effects.contains( PotionEffectOptions.forceConfictRemoval ); if ( player != null && player.getWrapper() != null ) { @@ -191,14 +164,6 @@ public void utilPotionEffects( CommandSender sender, addPotion( entity, potion, durationTicks, ampliferValue ); -// PotionEffect potionEffect = new PotionEffect( potion, durationTicks, ampliferValue, -// isAmbient, isParticles, isIcon ); -// -// if ( potionEffect != null ) { -// player.getWrapper().addPotionEffect( potionEffect, isForceConfictRemoval ); -// } - - } } } @@ -271,11 +236,4 @@ public void setEnablePotionEffects( boolean enablePotionEffects ) { this.enablePotionEffects = enablePotionEffects; } -// public boolean isEnablePotions() { -// return enablePotions; -// } -// public void setEnablePotions( boolean enablePotions ) { -// this.enablePotions = enablePotions; -// } - } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsRepair.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsRepair.java index 270630590..8637d826c 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsRepair.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsRepair.java @@ -152,55 +152,55 @@ public void utilRepairInHand(CommandSender sender, private void utilRepair( SpigotPlayer player, String playerName, List repairOptions ) { - final List repaired = new ArrayList<>(); - - if ( player != null && player.getWrapper() != null && player.getWrapper().getInventory() != null ) { - - SpigotPlayerInventory inventory = new SpigotPlayerInventory( player.getWrapper().getInventory() ); - - if ( repairOptions.contains( RepairOptions.repairAll ) ) { - - repairItems( inventory.getItems(), player, repaired, repairOptions); - } - else if ( repairOptions.contains( RepairOptions.repairInHand ) ) { - List itemStacks = new ArrayList<>(); - if ( inventory.getItemInLeftHand() != null ) { - itemStacks.add( inventory.getItemInLeftHand() ); - } - if ( inventory.getItemInRightHand() != null ) { - itemStacks.add( inventory.getItemInRightHand() ); - } - - if ( itemStacks.size() > 0 ) { - repairItems( itemStacks, player, repaired, repairOptions); - } - } - - if ( repairOptions.contains( RepairOptions.repairArmour ) ) { - - repairItems( inventory.getArmorContents(), player, repaired, repairOptions); - } - - } + final List repaired = new ArrayList<>(); + + if ( player != null && player.getWrapper() != null && player.getWrapper().getInventory() != null ) { + + SpigotPlayerInventory inventory = new SpigotPlayerInventory( player.getWrapper().getInventory() ); + + if ( repairOptions.contains( RepairOptions.repairAll ) ) { + + repairItems( inventory.getItems(), player, repaired, repairOptions); + } + else if ( repairOptions.contains( RepairOptions.repairInHand ) ) { + List itemStacks = new ArrayList<>(); + if ( inventory.getItemInLeftHand() != null ) { + itemStacks.add( inventory.getItemInLeftHand() ); + } + if ( inventory.getItemInRightHand() != null ) { + itemStacks.add( inventory.getItemInRightHand() ); + } + + if ( itemStacks.size() > 0 ) { + repairItems( itemStacks, player, repaired, repairOptions); + } + } + + if ( repairOptions.contains( RepairOptions.repairArmour ) ) { + + repairItems( inventory.getArmorContents(), player, repaired, repairOptions); + } + + } if (repaired.isEmpty()) { - if ( player.getWrapper() != null ) { - player.sendMessage( String.format( "&3Nothing was repaired.") ); - } - else { - Output.get().logInfo( "&3Nothing was repaired." ); - } + if ( player.getWrapper() != null ) { + player.sendMessage( String.format( "&3Nothing was repaired.") ); + } + else { + Output.get().logInfo( "&3Nothing was repaired." ); + } } else { - // At least one item was repaired so update the player's inventory: - player.updateInventory(); - - player.sendMessage( - String.format( "&3Repaired &7%d &3items: %s", - repaired.size(), String.join(", ", repaired)) ); - + // At least one item was repaired so update the player's inventory: + player.updateInventory(); + + player.sendMessage( + String.format( "&3Repaired &7%d &3items: %s", + repaired.size(), String.join(", ", repaired)) ); + } } @@ -226,22 +226,22 @@ private List getOptions( RepairOptions primaryOption, String opti options += " " + playerName; } - List repairOptions = new ArrayList<>(); - for ( String rOpt : options.split( " " ) ) { - RepairOptions repairOption = RepairOptions.fromString( rOpt ); - if ( repairOption != null ) { - repairOptions.add( repairOption ); - } - } - - repairOptions.remove( RepairOptions.repairInHand ); - repairOptions.remove( RepairOptions.repairAll ); - - if ( primaryOption != null ) { - repairOptions.add( 0, primaryOption ); - } - - return repairOptions; + List repairOptions = new ArrayList<>(); + for ( String rOpt : options.split( " " ) ) { + RepairOptions repairOption = RepairOptions.fromString( rOpt ); + if ( repairOption != null ) { + repairOptions.add( repairOption ); + } + } + + repairOptions.remove( RepairOptions.repairInHand ); + repairOptions.remove( RepairOptions.repairAll ); + + if ( primaryOption != null ) { + repairOptions.add( 0, primaryOption ); + } + + return repairOptions; } /** @@ -255,26 +255,26 @@ private List getOptions( RepairOptions primaryOption, String opti private boolean repairItem( SpigotItemStack item, List repaired, List repairOptions ) { - boolean results = false; - - Compatibility compat = SpigotCompatibility.getInstance(); - - if ( item != null && !item.isBlock() && !item.isAir() ) { - - if ( compat.getDurabilityMax( item ) > 0 && // has durability if > 0 - compat.getDurability( item ) > 0 && // has wear if > 0 - ( item.getEnchantments().isEmpty() || - !item.getEnchantments().isEmpty() && - !repairOptions.contains( RepairOptions.repairEnchanted ) - ) ) { - - results = compat.setDurability( item, 0 ); - if ( results ) { - final String itemName = item.getName(); - repaired.add(itemName.replace('_', ' ')); - } - } - } + boolean results = false; + + Compatibility compat = SpigotCompatibility.getInstance(); + + if ( item != null && !item.isBlock() && !item.isAir() ) { + + if ( compat.getDurabilityMax( item ) > 0 && // has durability if > 0 + compat.getDurability( item ) > 0 && // has wear if > 0 + ( item.getEnchantments().isEmpty() || + !item.getEnchantments().isEmpty() && + !repairOptions.contains( RepairOptions.repairEnchanted ) + ) ) { + + results = compat.setDurability( item, 0 ); + if ( results ) { + final String itemName = item.getName(); + repaired.add(itemName.replace('_', ' ')); + } + } + } return results; @@ -290,14 +290,15 @@ private void repairItems( List itemStacks, SpigotPlayer player, repairItem( item, repaired, repairOptions ); } } + private void repairItems( ItemStack[] itemStacks, SpigotPlayer player, List repaired, List repairOptions ) { - for (final ItemStack is : itemStacks) { - SpigotItemStack item = (SpigotItemStack) is; - - repairItem( item, repaired, repairOptions ); - } + for (final ItemStack is : itemStacks) { + SpigotItemStack item = (SpigotItemStack) is; + + repairItem( item, repaired, repairOptions ); + } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsTitles.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsTitles.java index 60bbd9cbc..fbb173d26 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsTitles.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsTitles.java @@ -143,127 +143,12 @@ public void utilsTitlesActionBar( CommandSender sender, player.setActionBar( message ); -// String titleJson = String.format( -// "title %s actionBar {\"text\": \"%s\"}", -// player.getName(), message ); -// -// dispatchCommand( titleJson ); } } } -// @Command(identifier = "prison utils titles clear", -// description = "Clears the screen title from the screens of the specified player.", -// onlyPlayers = false, -// permissions = "prison.utils.titles.clear", -// altPermissions = "prison.utils.titles.clear.others") -// public void utilsTitlesClear( CommandSender sender, -// @Arg(name = "playerName", description = "Player name") String playerName -// -// ) { -// -// if ( !isEnableTitlesTitle() ) { -// -// Output.get().logInfo( "Prison's utils command titles clear is disabled in modules.yml." ); -// } -// else { -// -// SpigotPlayer player = checkPlayerPerms( sender, playerName, -// "prison.utils.titles.clear", "prison.utils.titles.clear.others" ); -// -// if ( player != null ) { -// -// String titleJson = String.format( -// "title %s clear", -// player.getName() ); -// -// dispatchCommand( titleJson ); -// } -// -// } -// } -// @Command(identifier = "prison utils titles reset", -// description = "Resets the subtitle text for the specified player to blank text, " + -// "and the fade-in, stay and fade-out times to their default values " + -// "(defaults to fadeIn 10 ticks, stay 70 ticks, and fadeOut 20 ticks).", -// onlyPlayers = false, -// permissions = "prison.utils.titles.reset", -// altPermissions = "prison.utils.titles.reset.others") -// public void utilsTitlesReset( CommandSender sender, -// @Arg(name = "playerName", description = "Player name") String playerName -// -// ) { -// -// if ( !isEnableTitlesTitle() ) { -// -// Output.get().logInfo( "Prison's utils command titles reset is disabled in modules.yml." ); -// } -// else { -// -// SpigotPlayer player = checkPlayerPerms( sender, playerName, -// "prison.utils.titles.reset", "prison.utils.titles.reset.others" ); -// -// if ( player != null ) { -// -// String titleJson = String.format( -// "title %s reset", -// player.getName() ); -// -// dispatchCommand( titleJson ); -// } -// -// } -// } - - -// @Command(identifier = "prison utils titles times ", -// description = "Resets the player's title times for fade in, stay and fade out. " + -// "These settings will change the client's settings and they will stay in effect " + -// "until they are changed. A value of -1 will use the prior value for that setting. " + -// "This change will apply to all future titles for the player, until it is changed. " + -// "Use 'titles clear' to remove the titles, or 'titles reset' to restore the default " + -// "timings for the fadeIn, stay, and fadeOut values.", -// onlyPlayers = false, -// permissions = "prison.utils.titles.fadein", -// altPermissions = "prison.utils.titles.fadein.others") -// public void utilsTitlesFadeIn( CommandSender sender, -// @Arg(name = "playerName", description = "Player name") String playerName, -// @Arg(name = "fadeIn", description = "The the fade in time, in ticks. " + -// "A value of -1 will use the prior value. [-1]", def= "-1") int fadeIn, -// @Arg(name = "stay", description = "The the fade in time, in ticks. " + -// "A value of -1 will use the prior value. [-1]", def= "-1") int stay, -// @Arg(name = "fadeOut", description = "The the fade out time, in ticks. " + -// "A value of -1 will use the prior value. [-1]", def= "-1") int fadeOut -// -// ) { -// -// if ( !isEnableTitlesTimes() ) { -// -// Output.get().logInfo( "Prison's utils command titles times is disabled in modules.yml." ); -// } -// else { -// -// SpigotPlayer player = checkPlayerPerms( sender, playerName, -// "prison.utils.titles.fadein", "prison.utils.titles.fadein.others" ); -// -// if ( player != null ) { -// -// String titleJson = String.format( -// "title %s times %d %d %d", -// player.getName(), fadeIn, stay, fadeOut ); -// -// dispatchCommand( titleJson ); -// } -// -// } -// } - -// private void dispatchCommand( String command ) { -// Prison.get().getPlatform().dispatchCommand( Text.translateAmpColorCodes( command ) ); -// } - public boolean isEnableTitlesTitle() { return enableTitlesTitle; } @@ -271,13 +156,6 @@ public void setEnableTitlesTitle( boolean enableTitlesTitle ) { this.enableTitlesTitle = enableTitlesTitle; } -// public boolean isEnableTitlesSubtitle() { -// return enableTitlesSubtitle; -// } -// public void setEnableTitlesSubtitle( boolean enableTitlesSubtitle ) { -// this.enableTitlesSubtitle = enableTitlesSubtitle; -// } - public boolean isEnableTitlesActionBar() { return enableTitlesActionBar; } @@ -285,25 +163,4 @@ public void setEnableTitlesActionBar( boolean enableTitlesActionBar ) { this.enableTitlesActionBar = enableTitlesActionBar; } -// public boolean isEnableTitlesClear() { -// return enableTitlesClear; -// } -// public void setEnableTitlesClear( boolean enableTitlesClear ) { -// this.enableTitlesClear = enableTitlesClear; -// } -// -// public boolean isEnableTitlesReset() { -// return enableTitlesReset; -// } -// public void setEnableTitlesReset( boolean enableTitlesReset ) { -// this.enableTitlesReset = enableTitlesReset; -// } -// -// public boolean isEnableTitlesTimes() { -// return enableTitlesTimes; -// } -// public void setEnableTitlesTimes( boolean enableTitlesTimes ) { -// this.enableTitlesTimes = enableTitlesTimes; -// } - } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/UnbreakableBlockData.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/UnbreakableBlockData.java index 480c9989e..57a0af48a 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/UnbreakableBlockData.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/UnbreakableBlockData.java @@ -37,10 +37,6 @@ public UnbreakableBlockData( Location key, PrisonBlock block, Mine mine ) { this.taskId = 0; } -// public UnbreakableBlockData( PrisonBlock block, Mine mine ) { -// this( block.getLocation(), block, mine ); -// } - public Location getKey() { return key; } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/worldguard/WorldGuard6Integration.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/worldguard/WorldGuard6Integration.java index 387c3d226..016e669a6 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/worldguard/WorldGuard6Integration.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/worldguard/WorldGuard6Integration.java @@ -63,7 +63,5 @@ public void integrate() { } } - - } 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 index f9e3b9aa1..0fb009d95 100644 --- 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 @@ -30,8 +30,6 @@ public WorldGuardSettings() { } - - public String getWGPrefixRegionMine() { return wgPrefixRegionMine; } diff --git a/prison-spigot/src/test/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTest.java b/prison-spigot/src/test/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTest.java index 63e164248..68a71c68c 100644 --- a/prison-spigot/src/test/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTest.java +++ b/prison-spigot/src/test/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombsTest.java @@ -2,8 +2,6 @@ import static org.junit.Assert.assertEquals; -import org.junit.Test; - public class PrisonUtilsMineBombsTest extends PrisonUtilsMineBombs { // @Test From 10e9c79001834ea9f18899c47bf0dd1898539e97 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 23 Mar 2026 16:40:07 -0400 Subject: [PATCH 315/323] Prison Cleanup: prison-spigot: Removed obsolete and unneeded comments and fix indentation where needed. Second part. 2026-03-15 --- docs/changelog_v3.3.x.md | 5 +- .../spigot/game/SpigotCommandSender.java | 224 ++++--- .../prison/spigot/game/SpigotLocation.java | 19 - .../spigot/game/SpigotOfflinePlayer.java | 159 ++--- .../prison/spigot/game/SpigotPlayer.java | 539 +++-------------- .../prison/spigot/game/SpigotPlayerUtil.java | 38 -- .../prison/spigot/game/SpigotWorld.java | 150 ++--- .../spigot/game/entity/SpigotArmorStand.java | 62 -- .../spigot/game/entity/SpigotEntity.java | 20 - .../spigot/gui/ListenersPrisonManager.java | 562 ++---------------- .../prison/spigot/gui/SpigotGUIMenuTools.java | 76 --- .../prison/spigot/gui/SpigotPrisonGUI.java | 4 - .../gui/backpacks/BackpacksPlayerGUI.java | 5 - .../prison/spigot/gui/guiutility/Button.java | 25 +- .../spigot/gui/guiutility/ButtonLore.java | 3 +- .../gui/guiutility/SpigotGUIComponents.java | 57 +- .../spigot/gui/mine/SpigotBlocksListGUI.java | 36 +- .../spigot/gui/mine/SpigotMinesBlocksGUI.java | 54 +- .../spigot/gui/mine/SpigotMinesGUI.java | 73 +-- .../spigot/gui/mine/SpigotPlayerMinesGUI.java | 198 +++--- .../gui/rank/SpigotConfirmPrestigeGUI.java | 51 +- .../spigot/gui/rank/SpigotLaddersGUI.java | 33 +- .../gui/rank/SpigotPlayerPrestigesGUI.java | 33 - .../spigot/gui/rank/SpigotPlayerRanksGUI.java | 85 ++- .../spigot/gui/rank/SpigotRankPriceGUI.java | 4 - .../gui/rank/SpigotRankUPCommandsGUI.java | 4 +- .../spigot/gui/rank/SpigotRanksGUI.java | 22 - .../gui/sellall/SellAllAdminBlocksGUI.java | 71 +-- .../spigot/gui/sellall/SellAllAdminGUI.java | 6 +- .../spigot/gui/sellall/SellAllDelayGUI.java | 6 - .../spigot/gui/sellall/SellAllPlayerGUI.java | 29 +- .../SellAllPrestigesMultiplierGUI.java | 2 - .../SellAllPrestigesSetMultiplierGUI.java | 4 - .../spigot/gui/sellall/SellAllPriceGUI.java | 4 - .../integrations/IntegrationBackpackAPI.java | 313 +++++----- .../IntegrationCrazyEnchantmentsPickaxes.java | 1 - .../IntegrationMinepacksPlugin.java | 265 ++++----- 37 files changed, 811 insertions(+), 2431 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 650281e69..a37f25201 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.19j 2026-03-14 +# 3.3.0-alpha.19j 2026-03-15 + + +* **Prison Cleanup: prison-spigot: Removed obsolete and unneeded comments and fix indentation where needed.** Second part. * **Prison Cleanup: prison-spigot: Removed obsolete and unneeded comments and fix indentation where needed.** First part. 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 d417b81da..faca09541 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 @@ -67,10 +67,10 @@ public UUID getUniqueId() { } public UUID getUUID() { - UUID uuid = null; - if ( isPlayer() ) { - uuid = ((org.bukkit.entity.Player) bukkitSender).getUniqueId(); - } + UUID uuid = null; + if ( isPlayer() ) { + uuid = ((org.bukkit.entity.Player) bukkitSender).getUniqueId(); + } return uuid; } @@ -89,10 +89,10 @@ public String getName() { @Override public void dispatchCommand(String command) { - command = CommandHandler.remapRootCmdIdentifiers( command ); - - String registeredCmd = Prison.get().getCommandHandler() - .findRegisteredCommand( command ); + command = CommandHandler.remapRootCmdIdentifiers( command ); + + String registeredCmd = Prison.get().getCommandHandler() + .findRegisteredCommand( command ); Bukkit.getServer().dispatchCommand(bukkitSender, registeredCmd); } @@ -104,11 +104,11 @@ public boolean doesSupportColors() { @Override public void sendMessage(String message) { - - String[] msgs = Text.translateAmpColorCodes(message).split( "\\{br\\}" ); - - for ( String msg : msgs ) { - bukkitSender.sendMessage(msg); + + String[] msgs = Text.translateAmpColorCodes(message).split( "\\{br\\}" ); + + for ( String msg : msgs ) { + bukkitSender.sendMessage(msg); } } @@ -116,24 +116,24 @@ public void sendMessage(String message) { public void sendMessage(String[] messages) { for (String message : messages) { - String[] msgs = Text.translateAmpColorCodes(message).split( "\\{br\\}" ); - for ( String msg : msgs ) { - - sendMessage(msg); - } + String[] msgs = Text.translateAmpColorCodes(message).split( "\\{br\\}" ); + for ( String msg : msgs ) { + + sendMessage(msg); + } } } @Override public void sendMessage(List messages) { - for (String message : messages) { - - String[] msgs = Text.translateAmpColorCodes(message).split( "\\{br\\}" ); - for ( String msg : msgs ) { - - sendMessage(msg); - } - } + for (String message : messages) { + + String[] msgs = Text.translateAmpColorCodes(message).split( "\\{br\\}" ); + for ( String msg : msgs ) { + + sendMessage(msg); + } + } } @Override @@ -146,7 +146,7 @@ public void sendRaw(String json) { @Override public boolean isOp() { - return bukkitSender.isOp(); + return bukkitSender.isOp(); } @Override @@ -163,10 +163,10 @@ public boolean hasPermission(String perm) { @Override public List getPermissions() { - List results = new ArrayList<>(); - - Set perms = bukkitSender.getEffectivePermissions(); - for ( PermissionAttachmentInfo perm : perms ) + List results = new ArrayList<>(); + + Set perms = bukkitSender.getEffectivePermissions(); + for ( PermissionAttachmentInfo perm : perms ) { results.add( perm.getPermission() ); } @@ -178,128 +178,108 @@ public List getPermissions() { @Override public List getPermissions( String prefix ) { - return getPermissions( prefix, getPermissions() ); + return getPermissions( prefix, getPermissions() ); } @Override public List getPermissions( String prefix, List perms ) { - List results = new ArrayList<>(); - - for ( String perm : perms ) { - if ( perm.startsWith( prefix ) ) { - results.add( perm ); - } - } - - return results; + List results = new ArrayList<>(); + + for ( String perm : perms ) { + if ( perm.startsWith( prefix ) ) { + results.add( perm ); + } + } + + return results; } -// @Override -// public List getPermissions( String prefix ) { -// List results = new ArrayList<>(); -// -// for ( String perm : getPermissions() ) { -// if ( perm.startsWith( prefix ) ) { -// results.add( perm ); -// } -// } -// -// return results; -// } @Override public double getSellAllMultiplier() { - double results = 1.0; - - if ( isPlayer() ) { - - SellAllUtil sellall = SpigotPrison.getInstance().getSellAllUtil(); - - if ( sellall != null && getWrapper() != null ) { - results = sellall.getPlayerMultiplier((org.bukkit.entity.Player) getWrapper()); - } - } - - return results; - -// Optional oPlayer = Prison.get().getPlatform().getPlayer( getName() ); -// -// if ( oPlayer.isPresent() ) { -// results = oPlayer.get().getSellAllMultiplier(); -// } -// -// return results; + double results = 1.0; + + if ( isPlayer() ) { + + SellAllUtil sellall = SpigotPrison.getInstance().getSellAllUtil(); + + if ( sellall != null && getWrapper() != null ) { + results = sellall.getPlayerMultiplier((org.bukkit.entity.Player) getWrapper()); + } + } + + return results; } @Override public double getSellAllMultiplierDebug() { - double results = 1.0; - - if ( isPlayer() ) { - - SellAllUtil sellall = SpigotPrison.getInstance().getSellAllUtil(); - - if ( sellall != null && getWrapper() != null ) { - - Player player = getPlatformPlayer(); - - results = sellall.getPlayerMultiplierDebug( player ); - } - } - - return results; + double results = 1.0; + + if ( isPlayer() ) { + + SellAllUtil sellall = SpigotPrison.getInstance().getSellAllUtil(); + + if ( sellall != null && getWrapper() != null ) { + + Player player = getPlatformPlayer(); + + results = sellall.getPlayerMultiplierDebug( player ); + } + } + + return results; } @Override public List getSellAllMultiplierListings() { - List results = new ArrayList<>(); - - if ( isPlayer() ) { - - SellAllUtil sellall = SpigotPrison.getInstance().getSellAllUtil(); - - if ( sellall != null && getWrapper() != null ) { - results.addAll( sellall.getPlayerMultiplierList((org.bukkit.entity.Player) getWrapper()) ); - } - } - - - return results; + List results = new ArrayList<>(); + + if ( isPlayer() ) { + + SellAllUtil sellall = SpigotPrison.getInstance().getSellAllUtil(); + + if ( sellall != null && getWrapper() != null ) { + results.addAll( sellall.getPlayerMultiplierList((org.bukkit.entity.Player) getWrapper()) ); + } + } + + + return results; } public List getPermissionsIntegrations( boolean detailed ) { - List results = new ArrayList<>(); - - Optional oPlayer = Prison.get().getPlatform().getPlayer( getName() ); - - if ( oPlayer.isPresent() ) { - - PermissionIntegration perms = PrisonAPI.getIntegrationManager() .getPermission(); - if ( perms != null ) { - results = perms.getPermissions( oPlayer.get(), detailed ); - } - } - - return results; + List results = new ArrayList<>(); + + Optional oPlayer = Prison.get().getPlatform().getPlayer( getName() ); + + if ( oPlayer.isPresent() ) { + + PermissionIntegration perms = PrisonAPI.getIntegrationManager() .getPermission(); + if ( perms != null ) { + results = perms.getPermissions( oPlayer.get(), detailed ); + } + } + + return results; } @Override public boolean isPlayer() { - return bukkitSender != null && bukkitSender instanceof org.bukkit.entity.Player; + return bukkitSender != null && bukkitSender instanceof org.bukkit.entity.Player; } @Override public String toString() { - StringBuilder sb = new StringBuilder(); - - sb.append( "SpigotCommandSender: " ).append( getName() ) - .append( " isOp=" ).append( isOp() ) - .append( " isPlayer=" ).append( isPlayer() ); - - return sb.toString(); + StringBuilder sb = new StringBuilder(); + + sb.append( "SpigotCommandSender: " ).append( getName() ) + .append( " isOp=" ).append( isOp() ) + .append( " isPlayer=" ).append( isPlayer() ); + + return sb.toString(); } public org.bukkit.command.CommandSender getWrapper() { diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotLocation.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotLocation.java index 91b95dbd8..dce7ea10e 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotLocation.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotLocation.java @@ -29,7 +29,6 @@ public org.bukkit.Location getBukkitLocation() { if ( bukkitLocation == null ) { bukkitLocation = getBukkitLocation( this ); -// bukkitLocation = createBukkitLocation(); } return bukkitLocation; @@ -46,27 +45,9 @@ public static org.bukkit.Location getBukkitLocation( Location location ) { bLocation.setPitch( location.getPitch() ); -// bLocation.; - return bLocation; } -// private org.bukkit.Location createBukkitLocation() { -// -// org.bukkit.World world = Bukkit.getWorld( getWorld().getName() ); -// -// org.bukkit.Location bLocation = new org.bukkit.Location(world, getBlockX(), getBlockY(), getBlockZ() ); -// -// bLocation.setYaw(getYaw()); -// -// bLocation.setPitch(getPitch()); -// -// return bLocation; -// } - -// public void setBukkitLocation(org.bukkit.Location bukkitLocation) { -// this.bukkitLocation = bukkitLocation; -// } public org.bukkit.World getBukkitWorld() { return getBukkitLocation().getWorld(); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java index dd4b2007b..b5fbb9121 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java @@ -116,23 +116,17 @@ public void setFileCache(File fileCache) { public String filenamePlayer() { return getFilePlayer().getName(); -// return JsonFileIO.filenamePlayer( this ); } public String filenameCache() { return getFileCache().getName(); -// return JsonFileIO.filenameCache( this ); } -// public String getPlayerFileName() { -// -// return JsonFileIO.filenamePlayer( this ); -// } @Override public String toString() { - return getName(); + return getName(); } @@ -154,7 +148,6 @@ public String getDisplayName() { @Override public boolean isOnline() { return offlinePlayer.isOnline(); -// return false; } @@ -171,17 +164,10 @@ public long getLastSeenDate() { */ @Override public boolean isPlayer() { - return ( offlinePlayer != null && offlinePlayer.getPlayer() != null && - offlinePlayer.getPlayer() instanceof Player ); -// return false; + return ( offlinePlayer != null && offlinePlayer.getPlayer() != null && + offlinePlayer.getPlayer() instanceof Player ); } -// @Override -// public boolean hasPermission( String perm ) { -// Output.get().logError( "SpigotOfflinePlayer.hasPermission: Cannot access permissions for offline players." ); -// return false; -// } - @Override public void setDisplayName( String newDisplayName ) { Output.get().logError( "SpigotOfflinePlayer.setDisplayName: Cannot set display names." ); @@ -254,7 +240,7 @@ public tech.mcprison.prison.internal.block.Block getLineOfSightBlock() { public List getLineOfSightBlocks() { List results = new ArrayList<>(); - return results; + return results; } @@ -272,10 +258,6 @@ public Inventory getInventory() { return null; } -// @Override -// public void printDebugInventoryInformationToConsole() { -// -// } public OfflinePlayer getWrapper() { return offlinePlayer; @@ -294,43 +276,43 @@ public void recalculatePermissions() { @Override public List getPermissions() { - List results = new ArrayList<>(); - - if ( offlinePlayer.getPlayer() != null ) { - - Set perms = offlinePlayer.getPlayer().getEffectivePermissions(); - for ( PermissionAttachmentInfo perm : perms ) - { - results.add( perm.getPermission() ); - } - } - else { - // try to use vault: - - // TODO add permission integrations here!! - } - - - return results; + List results = new ArrayList<>(); + + if ( offlinePlayer.getPlayer() != null ) { + + Set perms = offlinePlayer.getPlayer().getEffectivePermissions(); + for ( PermissionAttachmentInfo perm : perms ) + { + results.add( perm.getPermission() ); + } + } + else { + // try to use vault: + + // TODO add permission integrations here!! + } + + + return results; } @Override public List getPermissions( String prefix ) { - return getPermissions( prefix, getPermissions() ); + return getPermissions( prefix, getPermissions() ); } @Override public List getPermissions( String prefix, List perms ) { - List results = new ArrayList<>(); - - for ( String perm : perms ) { - if ( perm.startsWith( prefix ) ) { - results.add( perm ); - } - } - - return results; + List results = new ArrayList<>(); + + for ( String perm : perms ) { + if ( perm.startsWith( prefix ) ) { + results.add( perm ); + } + } + + return results; } @Override @@ -347,30 +329,8 @@ public boolean hasPermission( String perm ) { } return hasPerm; - -// List perms = getPermissions( perm ); -// return perms.contains( perm ); } -// @Override -// public List getPermissions() { -// List results = new ArrayList<>(); -// -// return results; -// } -// -// @Override -// public List getPermissions( String prefix ) { -// List results = new ArrayList<>(); -// -// for ( String perm : getPermissions() ) { -// if ( perm.startsWith( prefix ) ) { -// results.add( perm ); -// } -// } -// -// return results; -// } @Override public List getPermissionsIntegrations( boolean detailed ) { @@ -391,63 +351,48 @@ public List getPermissionsIntegrations( boolean detailed ) { */ @Override public double getSellAllMultiplier() { - double results = 1.0; + double results = 1.0; SellAllUtil sellall = SpigotPrison.getInstance().getSellAllUtil(); if ( sellall != null && getWrapper() != null ) { -// SpigotPlayer sPlayer = new SpigotPlayer( getWrapper() ); - results = sellall.getPlayerMultiplier( this ); } -// SpigotPlayer sPlayer = null; -// -// if ( getWrapper() != null ) { -// sPlayer = new SpigotPlayer( getWrapper() ); -// -// results = sPlayer.getSellAllMultiplier(); -// } - - return results; + return results; } @Override public double getSellAllMultiplierDebug() { - double results = 1.0; + double results = 1.0; // NOTE: isPlayer() is a check to see if it's tied to the bukkit Player object, of // which offline player is not. But the sellall multiplier can still be called. -// if ( isPlayer() ) { SellAllUtil sellall = SpigotPrison.getInstance().getSellAllUtil(); if ( sellall != null && getWrapper() != null ) { -// SpigotPlayer sPlayer = new SpigotPlayer( getWrapper() ); - results = sellall.getPlayerMultiplierDebug( this ); } -// } return results; } public List getSellAllMultiplierListings() { - List results = new ArrayList<>(); - - if ( isPlayer() ) { - - SellAllUtil sellall = SpigotPrison.getInstance().getSellAllUtil(); - - if ( sellall != null && getWrapper() != null ) { - results.addAll( sellall.getPlayerMultiplierList((org.bukkit.entity.Player) getWrapper()) ); - } - } - - - return results; + List results = new ArrayList<>(); + + if ( isPlayer() ) { + + SellAllUtil sellall = SpigotPrison.getInstance().getSellAllUtil(); + + if ( sellall != null && getWrapper() != null ) { + results.addAll( sellall.getPlayerMultiplierList((org.bukkit.entity.Player) getWrapper()) ); + } + } + + return results; } @Override @@ -517,16 +462,6 @@ public tech.mcprison.prison.internal.Player getPlatformPlayer() { SpigotPlayer sPlayer = SpigotPlayer.getSpigotPlayer( getRankPlayer() ); return sPlayer; - -// tech.mcprison.prison.internal.Player player = null; -// -// Optional oPlayer = Prison.get().getPlatform().getPlayer( getName() ); -// -// if ( oPlayer.isPresent() ) { -// player = oPlayer.get(); -// } -// -// return player; } 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 c7c99176a..b2e5ecab5 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 @@ -26,11 +26,9 @@ import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.Material; -import org.bukkit.OfflinePlayer; import org.bukkit.Statistic; import org.bukkit.block.Block; import org.bukkit.entity.ExperienceOrb; -import org.bukkit.inventory.meta.ItemMeta; import com.cryptomorin.xseries.XMaterial; @@ -38,7 +36,6 @@ import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; import tech.mcprison.prison.autofeatures.AutoFeaturesWrapper; import tech.mcprison.prison.autofeatures.PlayerMessaging.MessageType; -import tech.mcprison.prison.bombs.MineBombData; import tech.mcprison.prison.cache.PlayerCache; import tech.mcprison.prison.cache.PlayerCachePlayerData; import tech.mcprison.prison.file.JsonFileIO; @@ -63,7 +60,6 @@ import tech.mcprison.prison.spigot.utils.tasks.PlayerMessagingTask; import tech.mcprison.prison.util.Gamemode; import tech.mcprison.prison.util.Location; -import tech.mcprison.prison.util.Text; import tech.mcprison.prison.util.Vector; /** @@ -120,25 +116,25 @@ public SpigotPlayer(org.bukkit.entity.Player bukkitPlayer) { */ public static SpigotPlayer getSpigotPlayer( RankPlayer rankPlayer ) { - SpigotPlayer result = null; - - // We have a RankPlayer object, but we need to connect this SpigotPlayer object - // to the bukkit player object. - - // NOTE: We're directly accessing bukkit here because it's more direct instead of - // trying to do that through a few different function within the - // SpigotPlatform. - - // First try to load a bukkit online player: - org.bukkit.entity.Player bPlayer = Bukkit.getPlayer( rankPlayer.getUUID() ); - - if ( bPlayer != null ) { - result = new SpigotPlayer( bPlayer ); - - result.setRankPlayer( rankPlayer ); - } - - return result; + SpigotPlayer result = null; + + // We have a RankPlayer object, but we need to connect this SpigotPlayer object + // to the bukkit player object. + + // NOTE: We're directly accessing bukkit here because it's more direct instead of + // trying to do that through a few different function within the + // SpigotPlatform. + + // First try to load a bukkit online player: + org.bukkit.entity.Player bPlayer = Bukkit.getPlayer( rankPlayer.getUUID() ); + + if ( bPlayer != null ) { + result = new SpigotPlayer( bPlayer ); + + result.setRankPlayer( rankPlayer ); + } + + return result; } @@ -159,7 +155,7 @@ public static SpigotPlayer getSpigotPlayer( RankPlayer rankPlayer ) { */ public String getPlayerFileName() { - return filenamePlayer(); + return filenamePlayer(); } @@ -199,20 +195,6 @@ public String filenameCache() { return getFileCache().getName(); } -// public String getPlayerFileName() { -// -// return JsonFileIO.filenamePlayer( this ); -// } - -// @Override -// public UUID getUUID() { -// return bukkitPlayer.getUniqueId(); -// } - -// @Override -// public String getName() { -// return bukkitPlayer.getName(); -// } @Override public String getDisplayName() { @@ -239,17 +221,6 @@ public void give(ItemStack itemStack) { bukkitPlayer.getInventory().addItem(SpigotUtil.prisonItemStackToBukkit(itemStack)); } -// @Override -// public Location getLocation() { -// return SpigotUtil.bukkitLocationToPrison(bukkitPlayer.getLocation()); -// } - -// @Override public boolean teleport(Location location) { -// -// -// return bukkitPlayer.teleport(SpigotUtil.prisonLocationToBukkit(location), -// PlayerTeleportEvent.TeleportCause.PLUGIN); -// } @Override public boolean isOnline() { @@ -273,66 +244,29 @@ public void setGamemode(Gamemode gamemode) { @Override public Optional getLocale() { - Optional results = Optional.empty(); + Optional results = Optional.empty(); -// if ( SpigotNMSPlayer.getInstance().hasSupport() ) { -// try { -// results = Optional.ofNullable( -// SpigotNMSPlayer.getInstance().getLocale( getWrapper() ) -// ); -// } -// catch ( Exception ex ) { -// Output.get().logInfo( -// "Failed to initialize NMS components -- " + -// "NMS is not functional - " + ex.getMessage() ); -// } -// } return results; } @Override public SpigotBlock getLineOfSightBlock() { - SpigotBlock results = null; - -// org.bukkit.Location eyeLocation = getWrapper().getEyeLocation(); -// org.bukkit.util.Vector lineOfSight = eyeLocation.getDirection().normalize(); -// -// double maxDistance = 256; -// -// for(double i = 0; i < maxDistance; ++i){ -// Block block = eyeLocation.add( lineOfSight.clone().multiply(i) ).getBlock(); -// if( block.getType() != Material.AIR ) { -//// if( block.getType().isSolid() ) { -// -// results = new SpigotBlock( block ); -// break; -// } -// -// } -// -// return results; -// - - - -// List results = new ArrayList<>(); - - - - List blocks = bukkitPlayer.getLineOfSight( null, 256 ); - for ( Block block : blocks ) { - if ( block != null && block.getType() != Material.AIR && - !SpigotCompatibility.getInstance().isPassable(block) ) { - - - // return the first non-null and non-AIR block, which will - // be the one the player is looking at: - results = SpigotBlock.getSpigotBlock( block ); - } - } - - return results; + SpigotBlock results = null; + + List blocks = bukkitPlayer.getLineOfSight( null, 256 ); + for ( Block block : blocks ) { + if ( block != null && block.getType() != Material.AIR && + !SpigotCompatibility.getInstance().isPassable(block) ) { + + + // return the first non-null and non-AIR block, which will + // be the one the player is looking at: + results = SpigotBlock.getSpigotBlock( block ); + } + } + + return results; } @@ -356,27 +290,27 @@ public SpigotBlock getLineOfSightBlock() { * @return */ public Location getLineOfSightExactLocation() { - - SpigotLocation eyeLoc = new SpigotLocation( getWrapper().getEyeLocation() ); - Vector eyeVec = eyeLoc.getDirection(); - - Location loc = eyeLoc.add(eyeVec); - - int i = 0; - - // Is isPassible also true when isEmpty? If so, then this could be simplified... - // while ( i++ <= 75 && (loc.getBlockAt().isEmpty() || loc.getBlockAt().isPassible()) ) { - - while ( i++ <= 75 && loc.getBlockAt().isEmpty() ) { - - loc = loc.add(eyeVec); - } - - if ( loc.getBlockAt().isEmpty() ) { - loc = null; - } - - return loc; + + SpigotLocation eyeLoc = new SpigotLocation( getWrapper().getEyeLocation() ); + Vector eyeVec = eyeLoc.getDirection(); + + Location loc = eyeLoc.add(eyeVec); + + int i = 0; + + // Is isPassible also true when isEmpty? If so, then this could be simplified... + // while ( i++ <= 75 && (loc.getBlockAt().isEmpty() || loc.getBlockAt().isPassible()) ) { + + while ( i++ <= 75 && loc.getBlockAt().isEmpty() ) { + + loc = loc.add(eyeVec); + } + + if ( loc.getBlockAt().isEmpty() ) { + loc = null; + } + + return loc; } /** @@ -389,21 +323,21 @@ public Location getLineOfSightExactLocation() { @Override public List getLineOfSightBlocks() { - List results = new ArrayList<>(); - - List blocks = bukkitPlayer.getLineOfSight( null, 256 ); - for ( Block block : blocks ) { - if ( block != null && - (results.size() == 0 && block.getType() != Material.AIR || - results.size() > 0 && results.size() < 20 )) { - - // return the first non-null and non-AIR block, which will - // be the one the player is looking at: - results.add( SpigotBlock.getSpigotBlock( block ) ); - } + List results = new ArrayList<>(); + + List blocks = bukkitPlayer.getLineOfSight( null, 256 ); + for ( Block block : blocks ) { + if ( block != null && + (results.size() == 0 && block.getType() != Material.AIR || + results.size() > 0 && results.size() < 20 )) { + + // return the first non-null and non-AIR block, which will + // be the one the player is looking at: + results.add( SpigotBlock.getSpigotBlock( block ) ); + } } - return results; + return results; } @@ -417,7 +351,7 @@ public Inventory getInventory() { } public SpigotPlayerInventory getSpigotPlayerInventory() { - return new SpigotPlayerInventory(getWrapper().getInventory()); + return new SpigotPlayerInventory(getWrapper().getInventory()); } @Override @@ -438,284 +372,33 @@ public boolean isPlayer() { @Override public long getLastSeenDate() { - return bukkitPlayer.getLastPlayed(); + return bukkitPlayer.getLastPlayed(); } -// @Override -// public boolean isOp() { -// return bukkitPlayer.isOp(); -// } - -// @Override -// public boolean hasPermission( String perm ) { -// List perms = getPermissions( perm ); -// return perms.contains( perm ); -// } - - -// @Override -// public List getPermissions() { -// List results = new ArrayList<>(); -// -// Set perms = bukkitPlayer.getEffectivePermissions(); -// for ( PermissionAttachmentInfo perm : perms ) -// { -// results.add( perm.getPermission() ); -// } -// -// return results; -// } - - -// @Override -// public List getPermissions( String prefix ) { -// List results = new ArrayList<>(); -// -// for ( String perm : getPermissions() ) { -// if ( perm.startsWith( prefix ) ) { -// results.add( perm ); -// } -// } -// -// return results; -// } - - -// /** -// *

    This uses the sellall configs for the permission name to use to get the list of -// * multipliers. It then adds all of the multipliers together to ... -// * -// *

    -// * -// */ -// @Override -// public double getSellAllMultiplier() { -// double results = 1.0; -// -// SellAllPrisonCommands sellall = SellAllPrisonCommands.get(); -// -// if ( sellall != null ) { -// results = sellall.getMultiplier( this ); -// } -// -// return results; -// } @Override public int compareTo( SpigotPlayer sPlayer) { return getUUID().compareTo( sPlayer.getUUID() ); -// return getName().compareTo( sPlayer.getName() ); } @Override public String toString() { - StringBuilder sb = new StringBuilder(); - - sb.append( "SpigotPlayer: " ).append( getName() ) - .append( " isOp=" ).append( isOp() ) - .append( " isOnline=" ).append( isOnline() ) - .append( " isPlayer=" ).append( isPlayer() ) - - .append( " hasBukkitPlayer=" ).append( bukkitPlayer != null ) - .append( " hasRankPlayer=" ).append( rankPlayer != null ) - ; - - return sb.toString(); + StringBuilder sb = new StringBuilder(); + + sb.append( "SpigotPlayer: " ).append( getName() ) + .append( " isOp=" ).append( isOp() ) + .append( " isOnline=" ).append( isOnline() ) + .append( " isPlayer=" ).append( isPlayer() ) + + .append( " hasBukkitPlayer=" ).append( bukkitPlayer != null ) + .append( " hasRankPlayer=" ).append( rankPlayer != null ) + ; + + return sb.toString(); } -// /** -// * This class is an adaptation of the NmsHelper class in the Rosetta library by Max Roncace. The -// * library is licensed under the New BSD License. See the {@link tech.mcprison.prison.localization} -// * package for the full license. -// * -// * @author Max Roncacé -// */ -// private static class NmsHelper { -// -// private static final boolean SUPPORT; -// -// private static final String PACKAGE_VERSION; -// -// private static final Method PLAYER_SPIGOT; -// private static final Method PLAYER$SPIGOT_GETLOCALE; -// private static final Method CRAFTPLAYER_GETHANDLE; -// -// private static final Field ENTITY_PLAYER_LOCALE; -// private static final Field LOCALE_LANGUAGE_WRAPPED_STRING; -// -// static { -// String[] array = Bukkit.getServer().getClass().getPackage().getName().split("\\."); -// PACKAGE_VERSION = array.length == 4 ? array[3] + "." : ""; -// -// Method player_spigot = null; -// Method player$spigot_getLocale = null; -// Method craftPlayer_getHandle = null; -// Field entityPlayer_locale = null; -// Field localeLanguage_wrappedString = null; -// try { -// -// Class craftPlayer = getCraftClass("entity.CraftPlayer"); -// -// // for reasons not known to me Paper decided to make EntityPlayer#locale null by default and have the -// // fallback defined in CraftPlayer$Spigot#getLocale. Rosetta will use that method if possible and fall -// // back to accessing the field directly. -// try { -// player_spigot = org.bukkit.entity.Player.class.getMethod("spigot"); -// Class player$spigot = Class.forName("org.bukkit.entity.Player$Spigot"); -// player$spigot_getLocale = player$spigot.getMethod("getLocale"); -// } catch (NoSuchMethodException ignored) { // we're non-Spigot or old -// } -// -// if (player$spigot_getLocale == null) { // fallback for non-Spigot software -// craftPlayer_getHandle = craftPlayer.getMethod("getHandle"); -// -// entityPlayer_locale = getNmsClass("EntityPlayer").getDeclaredField("locale"); -// entityPlayer_locale.setAccessible(true); -// if (entityPlayer_locale.getType().getSimpleName().equals("LocaleLanguage")) { -// // On versions prior to 1.6, the locale is stored as a LocaleLanguage object. -// // The actual locale string is wrapped within it. -// // On 1.5, it's stored in field "e". -// // On 1.3 and 1.4, it's stored in field "d". -// try { // try for 1.5 -// localeLanguage_wrappedString = -// entityPlayer_locale.getType().getDeclaredField("e"); -// } catch (NoSuchFieldException ex) { // we're pre-1.5 -// localeLanguage_wrappedString = -// entityPlayer_locale.getType().getDeclaredField("d"); -// } -// } -// } -// } -// catch ( ClassNotFoundException ex ) { -// Output.get().logInfo( -// "Cannot initialize NMS components - ClassNotFoundException - " + -// "NMS is not functional - " + ex.getMessage() ); -// -// } -// catch (NoSuchFieldException | NoSuchMethodException ex) { -// Output.get().logInfo( -// "Cannot initialize NMS components - per-player localization disabled. - " + ex.getMessage()); -// } -// PLAYER_SPIGOT = player_spigot; -// PLAYER$SPIGOT_GETLOCALE = player$spigot_getLocale; -// CRAFTPLAYER_GETHANDLE = craftPlayer_getHandle; -// ENTITY_PLAYER_LOCALE = entityPlayer_locale; -// LOCALE_LANGUAGE_WRAPPED_STRING = localeLanguage_wrappedString; -// SUPPORT = CRAFTPLAYER_GETHANDLE != null; -// } -// -// private static boolean hasSupport() { -// return SUPPORT; -// } -// -// private static String getLocale(org.bukkit.entity.Player player) -// throws IllegalAccessException, InvocationTargetException, ClassNotFoundException { -// if (PLAYER$SPIGOT_GETLOCALE != null) { -// return (String) PLAYER$SPIGOT_GETLOCALE.invoke(PLAYER_SPIGOT.invoke(player)); -// } -// -// Object entityPlayer = CRAFTPLAYER_GETHANDLE.invoke(player); -// Object locale = ENTITY_PLAYER_LOCALE.get(entityPlayer); -// if (LOCALE_LANGUAGE_WRAPPED_STRING != null) { -// return (String) LOCALE_LANGUAGE_WRAPPED_STRING.get(locale); -// } else { -// return (String) locale; -// } -// } -// -// private static Class getCraftClass(String className) throws ClassNotFoundException { -// return Class.forName("org.bukkit.craftbukkit." + PACKAGE_VERSION + className); -// } -// -// private static Class getNmsClass(String className) throws ClassNotFoundException { -// return Class.forName("net.minecraft.server." + PACKAGE_VERSION + className); -// } -// -// } - -// @SuppressWarnings( "deprecation" ) -// public void printDebugInventoryInformationToConsole() { -// -// try { -// printDebugInfo( bukkitPlayer.getInventory().getContents(), "Inventory Contents"); -// } -// catch ( java.lang.NoSuchMethodError | Exception e ) { -// // Ignore: Not supported with that version of spigot: -// } -// -// try { -// printDebugInfo( bukkitPlayer.getInventory().getExtraContents(), "Inventory Extra Contents"); -// } -// catch ( java.lang.NoSuchMethodError | Exception e ) { -// // Ignore: Not supported with that version of spigot: -// } -// -// try { -// printDebugInfo( bukkitPlayer.getInventory().getArmorContents(), "Inventory Armor Contents"); -// } -// catch ( java.lang.NoSuchMethodError | Exception e ) { -// // Ignore: Not supported with that version of spigot: -// } -// try { -// printDebugInfo( bukkitPlayer.getInventory().getStorageContents(), "Inventory Storage Contents"); -// } -// catch ( java.lang.NoSuchMethodError | Exception e ) { -// // Ignore: Not supported with that version of spigot: -// } -// -// try { -// printDebugInfo( bukkitPlayer.getInventory().getItemInHand(), "Inventory Item In Hand (pre 1.13)"); -// } -// catch ( java.lang.NoSuchMethodError | Exception e ) { -// // Ignore: Not supported with that version of spigot: -// } -// -// try { -// printDebugInfo( bukkitPlayer.getInventory().getItemInMainHand(), "Inventory Item in Main Hand"); -// } -// catch ( java.lang.NoSuchMethodError | Exception e ) { -// // Ignore: Not supported with that version of spigot: -// } -// -// try { -// printDebugInfo( bukkitPlayer.getInventory().getItemInOffHand(), "Inventory Item in Off Hand"); -// } -// catch ( java.lang.NoSuchMethodError | Exception e ) { -// // Ignore: Not supported with that version of spigot: -// } -// } - -// private void printDebugInfo( org.bukkit.inventory.ItemStack[] iStacks, String title ) { -// -// Output.get().logInfo( "&7%s:", title ); -// for ( int i = 0; i < iStacks.length; i++ ) { -// org.bukkit.inventory.ItemStack iStack = iStacks[i]; -// -// if ( iStack != null ) { -// -// ItemStack pItemStack = SpigotUtil.bukkitItemStackToPrison(iStack); -// -// Output.get().logInfo( " i=%d &3%s &3%d &a[&3%s&a]", -// i, iStack.getType().name(), iStack.getAmount(), -// (pItemStack == null ? "" : -// (pItemStack.getDisplayName() == null ? "" : -// pItemStack.getDisplayName())) ); -// } -// } -// } - -// private void printDebugInfo( org.bukkit.inventory.ItemStack iStack, String title ) { -// -// Output.get().logInfo( "&7%s:", title ); -// if ( iStack != null ) { -// -// Output.get().logInfo( " &3%s &3%d", -// iStack.getType().name(), iStack.getAmount() ); -// } -// } - public void giveExp( int xp ) { if ( getWrapper() != null ) { @@ -860,8 +543,6 @@ public void setActionBar( String actionBar ) { if ( getWrapper() != null) { PlayerMessagingTask.submitTask( getWrapper(), MessageType.actionBar, actionBar ); -// SpigotCompatibility.getInstance() -// .sendActionBar( getWrapper(), actionBar ); } } @@ -920,7 +601,6 @@ public boolean addBalance( String currency, double amount ) { if ( currencyEcon != null ) { results = currencyEcon.addBalance( this, amount, currency ); -// addCachedRankPlayerBalance( currency, amount ); } } return results; @@ -947,20 +627,6 @@ public boolean enableFlying( Mine mine, float flightSpeed ) { return enabled; } -// public Mine getEffectsMine() { -// Mine effectsMine = null; -// -// if ( lastEffectsMine != null ) { -// -// if ( !lastEffectsMine.isInMineExact( getLocation() ) ) { -// lastEffectsMine = null; -// -// // cancel all effects for player -// } -// effectsMine = lastEffectsMine; -// } -// return effectsMine; -// } public boolean isFlying() { boolean flying = false; @@ -994,13 +660,7 @@ public boolean isMinecraftStatisticsEnabled() { @Override public void incrementMinecraftStatsMineBlock( Player player, String blockName, int quantity) { -// Statistic.BREAK_ITEM; -// Statistic.DROP_COUNT; -// Statistic.MINE_BLOCK; -// Statistic.PICKUP; - XMaterial xMat = XMaterial.matchXMaterial( blockName ).orElse( null ); -// XMaterial xMat = SpigotCompatibility.getInstance().getXMaterial( block ); if ( xMat != null ) { Material mat = xMat.parseMaterial(); @@ -1012,12 +672,6 @@ public void incrementMinecraftStatsMineBlock( Player player, String blockName, i } } -// Statistic.MINE_BLOCK; -// player.setStatistic(null, count); -// player.incrementStatistic(null, null); -// player.incrementStatistic(null, null, count); -// player.statistic - } @Override @@ -1076,9 +730,6 @@ public boolean isInventoryFull() { * * @return */ -// public boolean isAutoSellEnabled() { -// return isAutoSellEnabled( null ); -// } public boolean isAutoSellEnabled( StringBuilder debugInfo ) { boolean results = false; @@ -1089,8 +740,6 @@ public boolean isAutoSellEnabled( StringBuilder debugInfo ) { if ( SellAllUtil.get().isAutoSellPerUserToggleable ) { debugInfo.append( "(&7sellallEnabled:userToggleable&3)" ); -// boolean isAutoSellPerUserToggleable = SellAllUtil.get().isAutoSellPerUserToggleable; - boolean isPlayerAutoSellTurnedOn = SellAllUtil.get().isSellallPlayerUserToggleEnabled( getWrapper() ); @@ -1136,22 +785,6 @@ public boolean isAutoSellEnabled( StringBuilder debugInfo ) { return results; } - -// /** -// *

    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( StringBuilder debugInfo ) { -// return isAutoSellByPermEnabled( isAutoSellEnabled( debugInfo ), debugInfo ); -// } /** *

    This will check to see if the player has the perms enabled @@ -1181,8 +814,8 @@ private boolean isAutoSellByPermEnabledAutoFeatures( StringBuilder debugInfo ) { !"false".equalsIgnoreCase( perm ) ) { debugInfo.append( "(&7autosellAutoFeaturesByPerm&3: " ) - .append( Output.get().getColorCodeWarning() ) - ; + .append( Output.get().getColorCodeWarning() ) + ; if ( isOp() ) { debugInfo.append( diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotPlayerUtil.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotPlayerUtil.java index 5fb7637ad..1fb291529 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotPlayerUtil.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotPlayerUtil.java @@ -365,12 +365,6 @@ private int getEnchantment( String enchant ) { } } -// for ( Enchantment e : Enchantment.values() ) { -// if (e.getKey().getKey().equalsIgnoreCase( enchant ) ) { -// enchantment = e; -// break; -// } -// } if ( enchantment != null ) { @@ -425,36 +419,6 @@ public int getItemInHandEnchantmentLuck() { } -// public String getEnchantments() { -// StringBuilder sb = new StringBuilder(); -// -// SpigotItemStack itemStack = getItemInHand(); -// -// if ( itemStack != null && itemStack.getBukkitStack() != null) { -// try { -// -// Set keys = itemStack.getBukkitStack().getEnchantments().keySet(); -// -// for ( Enchantment key : keys ) { -// Integer value = itemStack.getBukkitStack().getEnchantments().get( key ); -// -// if ( value != null ) { -// if ( sb.length() > 0 ) { -// sb.append( ", " ); -// } -// sb.append( key.getName() ).append( ": " ).append( value ); -// key.getItemTarget().toString() -// } -// } -// -// } -// catch ( NullPointerException e ) { -// // Ignore. This happens when a TokeEnchanted tool is used when TE is not installed anymore. -// // It throws this exception: Caused by: java.lang.NullPointerException: null key in entry: null=5 -// } -// } -// } - public String getItemInHandLore() { StringBuilder sb = new StringBuilder(); @@ -482,6 +446,4 @@ public void setSpigotPlayer( SpigotPlayer spigotPlayer ) { this.spigotPlayer = spigotPlayer; } - - } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotWorld.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotWorld.java index db23cf30f..2da03d031 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotWorld.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotWorld.java @@ -82,14 +82,14 @@ public SpigotWorld(org.bukkit.World bukkitWorld) { @Override public List getEntities() { - List results = new ArrayList<>(); - - for (org.bukkit.entity.Entity bukkitEnitity : getWrapper().getEntities() ) { - - results.add( new SpigotEntity( bukkitEnitity) ); + List results = new ArrayList<>(); + + for (org.bukkit.entity.Entity bukkitEnitity : getWrapper().getEntities() ) { + + results.add( new SpigotEntity( bukkitEnitity) ); } - return results; + return results; } /** @@ -99,20 +99,20 @@ public List getEntities() { * @return */ public List getEntities( EntityType eType ) { - List results = new ArrayList<>(); - - SpigotEntityType seType = eType == null ? null : (SpigotEntityType) eType; - - for (org.bukkit.entity.Entity bukkitEnitity : getWrapper().getEntities() ) { - - if ( seType == null || - seType.getxEType() == XEntityType.of(bukkitEnitity) ) { - - results.add( new SpigotEntity( bukkitEnitity )); - } - } - - return results; + List results = new ArrayList<>(); + + SpigotEntityType seType = eType == null ? null : (SpigotEntityType) eType; + + for (org.bukkit.entity.Entity bukkitEnitity : getWrapper().getEntities() ) { + + if ( seType == null || + seType.getxEType() == XEntityType.of(bukkitEnitity) ) { + + results.add( new SpigotEntity( bukkitEnitity )); + } + } + + return results; } /** @@ -128,42 +128,37 @@ public List getEntities( EntityType eType ) { @Override public Block getBlockAt( Location location, boolean containsCustomBlocks ) { - if ( getBlockAtLocation == null ) { - getBlockAtLocation = new SpigotBlockGetAtLocation(); - } - - return getBlockAtLocation.getBlockAt(location, containsCustomBlocks, this); + if ( getBlockAtLocation == null ) { + getBlockAtLocation = new SpigotBlockGetAtLocation(); + } + + return getBlockAtLocation.getBlockAt(location, containsCustomBlocks, this); } public Block getBlockAt( Location location ) { - return getBlockAt( location, false ); + return getBlockAt( location, false ); } -// public SpigotBlock getSpigotBlockAt(Location location) { -// return new SpigotBlock( -// bukkitWorld.getBlockAt(SpigotUtil.prisonLocationToBukkit(location))); -// } - public org.bukkit.Location getBukkitLocation(Location location) { - return SpigotUtil.prisonLocationToBukkit(location); + return SpigotUtil.prisonLocationToBukkit(location); } public org.bukkit.inventory.ItemStack getBukkitItemStack( ItemStack itemStack ) { - SpigotItemStack sItemStack = (SpigotItemStack) itemStack; - - return sItemStack.getBukkitStack(); + SpigotItemStack sItemStack = (SpigotItemStack) itemStack; + + return sItemStack.getBukkitStack(); } @Override public void setBlock( PrisonBlock block, int x, int y, int z ) { - Location loc = new Location( this, x, y, z ); - org.bukkit.block.Block bukkitBlock = - bukkitWorld.getBlockAt(SpigotUtil.prisonLocationToBukkit(loc)); - - SpigotCompatibility.getInstance().updateSpigotBlock( block, bukkitBlock ); + Location loc = new Location( this, x, y, z ); + org.bukkit.block.Block bukkitBlock = + bukkitWorld.getBlockAt(SpigotUtil.prisonLocationToBukkit(loc)); + + SpigotCompatibility.getInstance().updateSpigotBlock( block, bukkitBlock ); } @@ -209,59 +204,6 @@ public void setBlocksSynchronously( List tBlocks, MineRes } -// public String getBlockSignature( Location location ) { -// String results = null; -// -// if ( getWrapper() != null ) { -// -// SpigotBlock block = (SpigotBlock) getBlockAt( location ); -// -// StringBuilder sb = new StringBuilder(); -// sb.append( block.getWrapper().getType().name() ) -// .append( ":" ) -//// .append( location.toWorldCoordinates() ) -//// .append( "::" ) -// .append( block.getWrapper().getBlockData() ); -// -// results = sb.toString(); -// } -// -// return results; -// } - -// public void getTestBlock() { -// -// PrisonNBTUtil nbtUtil = new PrisonNBTUtil(); -// -// NBTItem nbtItemStack = nbtUtil.getNBT( bstack ); -// -// nbtItemStack. -// } - -// public void setBlockFromString( String blockString, Location location ) { -// -// String[] parts = blockString.split("::"); -// String blockNameFormal = parts[0]; -// String worldCoordinates = parts[1]; -// String blockData = parts[2]; -// -// Location targetLocation = location; -// if ( targetLocation == null ) { -// targetLocation = Location.decodeWorldCoordinates(worldCoordinates); -// } -// -// SpigotBlock block = (SpigotBlock) getBlockAt( targetLocation ); -// -// Prison.get().getPlatform().getPrisonBlock(blockNameFormal); -//// block.setType(Material.getMaterial(parts[0])); -// -// BlockData targetBlockData = -// SpigotPrison.getInstance().getServer().createBlockData( blockData ); -// -// block.getWrapper().setBlockData( targetBlockData ); -// -// } - public org.bukkit.World getWrapper() { return bukkitWorld; @@ -306,9 +248,6 @@ public org.bukkit.entity.ArmorStand spawnBukkitArmorStand( Location location ) { Location spawnPoint = new Location( location ); spawnPoint.setY(maxHight); -// Entity e = spawnEntity( spawnPoint, SpigotEntityType.ENTITY_TYPE_ARMOR_STAND ); -// SpigotEntity sEntity = (SpigotEntity) e; - org.bukkit.entity.Entity bEntity = spawnBukkitEntity( spawnPoint, SpigotEntityType.ENTITY_TYPE_ARMOR_STAND ); org.bukkit.entity.ArmorStand armorStand = (org.bukkit.entity.ArmorStand) bEntity; @@ -316,12 +255,6 @@ public org.bukkit.entity.ArmorStand spawnBukkitArmorStand( Location location ) { armorStand.teleport( new SpigotLocation( location ).getBukkitLocation() ); -// SpigotArmorStand sArmorStand = new SpigotArmorStand( armorStand ); - -// sArmorStand.teleport(location); - -// testArmorStandPlacement( spawnPoint ); - return armorStand; } @@ -401,22 +334,9 @@ public ArmorStand spawnArmorStand( Location location, String itemType, as.getHelmet(); as.setHelmet(bItemStack); -// String msg = "SpigotWorld.spawnArmorStand: itemInHand: " + -// ( as.getItemInHand() == null ? "null" : as.getItemInHand().toString()) + -// " hasArmms: " + as.hasArms() + -// " itemStack( " + -// (bItemStack == null ? "null" : -// bItemStack.toString() + " " + bItemStack.getAmount()) + ") " + -// " name: " + (customName == null ? "noCustomName" : customName); -// -// Output.get().logInfo( msg ); - -// as.teleport( SpigotLocation.getBukkitLocation(location) ); - // wrap in a SpigotArmorStand: SpigotArmorStand sas = new SpigotArmorStand( as ); - //sas.teleport( location ); return sas; } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotArmorStand.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotArmorStand.java index 2fe6cd813..a07e090a4 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotArmorStand.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotArmorStand.java @@ -23,16 +23,6 @@ public SpigotArmorStand( org.bukkit.entity.ArmorStand bArmorStand ) { this.bArmorStand = bArmorStand; } -// public static ArmorStand spawn( tech.mcprison.prison.util.Location location ) { -// tech.mcprison.prison.internal.Entity e = location.spawnEntity( SpigotEntityType.ENTITY_TYPE_ARMOR_STAND ); -// SpigotEntity sEntity = (SpigotEntity) e; -// -// org.bukkit.entity.ArmorStand armorStand = (org.bukkit.entity.ArmorStand) sEntity.getBukkitEntity(); -// SpigotArmorStand sArmorStand = new SpigotArmorStand( armorStand ); -// -// return sArmorStand; -// } - public SpigotArmorStand(Entity entity) { this( (org.bukkit.entity.ArmorStand) ((SpigotEntity) entity).getBukkitEntity() ); @@ -43,58 +33,6 @@ public SpigotArmorStand(Entity entity) { } } -// /** -// * Sets visibility:false, arms:true, basePlate:false, canPickupItems:false, -// * removeWhenFar:false, gravity:false, and itemInHand. -// */ -// @Override -// public void setupArmorStand( ItemStack item ) { -// -// if ( item != null ) { -// -// setVisible( false ); -// -// setArms( true ); -// setBasePlate( false ); -// setCanPickupItems( false ); -// -// setItemInHand( item ); -// -// setRemoveWhenFarAway(false); -// -// if ( new BluesSemanticVersionComparator().compareMCVersionTo( "1.9.0" ) >= 0 ) { -// -// // setGravity is invalid for spigot 1.8.8: -// setGravity( false ); -// } -// } -// } - -// @Override -// public void setupArmorStand( String itemType ) { -// SpigotItemStack item = null; -// -// XMaterial xBomb = XMaterial.matchXMaterial( itemType ).orElse( null ); -// -// if ( xBomb != null ) { -// try { -// -// // Create the spigot/bukkit ItemStack: -// org.bukkit.inventory.ItemStack bItemStack = xBomb.parseItem(); -// -// if ( sItemStack != null ) { -// -// item = new SpigotItemStack( bItemStack ); -// } -// } -// catch (PrisonItemStackNotSupportedRuntimeException e) { -// // Ignore -// } -// } -// -// setupArmorStand( item ); -// } - @Override public boolean isVisible() { return bArmorStand.isVisible(); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotEntity.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotEntity.java index 95f9b052c..3f3b931f8 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotEntity.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/entity/SpigotEntity.java @@ -104,7 +104,6 @@ public int getMaxFireTicks() { * @return */ public List getNearbyEntities( int r, EntityType eType ) { -// Location loc = getLocation(); List bEntities = getBukkitEntity() .getNearbyEntities( r * 2, r * 2, r * 2 ); @@ -280,15 +279,6 @@ public org.bukkit.entity.Entity getBukkitEntity() { return bukkitEntity; } - -// @Override -// public String getName() { -// -// return bukkitEntity != null ? -// bukkitEntity.getName() : -// rankplayer; -// } - @Override public boolean isPlayer() { @@ -296,14 +286,4 @@ public boolean isPlayer() { } - -// @Override -// public boolean doesSupportColors() { -// return false; -// } - - - - - } 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 2d6586434..cc8440ef9 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 @@ -92,7 +92,6 @@ public class ListenersPrisonManager private final MessagesConfig messages = SpigotPrison.getInstance().getMessagesConfig(); boolean guiNotEnabled = !getBoolean(config.getString("prison-gui-enabled")); -// private Optional ladder; // makes no sense... not thread safe. public ChatMode mode; @@ -238,7 +237,6 @@ public void onPlayerInteractEvent(PlayerInteractEvent e){ // signs, so check if the material name contains "sign": String matName = clickedBlock.name().toLowerCase(); if ( matName.contains("sign")) { -// if (clickedBlock == Material.SIGN || clickedBlock == Material.WALL_SIGN) { // Get the player Player p = e.getPlayer(); @@ -265,7 +263,6 @@ public void onPlayerInteractEvent(PlayerInteractEvent e){ if (sellAllUtil.isSellAllSignPermissionToUseEnabled && !p.hasPermission(permissionUseSign)) { Output.get().sendWarn(new SpigotPlayer(p), messages.getString(MessagesConfig.StringID.spigot_message_missing_permission) -// + " [&3" + permissionUseSign + "&7]" ); return; } @@ -426,7 +423,7 @@ public void onClick(InventoryClickEvent e){ // If a GUI Tools Page action, then process the request and just exit: else if ( SpigotGUIMenuTools.getInstance().processGUIPage( p, title, e ) ) { - return; + return; } @@ -570,41 +567,7 @@ else if ( SpigotGUIMenuTools.getInstance().processGUIPage( p, title, e ) ) { break; } -// // Check the inventory title and do the actions. -// case "PrisonManager -> AutoFeatures": { -// -// // Call the method -// autoFeaturesGUI(e, p, parts); -// -// break; -// } - -// // Check the title and do the actions. -// case "AutoFeatures -> AutoPickup": { -// -// // Call the method -// autoPickupGUI(e, p, parts); -// -// break; -// } - -// // Check the title and do the actions. -// case "AutoFeatures -> AutoSmelt": { -// -// // Call the method -// autoSmeltGUI(e, p, parts); -// -// break; -// } - -// // Check the title and do the actions. -// case "AutoFeatures -> AutoBlock": { -// -// // Call the method -// autoBlockGUI(e, p, parts); -// -// break; -// } + // Check the title and do the actions. case "SellAll -> Blocks": { @@ -744,60 +707,8 @@ else if ( SpigotGUIMenuTools.getInstance().processGUIPage( p, title, e ) ) { } - - -// private boolean processGUIPage( Player p, String title, InventoryClickEvent e ) { -// boolean isPageAction = false; -// -// ItemStack currentItem = e.getCurrentItem(); -// if ( currentItem != null && currentItem.hasItemMeta() ) { -// -// ItemMeta meta = currentItem.getItemMeta(); -// -// if ( meta.hasLore() ) { -// -// String command = null; -// -// List lores = meta.getLore(); -// -// for ( String lore : lores ) { -// -// if ( lore.contains( SpigotGUIMenuTools.GUI_MENU_TOOLS_PAGE ) ) { -// isPageAction = true; -// } -// if ( lore.contains( SpigotGUIMenuTools.GUI_MENU_TOOLS_COMMAND ) ) { -// command = Text.stripColor( lore ).replace( SpigotGUIMenuTools.GUI_MENU_TOOLS_COMMAND, "" ).trim(); -// } -// } -// -// if ( isPageAction && command != null ) { -// Bukkit.dispatchCommand(p, -// Prison.get().getCommandHandler().findRegisteredCommand( command )); -// -// } -// } -// -// } -// -// return isPageAction; -// } private void sellAllPlayerGUI(InventoryClickEvent e, Player p, String[] parts) { -// if (parts[0].equalsIgnoreCase("Prior")){ -// -// SellAllPlayerGUI gui = new SellAllPlayerGUI(p, Integer.parseInt(parts[1])); -// gui.open(); -// -// e.setCancelled(true); -// return; -// } else if (parts[0].equalsIgnoreCase("Next")){ -// -// SellAllPlayerGUI gui = new SellAllPlayerGUI(p, Integer.parseInt(parts[1])); -// gui.open(); -// -// e.setCancelled(true); -// return; -// } p.closeInventory(); e.setCancelled(true); @@ -1401,7 +1312,7 @@ private void mineBlockPercentage(InventoryClickEvent e, Player p, String[] parts String positionStr = ( parts.length > 5 ? parts[5] : "0" ); int position = 0; try { - position = Integer.parseInt( positionStr ); + position = Integer.parseInt( positionStr ); } catch(NumberFormatException ignored) {} @@ -1620,22 +1531,6 @@ private void sellAllItemValue(InventoryClickEvent e, Player p, String[] parts) { private void sellAllAdminBlocksGUI(InventoryClickEvent e, Player p, String[] parts) { -// if (parts[0].equalsIgnoreCase("Prior")){ -// -// SellAllAdminBlocksGUI gui = new SellAllAdminBlocksGUI(p, Integer.parseInt(parts[1])); -// gui.open(); -// -// e.setCancelled(true); -// return; -// } else if (parts[0].equalsIgnoreCase("Next")){ -// -// SellAllAdminBlocksGUI gui = new SellAllAdminBlocksGUI(p, Integer.parseInt(parts[1])); -// gui.open(); -// -// e.setCancelled(true); -// return; -// } - if (e.isRightClick()){ String registeredCmd = Prison.get().getCommandHandler().findRegisteredCommand( "sellall delete" ); @@ -1666,19 +1561,6 @@ private void prisonManagerGUI(InventoryClickEvent e, Player p, String buttonName break; } -// // Check the Item display name and do open the right GUI. -// case "AutoManager": { -// -// // Check if the autofeatures config isn't null. -// if(SpigotGUIComponents.afConfig() != null) { -// SpigotAutoFeaturesGUI gui = new SpigotAutoFeaturesGUI(p); -// gui.open(); -// } else { -// Output.get().sendWarn(new SpigotPlayer(p), "Can't find an autofeatures config, maybe they're disabled."); -// } -// break; -// } - // Check the Item display name and do open the right GUI. case "Mines": { SpigotMinesGUI gui = new SpigotMinesGUI(p, 1, "gui admin mines", "gui"); @@ -1713,21 +1595,12 @@ private void laddersGUI(InventoryClickEvent e, Player p, String buttonNameMain, return; } -// if (parts[0].equalsIgnoreCase("Next") || parts[0].equalsIgnoreCase("Prior")){ -// -// // Open a new SpigotLadders GUI page. -// SpigotLaddersGUI gui = new SpigotLaddersGUI(p, Integer.parseInt(parts[1]), 1); -// p.closeInventory(); -// gui.open(); -// return; -// } - // Get the ladder by the name of the button got before. RankLadder rLadder = PrisonRanks.getInstance().getLadderManager().getLadder(buttonNameMain); if ( rLadder == null ) { - // Do nothing since it's not a valid ladder name: - return; + // Do nothing since it's not a valid ladder name: + return; } // ladder = rLadder; @@ -1735,22 +1608,22 @@ private void laddersGUI(InventoryClickEvent e, Player p, String buttonNameMain, // to be sure's a right click. if (e.isShiftClick() && e.isRightClick()) { - if ( rLadder.getRanks().size() > 0 ) { - - SpigotPlayer sPlayer = new SpigotPlayer( p ); - sPlayer.setActionBar( "Cannot delete a non-empty ladder" ); - } - else { - - // Execute the command - 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" ); - gui.open(); - return; - } + if ( rLadder.getRanks().size() > 0 ) { + + SpigotPlayer sPlayer = new SpigotPlayer( p ); + sPlayer.setActionBar( "Cannot delete a non-empty ladder" ); + } + else { + + // Execute the command + 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" ); + gui.open(); + return; + } } @@ -1765,15 +1638,6 @@ private void laddersGUI(InventoryClickEvent e, Player p, String buttonNameMain, private void ranksGUI(InventoryClickEvent e, Player p, String buttonNameMain, String[] parts) { -// if (parts[0].equalsIgnoreCase("Next") || parts[0].equalsIgnoreCase("Prior")){ -// -// // Open a new SpigotLadders GUI page. -// SpigotRanksGUI gui = new SpigotRanksGUI(p, ladder, Integer.parseInt(parts[1])); -// p.closeInventory(); -// gui.open(); -// return; -// } - if ( !PrisonRanks.getInstance().isEnabled() ) { Output.get().sendWarn(new SpigotPlayer(p), "&cPrison ranks are not enabled."); @@ -1833,53 +1697,32 @@ private void playerPrestigesGUI(InventoryClickEvent e, Player p, String buttonNa private void prestigeConfirmationGUI(InventoryClickEvent e, Player p, String buttonNameMain) { - String playerName = p.getName(); + String playerName = p.getName(); // Check the button name and do the actions. if (buttonNameMain.equalsIgnoreCase("Confirm: Prestige")){ - Output.get().logDebug( DebugTarget.rankup, "rankup: /gui prestigeConfirm: Prestige has been Confirmed. " - + " calling: '/prestige " + playerName + " confirm'" ); - - // Execute the command. - String registeredCmd = Prison.get().getCommandHandler().findRegisteredCommand( "prestige" ); - - String command = registeredCmd + " " + playerName + " confirm"; - + Output.get().logDebug( DebugTarget.rankup, "rankup: /gui prestigeConfirm: Prestige has been Confirmed. " + + " calling: '/prestige " + playerName + " confirm'" ); + + // Execute the command. + String registeredCmd = Prison.get().getCommandHandler().findRegisteredCommand( "prestige" ); + + String command = registeredCmd + " " + playerName + " confirm"; + Bukkit.dispatchCommand(p, command ); } else if (buttonNameMain.equalsIgnoreCase("Cancel: Don't Prestige")){ - Output.get().logDebug( DebugTarget.rankup, "rankup: /gui prestigeConfirm: Prestige has been canceled " + - "for " + playerName + "." ); + Output.get().logDebug( DebugTarget.rankup, "rankup: /gui prestigeConfirm: Prestige has been canceled " + + "for " + playerName + "." ); - // Send a message to the player. -// Output.get().sendInfo(new SpigotPlayer(p), "&cCancelled"); } // Close the inventory. p.closeInventory(); -// // Check the button name and do the actions. -// if (buttonNameMain.equalsIgnoreCase("Confirm: Prestige")){ -// Output.get().logDebug( DebugTarget.rankup, "rankup: GUI: 'Confirm: Prestige' calling: '/rankup prestiges'" ); -// -// // Execute the command. -// String registeredCmd = Prison.get().getCommandHandler().findRegisteredCommand( "rankup" ); -// -// Bukkit.dispatchCommand(p, registeredCmd + " prestiges"); -// // Close the inventory. -// p.closeInventory(); -// } else if (buttonNameMain.equalsIgnoreCase("Cancel: Don't Prestige")){ -// Output.get().logDebug( DebugTarget.rankup, "rankup: GUI/: 'Cancel: Don't Prestige' sendInfo: 'cancelled'" ); -// -// // Send a message to the player. -// Output.get().sendInfo(new SpigotPlayer(p), "&cCancelled"); -// // Close the inventory. -// p.closeInventory(); -// } -// // Cancel the event. e.setCancelled(true); } @@ -1957,7 +1800,7 @@ private void rankManagerGUI(InventoryClickEvent e, Player p, String[] parts) { private void playerRanksGUI(InventoryClickEvent e, Player p, String buttonNameMain) { // Check the buttonName and do the actions. - String message = Text.stripColor( messages.getString(MessagesConfig.StringID.spigot_gui_lore_rankup) ); + String message = Text.stripColor( messages.getString(MessagesConfig.StringID.spigot_gui_lore_rankup) ); if (buttonNameMain.equals(SpigotPrison.format( message ))){ Bukkit.dispatchCommand(p, Prison.get().getCommandHandler().findRegisteredCommand( @@ -2096,15 +1939,6 @@ private void rankPriceGUI(InventoryClickEvent e, Player p, String[] parts) { private void minesGUI(InventoryClickEvent e, Player p, String buttonNameMain, String[] parts) { -// if (parts[0].equalsIgnoreCase("Next") || parts[0].equalsIgnoreCase("Prior")){ -// -// // Open a new SpigotLadders GUI page. -// SpigotMinesGUI gui = new SpigotMinesGUI(p, Integer.parseInt(parts[1])); -// p.closeInventory(); -// gui.open(); -// return; -// } - // Variables. PrisonMines pMines = PrisonMines.getInstance(); Mine m = pMines.getMine(buttonNameMain); @@ -2655,277 +2489,7 @@ private void radiusGUI(InventoryClickEvent e, Player p, String[] parts) { } } -// private void autoFeaturesGUI(InventoryClickEvent e, Player p, String[] parts) { -// -// // Get the config -// AutoFeaturesFileConfig afConfig = AutoFeaturesWrapper.getInstance().getAutoFeaturesConfig(); -// -// // Output finally the buttonname and the mode explicit out of the array -// String buttonName = parts[0]; -// String mode = parts[1]; -// -// boolean enabled = mode.equalsIgnoreCase("Enabled"); -// -// // Check the clickType and do the actions -// if ( enabled && e.isRightClick() && e.isShiftClick() || -// !enabled && e.isRightClick()){ -// -// if (buttonName.equalsIgnoreCase("Full-Inventory-Sound")){ -// afConfig.setFeature( AutoFeatures.playSoundIfInventoryIsFull, !enabled ); -// saveConfigAutoFeatures(e, p); -// } -// -// if (buttonName.equalsIgnoreCase("Full-Inventory-ActionBar")){ -// afConfig.setFeature(AutoFeatures.actionBarMessageIfInventoryIsFull, !enabled); -// saveConfigAutoFeatures(e,p); -// } -// -// if (buttonName.equalsIgnoreCase("All")){ -// afConfig.setFeature(AutoFeatures.isAutoManagerEnabled, !enabled); -// saveConfigAutoFeatures(e,p); -// } -// -// } -// -// // Check the clickType and do the actions -// if (enabled && e.isRightClick() && e.isShiftClick() || !enabled && e.isRightClick() || enabled && e.isLeftClick()){ -// if (buttonName.equalsIgnoreCase("AutoPickup")){ -// if (e.isLeftClick()){ -// SpigotAutoPickupGUI gui = new SpigotAutoPickupGUI(p); -// gui.open(); -// return; -// } -// afConfig.setFeature(AutoFeatures.autoPickupEnabled, !enabled); -// saveConfigAutoFeatures(e,p); -// } -// -// if (buttonName.equalsIgnoreCase("AutoSmelt")){ -// if (e.isLeftClick()){ -// SpigotAutoSmeltGUI gui = new SpigotAutoSmeltGUI(p); -// gui.open(); -// return; -// } -// afConfig.setFeature(AutoFeatures.autoSmeltEnabled, !enabled); -// saveConfigAutoFeatures(e,p); -// } -// -// if (buttonName.equalsIgnoreCase("AutoBlock")){ -// if (e.isLeftClick()){ -// SpigotAutoBlockGUI gui = new SpigotAutoBlockGUI(p); -// gui.open(); -// return; -// } -// afConfig.setFeature(AutoFeatures.autoBlockEnabled, !enabled); -// saveConfigAutoFeatures(e,p); -// } -// } -// } - -// private void autoPickupGUI(InventoryClickEvent e, Player p, String[] parts) { -// -// // Get the config -// AutoFeaturesFileConfig afConfig = AutoFeaturesWrapper.getInstance().getAutoFeaturesConfig(); -// -// // Output finally the buttonname and the mode explicit out of the array -// String buttonname = parts[0]; -// String mode = parts[1]; -// -// boolean enabled = mode.equalsIgnoreCase("Enabled"); -// -// // Check the click and do the actions, also the buttonName -// if ( enabled && e.isRightClick() && e.isShiftClick() || -// !enabled && e.isRightClick() ){ -// -// switch (buttonname){ -// case "All_Blocks":{ -// afConfig.setFeature( AutoFeatures.pickupAllBlocks, !enabled ); -// saveConfigPickup(e, p); -// break; -// } -// case "Cobblestone":{ -// afConfig.setFeature(AutoFeatures.pickupCobbleStone, !enabled); -// saveConfigPickup(e,p); -// break; -// } -// case "Gold_Ore":{ -// afConfig.setFeature( AutoFeatures.pickupGoldOre, !enabled ); -// saveConfigPickup(e, p); -// break; -// } -// case "Iron_Ore":{ -// afConfig.setFeature( AutoFeatures.pickupIronOre, !enabled ); -// saveConfigPickup(e, p); -// break; -// } -// case "Coal_Ore":{ -// afConfig.setFeature( AutoFeatures.pickupCoalOre, !enabled ); -// saveConfigPickup(e, p); -// break; -// } -// case "Diamond_Ore":{ -// afConfig.setFeature( AutoFeatures.pickupDiamondOre, !enabled ); -// saveConfigPickup(e, p); -// break; -// } -// case "Redstone_Ore":{ -// afConfig.setFeature( AutoFeatures.pickupRedStoneOre, !enabled ); -// saveConfigPickup(e, p); -// break; -// } -// case "Emerald_Ore":{ -// afConfig.setFeature( AutoFeatures.pickupEmeraldOre, !enabled ); -// saveConfigPickup(e, p); -// break; -// } -// case "Quartz_Ore":{ -// afConfig.setFeature( AutoFeatures.pickupQuartzOre, !enabled ); -// saveConfigPickup(e, p); -// break; -// } -// case "Lapis_Ore":{ -// afConfig.setFeature( AutoFeatures.pickupLapisOre, !enabled ); -// saveConfigPickup(e, p); -// break; -// } -// case "Snow_Ball":{ -// afConfig.setFeature( AutoFeatures.pickupSnowBall, !enabled ); -// saveConfigPickup(e, p); -// break; -// } -// case "Glowstone_Dust":{ -// afConfig.setFeature( AutoFeatures.pickupGlowstoneDust, !enabled ); -// saveConfigPickup(e, p); -// break; -// } -// default:{ -// break; -// } -// -// } -// } -// } -// -// private void autoSmeltGUI(InventoryClickEvent e, Player p, String[] parts) { -// -// // Get the config -// AutoFeaturesFileConfig afConfig = AutoFeaturesWrapper.getInstance().getAutoFeaturesConfig(); -// -// // Output finally the buttonname and the mode explicit out of the array -// String buttonname = parts[0]; -// String mode = parts[1]; -// -// boolean enabled = mode.equalsIgnoreCase("Enabled"); -// -// // Check the clickType and do the actions -// if ( enabled && e.isRightClick() && e.isShiftClick() || -// !enabled && e.isRightClick()){ -// -// switch (buttonname){ -// case "Gold_Ore":{ -// afConfig.setFeature( AutoFeatures.smeltGoldOre, !enabled ); -// saveConfigSmelt(e, p); -// break; -// } -// case "Iron_Ore":{ -// afConfig.setFeature( AutoFeatures.smeltIronOre, !enabled ); -// saveConfigSmelt(e, p); -// break; -// } -// case "All_Ores":{ -// afConfig.setFeature( AutoFeatures.smeltAllBlocks, !enabled ); -// saveConfigSmelt(e, p); -// break; -// } -// default:{ -// break; -// } -// } -// } -// } -// -// private void autoBlockGUI(InventoryClickEvent e, Player p, String[] parts) { -// -// // Get the config -// AutoFeaturesFileConfig afConfig = AutoFeaturesWrapper.getInstance().getAutoFeaturesConfig(); -// -// // Output finally the buttonname and the mode explicit out of the array -// String buttonname = parts[0]; -// String mode = parts[1]; -// -// boolean enabled = mode.equalsIgnoreCase("Enabled"); -// -// // Check the clickType and do the actions -// if ( enabled && e.isRightClick() && e.isShiftClick() || -// !enabled && e.isRightClick()){ -// -// switch (buttonname){ -// case "Gold_Block":{ -// afConfig.setFeature( AutoFeatures.blockGoldBlock, !enabled ); -// saveConfigBlock(e, p); -// break; -// } -// case "Iron_Block":{ -// afConfig.setFeature( AutoFeatures.blockIronBlock, !enabled ); -// saveConfigBlock(e, p); -// break; -// } -// case "Coal_Block":{ -// afConfig.setFeature( AutoFeatures.blockCoalBlock, !enabled ); -// saveConfigBlock(e, p); -// break; -// } -// case "Diamond_Block":{ -// afConfig.setFeature( AutoFeatures.blockDiamondBlock, !enabled ); -// saveConfigBlock(e, p); -// break; -// } -// case "Redstone_Block":{ -// afConfig.setFeature( AutoFeatures.blockRedstoneBlock, !enabled ); -// saveConfigBlock(e, p); -// break; -// } -// case "Emerald_Block":{ -// afConfig.setFeature( AutoFeatures.blockEmeraldBlock, !enabled ); -// saveConfigBlock(e, p); -// break; -// } -// case "Quartz_Block":{ -// afConfig.setFeature( AutoFeatures.blockQuartzBlock, !enabled ); -// saveConfigBlock(e, p); -// break; -// } -// case "Prismarine_Block":{ -// afConfig.setFeature( AutoFeatures.blockPrismarineBlock, !enabled ); -// saveConfigBlock(e, p); -// break; -// } -// case "Lapis_Block":{ -// afConfig.setFeature( AutoFeatures.blockLapisBlock, !enabled ); -// saveConfigBlock(e, p); -// break; -// } -// case "Snow_Block":{ -// afConfig.setFeature( AutoFeatures.blockSnowBlock, !enabled ); -// saveConfigBlock(e, p); -// break; -// } -// case "Glowstone_Block":{ -// afConfig.setFeature( AutoFeatures.blockGlowstone, !enabled ); -// saveConfigBlock(e, p); -// break; -// } -// case "All_Blocks":{ -// afConfig.setFeature( AutoFeatures.blockAllBlocks, !enabled ); -// saveConfigBlock(e, p); -// break; -// } -// default:{ -// break; -// } -// } -// } -// -// } + private void modeAction(AsyncPlayerChatEvent e, Player p, String message) { @@ -2955,7 +2519,7 @@ private void modeAction(AsyncPlayerChatEvent e, Player p, String message) { private void sellAllCurrencyChat(AsyncPlayerChatEvent e, Player p, String message) { // Check message and do the action - String registeredCmd = Prison.get().getCommandHandler().findRegisteredCommand( "sellall set currency" ); + String registeredCmd = Prison.get().getCommandHandler().findRegisteredCommand( "sellall set currency" ); if (message.equalsIgnoreCase("cancel")){ Output.get().sendInfo(new SpigotPlayer(p), messages.getString(MessagesConfig.StringID.spigot_message_event_cancelled)); } else if (message.equalsIgnoreCase("default")){ @@ -2970,21 +2534,6 @@ private void sellAllCurrencyChat(AsyncPlayerChatEvent e, Player p, String messag isChatEventActive = false; } -// private void prestigeAction(AsyncPlayerChatEvent e, Player p, String message) { -// -// // Check the chat message and do the actions -// if (message.equalsIgnoreCase("cancel")) { -// Output.get().sendInfo(new SpigotPlayer(p), messages.getString(MessagesConfig.StringID.spigot_message_prestiges_cancelled)); -// } else if (message.equalsIgnoreCase("confirm")) { -// Bukkit.getScheduler().runTask(SpigotPrison.getInstance(), () -> Bukkit.getServer().dispatchCommand(p, "rankup prestiges")); -// } else { -// Output.get().sendInfo(new SpigotPlayer(p), messages.getString(MessagesConfig.StringID.spigot_message_prestiges_cancelled_wrong_keyword)); -// } -// // Cancel the event -// e.setCancelled(true); -// // Set the event to false, because it got deactivated -// isChatEventActive = false; -// } private void mineAction(AsyncPlayerChatEvent e, Player p, String message) { @@ -3011,45 +2560,4 @@ private void rankAction(AsyncPlayerChatEvent e, Player p, String message) { isChatEventActive = false; } -// /** -// * Save the auto features, and then cancel the event and close the inventory. -// * -// * @param e -// * @param player -// */ -// private boolean saveAutoFeatures( InventoryClickEvent e, Player player ) { -// boolean success = AutoFeaturesWrapper.getInstance().getAutoFeaturesConfig().saveConf(); -// e.setCancelled(true); -// player.closeInventory(); -// return success; -// } -// -// -// private boolean saveConfigBlock(InventoryClickEvent e, Player p) { -// boolean success = saveAutoFeatures( e, p ); -// SpigotAutoBlockGUI gui = new SpigotAutoBlockGUI(p); -// gui.open(); -// return success; -// } -// -// private boolean saveConfigSmelt(InventoryClickEvent e, Player p) { -// boolean success = saveAutoFeatures( e, p ); -// SpigotAutoSmeltGUI gui = new SpigotAutoSmeltGUI(p); -// gui.open(); -// return success; -// } -// -// private boolean saveConfigPickup(InventoryClickEvent e, Player p) { -// boolean success = saveAutoFeatures( e, p ); -// SpigotAutoPickupGUI gui = new SpigotAutoPickupGUI(p); -// gui.open(); -// return success; -// } -// -// private boolean saveConfigAutoFeatures(InventoryClickEvent e, Player p) { -// boolean success = saveAutoFeatures( e, p ); -// SpigotAutoFeaturesGUI gui = new SpigotAutoFeaturesGUI(p); -// gui.open(); -// return success; -// } } 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 4ddb6322c..a9f7eb41c 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 @@ -49,8 +49,6 @@ public class SpigotGUIMenuTools private boolean useDisabledButtons; -// private String loreCommand; - private SpigotGUIMenuTools() { super(); @@ -66,8 +64,6 @@ private SpigotGUIMenuTools() { this.menuGoBack = XMaterial.BARRIER; -// this.menuStateOff1 = XMaterial.BLACK_STAINED_GLASS_PANE; -// this.menuStateOff2 = XMaterial.GRAY_STAINED_GLASS_PANE; } @@ -155,7 +151,6 @@ public GUIMenuPageData( int totalArraySize, int currentPage, String commandToRun posStart = (page - 1) * pageSize; posEnd = posStart + pageSize; -// posEnd = posStart + pageSize - 1; if ( posEnd > totalArraySize ) { posEnd = totalArraySize; @@ -305,29 +300,6 @@ public void setButtons( List