From 38f14be1657a63fcce94d09672990fd3aa216bc6 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 22 Nov 2023 18:39:25 -0500 Subject: [PATCH 01/92] doc updates... --- docs/prison_changelog_v3.3.0-alpha.16.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/prison_changelog_v3.3.0-alpha.16.md b/docs/prison_changelog_v3.3.0-alpha.16.md index 9df2c680e..69d13a70e 100644 --- a/docs/prison_changelog_v3.3.0-alpha.16.md +++ b/docs/prison_changelog_v3.3.0-alpha.16.md @@ -23,13 +23,13 @@ The following is a highlight of changes for the alpha.16 release since the alpha * Auto Features: Many updates and enhancements. -* Sellall: Many updates and enhancements from API to GUI and autofeatures integration. +* Sellall: Many updates and enhancements from API to GUI and auto features integration. - Streamlined to work with prison's custom blocks instead of just XMaterial items. - New functionality to improve managing what's been sold, or just getting their value. Extended a lot of this new functionality to the prison APIs. - Added many new default items - Changed all of the commands under sellall to better organize like commands in to sub-commands - Rank multipliers now works for all ranks, not just prestiges. New commands to reset all multipliers for ladders (which is great if you have a few thousand prestige ranks). - - If blocks could not be sold through auto features autosell, it will generate debug mmessages so it's easier to track why blocks are not being sold. + - If blocks could not be sold through auto features autosell, it will generate debug messages so it's easier to track why blocks are not being sold. - Able to disable the "nothing to sell" message so it stops spamming the player. - For different server configs, where there are issues that prevent autosell from being used, such as other plugins placing blocks in the player's inventory, you can now force a sellall after the block break event is finished being processed. - Sellall Multipliers - Many new features and commands. Explore with `/sellall multiplier` and use the keyword `help` on each command for more details. The multiplier list can use different column widths to better support thousands of prestige ranks. @@ -64,7 +64,7 @@ The following is a highlight of changes for the alpha.16 release since the alpha * Mines - - - Mine tracer now has an option to 'clear' the whole mine, mark jjust the 'corners', or the standard full tracer. + - Mine tracer now has an option to 'clear' the whole mine, mark just the 'corners', or the standard full tracer. - Found and fixed a sync task that was a possible cause of jitters. This helps when the server is under a heavy load. - Added a `/mtop` command. `/mines top` which teleports a player to the top of the mine they are in. From db5b101ff22358e67467f48283ea912e1e9341c1 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 22 Nov 2023 18:43:29 -0500 Subject: [PATCH 02/92] Localizable: Bug fix. Blanks were being removed by the use of trim() so the spaces were being ignored. --- docs/changelog_v3.3.x.md | 5 ++++- .../java/tech/mcprison/prison/localization/Localizable.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 0c3a4a436..9fbeeb474 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.16 2023-11-18 +# 3.3.0-alpha.16 2023-11-22 + + +* **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** 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 cd0504a27..dbc54a53a 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 @@ -248,7 +248,7 @@ private String localizeIn(String locale, boolean recursive, String... fallbacks) // If the entry has been marked with "*none*" or an empty String then return an empty String: if ( LocaleManager.IGNORE_TEXT_NO_MESSAGE_INTENDED.equalsIgnoreCase(message) || - message != null && message.trim().length() == 0 ) { + message != null && message.length() == 0 ) { return ""; } From 83e6b45521e60a9eeece9433260e57b397ef662f Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 24 Nov 2023 03:46:13 -0500 Subject: [PATCH 03/92] Mines: Added support for '*all*' for mine names for the following mine commands: resetDelay, resetThreshhold, notificationPerm, and accessPermission --- docs/changelog_v3.3.x.md | 5 +- .../prison/mines/commands/MinesCommands.java | 368 +++++++++++------- 2 files changed, 232 insertions(+), 141 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 9fbeeb474..1e60c031a 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.16 2023-11-22 +# 3.3.0-alpha.16 2023-11-24 + + +* **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.** 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 35512e819..ce8fa6b90 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 @@ -2019,19 +2019,21 @@ else if ( "*default*".equalsIgnoreCase( time ) ) { @Command(identifier = "mines set resetDelay", permissions = "mines.set", description = "Set a mine's delay before reset when it reaches zero blocks.") public void zeroBlockResetDelayCommand(CommandSender sender, - @Arg(name = "mineName", description = "The name of the mine to edit.") String mineName, + @Arg(name = "mineName", + description = "The name of the mine to edit. Use '*all' for all mines.") String mineName, @Arg(name = "time/DISABLE", description = "Delay in seconds before resetting when the mine reaches " + "zero blocks, or DISABLE." ) String time ) { - if (performCheckMineExists(sender, mineName)) { - setLastMineReferenced(mineName); + if ( "*all*".equalsIgnoreCase( mineName ) || + performCheckMineExists(sender, mineName)) { + + double resetTime = + time != null && "disable".equalsIgnoreCase( time ) ? -1.0d : + 0.0d; try { - double resetTime = - time != null && "disable".equalsIgnoreCase( time ) ? -1.0d : - 0.0d; if ( resetTime != -1.0d && time != null && time.trim().length() > 0 ) { resetTime = Double.parseDouble( time ); @@ -2044,45 +2046,64 @@ public void zeroBlockResetDelayCommand(CommandSender sender, resetTime = 0.0d; } } - - 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; -// } - - m.setZeroBlockResetDelaySec( resetTime ); - - pMines.getMineManager().saveMine( m ); - - DecimalFormat dFmt = Prison.get().getDecimalFormat("#,##0.00"); - // User's message: - if ( m.isZeroBlockResetDisabled() ) { - Output.get().sendInfo( sender, "&7Mine &b%s Zero Block Reset Delay: &cDISABLED", - m.getTag(), dFmt.format( resetTime ) ); - - } else { - Output.get().sendInfo( sender, "&7Mine &b%s Zero Block Reset Delay: &b%s &7sec", - m.getTag(), dFmt.format( resetTime ) ); - - } - - // Server Log message: - Player player = getPlayer( sender ); - Output.get().logInfo( "&7Mine &b%s Zero Block Reset Delay: &b%s &7set it to &b%s &7sec", - (player == null ? "console" : player.getDisplayName()), - m, dFmt.format( resetTime ) ); } 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; +// } + + } } + + private void minesSetResetDelay(CommandSender sender, double resetTime, PrisonMines pMines, Mine m) { + m.setZeroBlockResetDelaySec( resetTime ); + + pMines.getMineManager().saveMine( m ); + + DecimalFormat dFmt = Prison.get().getDecimalFormat("#,##0.00"); + // User's message: + if ( m.isZeroBlockResetDisabled() ) { + Output.get().sendInfo( sender, "&7Mine &b%s Zero Block Reset Delay: &cDISABLED", + m.getTag(), dFmt.format( resetTime ) ); + + } else { + Output.get().sendInfo( sender, "&7Mine &b%s Zero Block Reset Delay: &b%s &7sec", + m.getTag(), dFmt.format( resetTime ) ); + + } + + // Server Log message: + Player player = getPlayer( sender ); + Output.get().logInfo( "&7Mine &b%s Zero Block Reset Delay: &b%s &7set it to &b%s &7sec", + (player == null ? "console" : player.getDisplayName()), + m, dFmt.format( resetTime ) ); + } @@ -2099,71 +2120,89 @@ public void zeroBlockResetDelayCommand(CommandSender sender, description = "Triggers a mine reset once this threshold is crossed and the remaining " + "block percentage is less than or equal to this value") public void resetThresholdPercentCommand(CommandSender sender, - @Arg(name = "mineName", description = "The name of the mine to edit.") String mineName, + @Arg(name = "mineName", + description = "The name of the mine to edit. Use '*all*' to apply to all mmines.") + String mineName, @Arg(name = "percent", description = "Threshold percent to trigger a reset.(0 is disabled)", def = "0" ) String percent ) { - if (performCheckMineExists(sender, mineName)) { - setLastMineReferenced(mineName); + if ( "*all*".equalsIgnoreCase( mineName ) || + performCheckMineExists(sender, mineName)) { PrisonMines pMines = PrisonMines.getInstance(); - Mine m = pMines.getMine(mineName); + + if ( !"*all*".equalsIgnoreCase( mineName ) ) { + setLastMineReferenced(mineName); + + Mine m = pMines.getMine(mineName); + + changeMinePercentThreshhold(sender, percent, pMines, m); + } + else { + for ( Mine m : pMines.getMines() ) { + + changeMinePercentThreshhold(sender, percent, pMines, m); + } + } // if ( !m.isEnabled() ) { // sender.sendMessage( "&cMine is disabled&7. Use &a/mines info &7for possible cause." ); // return; // } - double thresholdPercent = 0.0d; - - try { - thresholdPercent = Double.parseDouble( percent ); - if ( thresholdPercent < 0.0d ) { - thresholdPercent = 0.0d; - } else if ( thresholdPercent > 100.0d ) { - thresholdPercent = 100.0d; - } - } - catch ( NumberFormatException e1 ) { - Output.get().sendWarn( sender,"&7Invalid percentage. Not a number. " + - "Was &b%s&7.", (percent == null ? "&c-blank-" : percent) ); - return; - } - - - if ( thresholdPercent == m.getResetThresholdPercent() ) { - String msg = "The Reset Threshold Percent was not changed."; - Output.get().sendInfo( sender, msg ); - return; - } - - m.setResetThresholdPercent( thresholdPercent ); - - pMines.getMineManager().saveMine( m ); - - double blocks = m.isVirtual() ? 0 : - m.getBounds().getTotalBlockCount() * - m.getResetThresholdPercent() / 100.0d; - - DecimalFormat dFmt = Prison.get().getDecimalFormatInt(); - DecimalFormat fFmt = Prison.get().getDecimalFormat("#,##0.00"); - - // User's message: - String message = String.format( "&7The Reset Threshold Percent for mine &b%s&7 was set to &b%s&7, " + - "which is about &b%s &7blocks.", - m.getTag(), - fFmt.format( m.getResetThresholdPercent() ), - dFmt.format( blocks ) ); - Output.get().sendInfo( sender, message ); - - // Server Log message: - Player player = getPlayer( sender ); - Output.get().logInfo( "%s :: Changed by: %s", message, - (player == null ? "console" : player.getDisplayName()) ); } } + private void changeMinePercentThreshhold(CommandSender sender, String percent, PrisonMines pMines, Mine m) { + double thresholdPercent = 0.0d; + + try { + thresholdPercent = Double.parseDouble( percent ); + if ( thresholdPercent < 0.0d ) { + thresholdPercent = 0.0d; + } else if ( thresholdPercent > 100.0d ) { + thresholdPercent = 100.0d; + } + } + catch ( NumberFormatException e1 ) { + Output.get().sendWarn( sender,"&7Invalid percentage. Not a number. " + + "Was &b%s&7.", (percent == null ? "&c-blank-" : percent) ); + return; + } + + + if ( thresholdPercent == m.getResetThresholdPercent() ) { + String msg = "The Reset Threshold Percent was not changed."; + Output.get().sendInfo( sender, msg ); + return; + } + + m.setResetThresholdPercent( thresholdPercent ); + + pMines.getMineManager().saveMine( m ); + + double blocks = m.isVirtual() ? 0 : + m.getBounds().getTotalBlockCount() * + m.getResetThresholdPercent() / 100.0d; + + DecimalFormat dFmt = Prison.get().getDecimalFormatInt(); + DecimalFormat fFmt = Prison.get().getDecimalFormat("#,##0.00"); + + // User's message: + String message = String.format( "&7The Reset Threshold Percent for mine &b%s&7 was set to &b%s&7, " + + "which is about &b%s &7blocks.", + m.getTag(), + fFmt.format( m.getResetThresholdPercent() ), + dFmt.format( blocks ) ); + Output.get().sendInfo( sender, message ); + + // Server Log message: + Player player = getPlayer( sender ); + Output.get().logInfo( "%s :: Changed by: %s", message, + (player == null ? "console" : player.getDisplayName()) ); + } + @Command(identifier = "mines set notification", permissions = "mines.set", @@ -2282,49 +2321,67 @@ private boolean changeMineNotification( CommandSender sender, String mineName, "can be combined with the other notification settings.", altPermissions = "mines.notification.[mineName]") public void setNotificationPermissionCommand(CommandSender sender, - @Arg(name = "mineName", description = "The name of the mine to edit.") String mineName, + @Arg(name = "mineName", + description = "The name of the mine to edit. Use '*all*' for all mines.") String mineName, @Arg(name = "action", def="enable", description = "Enable or disable the permission filtering: [enable, disable]") String action ) { - if (performCheckMineExists(sender, mineName)) { - setLastMineReferenced(mineName); + + 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(); - Mine m = pMines.getMine(mineName); - + + 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; // } - if ( !action.equalsIgnoreCase( "enable" ) && !action.equalsIgnoreCase( "disable" )) { - sender.sendMessage( "&7Invalid value for action: [enable, disable]" ); - return; - } - - if ( action.equalsIgnoreCase( "enable" ) && !m.isUseNotificationPermission() ) { - sender.sendMessage( - String.format( "&7Notification Permission filter has been enabled. Using permission %s", - m.getMineNotificationPermissionName() ) ); - m.setUseNotificationPermission( true ); - pMines.getMineManager().saveMine( m ); - } - else if ( action.equalsIgnoreCase( "disable" ) && m.isUseNotificationPermission() ) { - sender.sendMessage( "&7Notification Permission filter has been disabled." ); - m.setUseNotificationPermission( false ); - pMines.getMineManager().saveMine( m ); - } - else { - - sender.sendMessage( "&7Notification Permission filter was not changed. Canceling." ); - } } } + private void minesSetNotificationPerm(CommandSender sender, String action, PrisonMines pMines, Mine m) { + if ( action.equalsIgnoreCase( "enable" ) && !m.isUseNotificationPermission() ) { + sender.sendMessage( + String.format( "&7Notification Permission filter has been enabled. Using permission %s", + m.getMineNotificationPermissionName() ) ); + m.setUseNotificationPermission( true ); + pMines.getMineManager().saveMine( m ); + } + else if ( action.equalsIgnoreCase( "disable" ) && m.isUseNotificationPermission() ) { + sender.sendMessage( "&7Notification Permission filter has been disabled." ); + m.setUseNotificationPermission( false ); + pMines.getMineManager().saveMine( m ); + } + else { + + sender.sendMessage( "&7Notification Permission filter was not changed. Canceling." ); + } + } + @@ -2340,48 +2397,79 @@ else if ( action.equalsIgnoreCase( "disable" ) && m.isUseNotificationPermission( "This command can only use permissions. Permission groups will not work. ", altPermissions = "mines.notification.[mineName]") public void setMinePermissionCommand(CommandSender sender, - @Arg(name = "mineName", description = "The name of the mine to add a permission to.") String mineName, - @Arg(name = "permission", def="enable", description = "Permission. Suggested: `mines.`: [none]") + @Arg(name = "mineName", + description = "The name of the mine to add a permission to. Use '*all*' for all mines.") String mineName, + @Arg(name = "permission", def="enable", + description = "Permission. Can use a placeholder '{mmine}' to dynamically apply " + + "the mine name when using '*all*'. Example using placeholder: 'mines.{mine}' " + + "Suggested: 'mines.': [none]") String permission ) { - if (performCheckMineExists(sender, mineName)) { - setLastMineReferenced(mineName); - + if ( "*all*".equalsIgnoreCase( mineName ) || + performCheckMineExists(sender, mineName)) { + PrisonMines pMines = PrisonMines.getInstance(); - Mine m = pMines.getMine(mineName); - - if ( m.isMineAccessByRank() ) { - sender.sendMessage( "&3The use of Mine Access Permissions is not needed and is disabled " + - "because Mine Access is controlled by Ranks." ); + if ( "*all*".equalsIgnoreCase( mineName ) ) { - return; + setLastMineReferenced(mineName); + Mine m = pMines.getMine(mineName); + + minesSetAccessPermission(sender, permission, pMines, m); + } + else { + for ( Mine m : pMines.getMines() ) { + + minesSetAccessPermission(sender, permission, pMines, m); + } } - - - if ( permission == null || permission.equalsIgnoreCase( "none" ) ) { - m.setAccessPermission( null ); - pMines.getMineManager().saveMine( m ); - sender.sendMessage( - String.format( "&7The Mine Access Permission has been disabled for %s.", - m.getName() )); - } - else { - m.setAccessPermission( permission ); - pMines.getMineManager().saveMine( m ); - - sender.sendMessage( - String.format( "&7The Mine Access Permission has been enable for %s and " + - "has a value of [%s].", m.getName(), permission )); - } + } } + private void minesSetAccessPermission(CommandSender sender, + String permission, PrisonMines pMines, Mine m) { + + permission = permission + .replace( "{mine}", m.getName() ) + .replace( "{mineName}", m.getName() ) + .replace( "{minename}", m.getName() ) + .replace( "", m.getName() ) + .replace( "", m.getName() ) + .replace( "", m.getName() ); + + if ( m.isMineAccessByRank() ) { + + sender.sendMessage( "&3The use of Mine Access Permissions is not needed and is disabled " + + "because Mine Access is controlled by Ranks." ); + + return; + } + + + if ( permission == null || permission.equalsIgnoreCase( "none" ) ) { + m.setAccessPermission( null ); + pMines.getMineManager().saveMine( m ); + + sender.sendMessage( + String.format( "&7The Mine Access Permission has been disabled for %s.", + m.getName() )); + } + else { + m.setAccessPermission( permission ); + pMines.getMineManager().saveMine( m ); + + sender.sendMessage( + String.format( "&7The Mine Access Permission has been enable for %s and " + + "has a value of [%s].", m.getName(), permission )); + } + } + @Command(identifier = "mines set rank", permissions = "mines.set", description = "Links a mine to a rank or removes the rank.") From dc73e59ae7088e6ec6f946c261e0f7df22348833 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 26 Nov 2023 19:51:14 -0500 Subject: [PATCH 04/92] Docs - allow players to place blocks in mines and allow them to break them --- docs/prison_docs_101_setting_up_mines.md | 26 +++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/docs/prison_docs_101_setting_up_mines.md b/docs/prison_docs_101_setting_up_mines.md index 15594f294..0aed9edb2 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: 2023-01-13* +*Documented updated: 2023-11-26*
@@ -353,6 +353,30 @@ Example of a mine reset including a sealantern. Notice that there is still 19.5 +
+ + +# Allowing Players to place blocks in mines + +Normally, players are not allowed to place blocks in mines. Prison will identify that the blocks placed by players were not placed by Prison during the last mine reset, and therefore will fast-fail and ignore that block. + +By default though, prison will cancel the event, no matter what setting you have for general events, such as cancel events, or canceling the drops. + +To override this behavior, so players can actually break blocks within mines, you need to change the autoFeaturesConfig.yml file's setting: + +`ifBlockIsAlreadyCountedThenCancelEvent: false` + +You can then reload the settings without restarting the server: + `/prison reload autoFeatures` + + +By default, this setting is set to "true" so older installs of Prison will not break when they upgrade to a version that supports this feature. + +Just because prison is now ignoring the block break, this does not mean the player can break the block. This technically means that prison is doing nothing with it; not even canceling the event. So other plugins will be allowed to process the block. For example, WorldGuard may reject the player's access and prevent block breakage, and then WorldGuard will cancel the event. + +To address this issue, you would need to setup a WorldGuard region covering the whole mine, and then allowing the players to break blocks within the mine. This will allow the block to pass through to other plugins. If not other plugin does anything with the block, then bukkit will break the block normally at the end of handling the BlockBreakEvent. + +
From 7e00583e12a83924884c38f150e24039f3e69dc8 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 30 Nov 2023 12:35:37 -0500 Subject: [PATCH 05/92] 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}` --- docs/changelog_v3.3.x.md | 7 ++++- .../spigot/gui/mine/SpigotPlayerMinesGUI.java | 10 +++++-- .../gui/rank/SpigotPlayerPrestigesGUI.java | 30 ++++++++++++++++++- .../spigot/gui/rank/SpigotPlayerRanksGUI.java | 10 ++++++- 4 files changed, 52 insertions(+), 5 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 1e60c031a..864017797 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.16 2023-11-24 +# 3.3.0-alpha.16 2023-11-30 + + +* **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** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotPlayerMinesGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotPlayerMinesGUI.java index 951149bb1..b3e48b3b2 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotPlayerMinesGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotPlayerMinesGUI.java @@ -101,7 +101,7 @@ public void open() { PrisonGUI gui = new PrisonGUI(p, guiPageData.getDimension(), guiConfig.getString("Options.Titles.PlayerMinesGUI")); - String guiItemNameDefault = guiConfig.getString( "Options.Mines.GuiItemNameDefault" ); + String guiItemNameDefaultSetting = guiConfig.getString( "Options.Mines.GuiItemNameDefault" ); // Load the generic mine LORE that would be displayed first: @@ -144,7 +144,13 @@ public void open() { // Bug: Cannot safely use Material due to variants prior to bukkit v1.13: // Material material; - + + String guiItemNameDefault = + (guiItemNameDefaultSetting == null || guiItemNameDefaultSetting.trim().length() == 0) ? + m.getName() : + guiItemNameDefaultSetting + .replace( "{mineName}", m.getName() ) + .replace( "{mineTag}", m.getTag() ); // Get Mine Name. First use 'guiItemName' if not null, then try to use 'guiItemNameDefault' // if not null, and then use the mine's tag, or if that's null, then use the name: diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotPlayerPrestigesGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotPlayerPrestigesGUI.java index 0ea8b0a8e..ddce1a2f1 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotPlayerPrestigesGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotPlayerPrestigesGUI.java @@ -146,6 +146,11 @@ public void open() { PrisonGUI gui = new PrisonGUI(getPlayer(), guiPageData.getDimension(), guiConfig.getString("Options.Titles.PlayerPrestigesGUI")); + + String guiItemNameDefaultSetting = guiConfig.getString( "Options.Ranks.GuiItemNameDefault" ); + + + // dead code: // if ( ladder == null ){ // Output.get().sendWarn(new SpigotPlayer(player), messages.getString("Message.LadderPrestigesNotFound")); @@ -189,6 +194,26 @@ public void open() { for ( Rank rank : ranksDisplay ) { + + String guiItemNameDefault = + (guiItemNameDefaultSetting == null || guiItemNameDefaultSetting.trim().length() == 0) ? + rank.getName() : + guiItemNameDefaultSetting + .replace( "{rankName}", rank.getName() ); + + + String guiItemName = guiConfig.getString( "Options.Ranks.GuiItemNames." + rank.getName() ); + + + // Get Rank Name. First use 'guiItemName' if not null, then try to use 'guiItemNameDefault' + // if not null, and then use the rank's tag, or if that's null, then use the name: + String rankName = + guiItemName != null ? guiItemName : + guiItemNameDefault != null ? guiItemNameDefault : + rank.getTag() != null ? rank.getTag() : + rank.getName(); + + // hasAccess uses access by rank, and access by perm: boolean playerHasThisRank = getRankPlayer() != null && getRankPlayer().hasAccessToRank( rank ); @@ -218,7 +243,10 @@ public void open() { // playerHasThisRank = false; // } - Button itemrank = new Button(null, playerHasThisRank ? materialHas : materialHasNot, 1, ranksLore, rank.getTag()); + XMaterial hasRankMsg = playerHasThisRank ? materialHas : materialHasNot; + + Button itemrank = new Button( null, hasRankMsg, 1, ranksLore, rankName ); + if (!(playerHasThisRank)){ if (hackyCounterEnchant <= 0) { hackyCounterEnchant++; diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotPlayerRanksGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotPlayerRanksGUI.java index 7e489f599..a0c9b22e0 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotPlayerRanksGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotPlayerRanksGUI.java @@ -159,7 +159,7 @@ public void open() { - String guiItemNameDefault = guiConfig.getString( "Options.Ranks.GuiItemNameDefault" ); + String guiItemNameDefaultSetting = guiConfig.getString( "Options.Ranks.GuiItemNameDefault" ); // Not sure how you want to represent this: @@ -190,6 +190,14 @@ public void open() { for ( Rank rank : ranksDisplay ) { + + String guiItemNameDefault = + (guiItemNameDefaultSetting == null || guiItemNameDefaultSetting.trim().length() == 0) ? + rank.getName() : + guiItemNameDefaultSetting + .replace( "{rankName}", rank.getName() ) + .replace( "{rankTag}", rank.getTag() ); + String guiItemName = guiConfig.getString( "Options.Ranks.GuiItemNames." + rank.getName() ); // Get Rank Name. First use 'guiItemName' if not null, then try to use 'guiItemNameDefault' From a78e1d0193d65a9f9e7256ea8886107d79aba4e9 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 6 Dec 2023 02:38:15 -0500 Subject: [PATCH 06/92] 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. --- .../internal/block/PrisonBlockStatusData.java | 78 +++++++++++++++++++ .../mcprison/prison/mines/data/MineData.java | 13 +++- .../mines/data/MineLevelBlockListData.java | 43 ++++++++-- .../mcprison/prison/mines/data/MineReset.java | 23 +++--- 4 files changed, 137 insertions(+), 20 deletions(-) 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 8844ecc11..2f699fcba 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 @@ -1,6 +1,9 @@ package tech.mcprison.prison.internal.block; import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; import tech.mcprison.prison.Prison; import tech.mcprison.prison.internal.block.PrisonBlock.PrisonBlockType; @@ -37,6 +40,8 @@ public abstract class PrisonBlockStatusData { private boolean gravity = false; + private transient boolean includeInLayerCalculations; + public PrisonBlockStatusData( PrisonBlockType blockType, String blockName, double chance, long blockCountTotal ) { super(); @@ -65,6 +70,8 @@ public PrisonBlockStatusData( PrisonBlockType blockType, String blockName, doubl this.rangeBlockCountHighLimit = -1; this.gravity = checkGravityAffects( blockName ); + + this.includeInLayerCalculations = true; } @@ -507,4 +514,75 @@ public void setGravity( boolean gravity ) { this.gravity = gravity; } + + + public boolean isIncludeInLayerCalculations() { + return includeInLayerCalculations; + } + public void setIncludeInLayerCalculations(boolean includeInLayerCalculations) { + this.includeInLayerCalculations = includeInLayerCalculations; + } + + + /** + *

This is only used when calculating which blocks should be placed + * in each layer, one layer at a time. This would be used if a block is + * usable for a layer, but it has exceeded it's max constraint, so a + * value of 'false' would then prevent this block from being used, but + * will allow the stats to continue to collect the max usable range + * in which this block could be placed. + *

+ * + * @param targetBlocks + * @return + */ + public int getRandomBlockPositionInRangeUnmatched( + List targetBlocks) { + return getRandomBlockPositionInRange( targetBlocks, false ); + } + + public int getRandomBlockPositionInRangeMatched( + List targetBlocks) { + return getRandomBlockPositionInRange( targetBlocks, true ); + } + + /** + *

This function will select a block position from the + * targetBlocks list that is either of the same block type, or + * that is not equal to the same block type. This is to + * find valid blocks to either replace, or to add to the + * list without randomly trying to select a block to try. + *

+ * + * @param targetBlocks + * @param matched + * @return + */ + private int getRandomBlockPositionInRange( + List targetBlocks, + boolean matched) { + int position = -1; + + int rangeLow = getRangeBlockCountLowLimit(); + int rangeHigh = getRangeBlockCountHighLimit(); + + List choices = new ArrayList<>(); + + for ( int i = rangeLow; i < rangeHigh && i < targetBlocks.size(); i++ ) { + String bName = targetBlocks.get( i ).getPrisonBlock().getBlockName(); + + if ( matched == getBlockName().equals( bName ) ) { + choices.add( i ); + } + } + + if ( choices.size() > 0 ) { + int p = (int) (Math.random() * choices.size()); + + position = choices.get( p ); + } + + return position; + } + } 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 9fddfe96a..703fbe3e7 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 @@ -784,6 +784,7 @@ public void resetResetBlockCounts() { block.setRangeBlockCountHigh( -1 ); block.setRangeBlockCountLowLimit( -1 ); block.setRangeBlockCountHighLimit( -1 ); + block.setIncludeInLayerCalculations( true ); } for ( PrisonBlockStatusData block : getPrisonBlocks() ) { @@ -794,6 +795,7 @@ public void resetResetBlockCounts() { block.setRangeBlockCountHigh( -1 ); block.setRangeBlockCountLowLimit( -1 ); block.setRangeBlockCountHighLimit( -1 ); + block.setIncludeInLayerCalculations( true ); } // for ( PrisonBlockStatusData blockStats : getBlockStats().values() ) { @@ -811,10 +813,15 @@ public void resetResetBlockCounts() { */ public PrisonBlockStatusData incrementResetBlockCount( PrisonBlockStatusData statsBlock ) { - PrisonBlockStatusData sBlock = getBlockStats( statsBlock ); - if ( sBlock != null ) { + PrisonBlockStatusData sBlock = null; + + if ( statsBlock != null ) { + sBlock = getBlockStats( statsBlock ); - sBlock.incrementResetBlockCount(); + if ( sBlock != null ) { + + sBlock.incrementResetBlockCount(); + } } return sBlock; 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 ac7b6479c..35c7c78fe 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 @@ -47,13 +47,19 @@ private void initialize() { totalChance += pBlock.getChance(); // If the block has no constraints, or if the block is within the - // mine constraints, add it to our list: - if ( pBlock.getConstraintExcludeTopLayers() == 0 && + // mine constraints, add it to our list. + // Check to ensure that the max placement has not been exceeded and if + // it has, exclude from this level. Note that past levels may have + // placed more than max. + if ( + ( pBlock.getConstraintExcludeTopLayers() == 0 && pBlock.getConstraintExcludeBottomLayers() == 0 || pBlock.getConstraintExcludeTopLayers() <= currentMineLevel && (pBlock.getConstraintExcludeBottomLayers() == 0 || - pBlock.getConstraintExcludeBottomLayers() > currentMineLevel) ) { + pBlock.getConstraintExcludeBottomLayers() > currentMineLevel) ) + + ) { // Sum the selected blocks: selectedChance += pBlock.getChance(); @@ -65,8 +71,10 @@ private void initialize() { // If exclude top layers is enabled, then only try to set the // rangeBlockCountLowLimit once since we need the lowest possible // value. The initial value for getRangeBlockCountLowLimit is -1. - if ( pBlock.getRangeBlockCountLowLimit() <= 0 && - currentMineLevel > pBlock.getConstraintExcludeTopLayers() ) { + if ( pBlock.getRangeBlockCountLowLimit() == -1 && + (pBlock.getConstraintExcludeTopLayers() <= 0 || + currentMineLevel > pBlock.getConstraintExcludeTopLayers()) + ) { int targetBlockPosition = mine.getMineTargetPrisonBlocks().size(); pBlock.setRangeBlockCountLowLimit( targetBlockPosition ); @@ -81,8 +89,9 @@ private void initialize() { currentMineLevel > pBlock.getConstraintExcludeTopLayers() || pBlock.getConstraintExcludeTopLayers() == 0) && + (pBlock.getConstraintExcludeBottomLayers() == 0 || pBlock.getConstraintExcludeBottomLayers() > 0 && - pBlock.getConstraintExcludeBottomLayers() < currentMineLevel + pBlock.getConstraintExcludeBottomLayers() < currentMineLevel) ) { int targetBlockPosition = mine.getMineTargetPrisonBlocks().size(); @@ -129,8 +138,9 @@ public void checkSelectedBlockExcludeFromBottomLayers() { currentMineLevel > pBlock.getConstraintExcludeTopLayers() || pBlock.getConstraintExcludeTopLayers() == 0) && + (pBlock.getConstraintExcludeBottomLayers() == 0 || pBlock.getConstraintExcludeBottomLayers() > 0 && - pBlock.getConstraintExcludeBottomLayers() < currentMineLevel + pBlock.getConstraintExcludeBottomLayers() < currentMineLevel) ) { int targetBlockPosition = mine.getMineTargetPrisonBlocks().size(); @@ -152,7 +162,11 @@ public PrisonBlock randomlySelectPrisonBlock() for ( PrisonBlock block : selectedBlocks ) { - if ( chance <= block.getChance() ) { + // 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 + // prevent more of them from being added to the mine. + if ( block.isIncludeInLayerCalculations() && chance <= block.getChance() ) { // 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, @@ -165,6 +179,19 @@ public PrisonBlock randomlySelectPrisonBlock() } } + // If block reaches it's max amount, remove it from the block list. + // Note that the block has not been incremented yet, so add one to the placement count + if ( selected != null && + selected.getConstraintMax() > 0 && + (selected.getBlockPlacedCount() + 1) >= selected.getConstraintMax() ) { + + selected.setIncludeInLayerCalculations( false ); + +// selectedBlocks.remove(selected); + +// selectedChance -= selected.getChance(); + } + return selected; } 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 d397bfdc6..68e314919 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 @@ -1736,26 +1736,31 @@ private void constraintsApplyMin() { */ private void constraintsApplyMin( PrisonBlockStatusData block ) { - if ( block.getConstraintMin() > 0 ) { + + if ( block.getConstraintMin() > 0 && block.getBlockPlacedCount() < block.getConstraintMin() ) { + + int maxAttempts = (block.getConstraintMin() - block.getBlockPlacedCount()) + 3; - int maxAttempts = (block.getConstraintMin() - block.getBlockPlacedCount()) * 3; for ( int i = 0; i < maxAttempts && block.getBlockPlacedCount() < block.getConstraintMin(); i++ ) { // int maxSize = getMineTargetPrisonBlocks().size(); - int rangeLow = block.getRangeBlockCountLowLimit(); - int rangeHigh = block.getRangeBlockCountHighLimit(); -// int rangeLow = block.getRangeBlockCountLow(); -// int rangeHigh = block.getRangeBlockCountHigh(); + // 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; +// int rndPos = ((int) Math.round( Math.random() * (rangeHigh - rangeLow) )) + rangeLow; - if ( rndPos < getMineTargetPrisonBlocks().size() ) { + if ( blockPos > -1 && blockPos < getMineTargetPrisonBlocks().size() ) { - MineTargetPrisonBlock targetBlock = getMineTargetPrisonBlocks().get( rndPos ); + MineTargetPrisonBlock targetBlock = getMineTargetPrisonBlocks().get( blockPos ); if ( targetBlock != null && targetBlock.getPrisonBlock().getConstraintMin() == 0 && From 522bec614a7b711d69dfd516627071285abbe25a Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 6 Dec 2023 02:39:25 -0500 Subject: [PATCH 07/92] Upgrade XSeries to v9.7.0 from v9.4.0. --- docs/changelog_v3.3.x.md | 9 ++++++++- prison-spigot/build.gradle | 9 +++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 864017797..fe5b1a96e 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.16 2023-11-30 +# 3.3.0-alpha.16 2023-12-06 + + +* **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. diff --git a/prison-spigot/build.gradle b/prison-spigot/build.gradle index 1e33b8b42..6d4ab2f28 100644 --- a/prison-spigot/build.gradle +++ b/prison-spigot/build.gradle @@ -146,11 +146,11 @@ dependencies { // https://mvnrepository.com/artifact/me.lucko.luckperms/luckperms-api compileOnly 'me.lucko.luckperms:luckperms-api:4.4' - // jitpack.io: -// implementation 'com.github.cryptomorin:xseries:b95d195482' + // https://mvnrepository.com/artifact/com.github.cryptomorin/XSeries - implementation 'com.github.cryptomorin:XSeries:9.4.0' + implementation 'com.github.cryptomorin:XSeries:9.7.0' + //implementation 'com.github.cryptomorin:XSeries:9.4.0' //implementation 'com.github.cryptomorin:XSeries:9.2.0' @@ -265,7 +265,8 @@ shadowJar { //include(dependency('me.clip:placeholderapi:2.10.9')) // https://mvnrepository.com/artifact/com.github.cryptomorin/XSeries - include(dependency('com.github.cryptomorin:XSeries:9.4.0')) + include(dependency('com.github.cryptomorin:XSeries:9.7.0')) + //include(dependency('com.github.cryptomorin:XSeries:9.4.0')) //include(dependency('com.github.cryptomorin:XSeries:9.2.0')) //include(dependency('com.github.cryptomorin:XSeries:9.0.0')) //include(dependency('com.github.cryptomorin:XSeries:8.8.0')) From 82518336a401978891137e31ab8114ef70c87590 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 6 Dec 2023 02:40:02 -0500 Subject: [PATCH 08/92] Update a few comments... --- .../prison/spigot/block/OnBlockBreakEventCore.java | 7 +++++++ prison-spigot/src/main/resources/config.yml | 1 + 2 files changed, 8 insertions(+) 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 3017e4ec4..18409fcf7 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 @@ -420,6 +420,13 @@ protected boolean validateEvent( PrisonMinesBlockBreakEvent pmEvent ) pmEvent.setTargetBlock( targetBlock ); // NOTE: I have no idea why 25 blocks and less should be bypassed for validation: + // Perhaps its because small mines, with 25 or less blocks, just need to be + // processed as quickly as possible? Which could allow breakage even if it + // does not match? + // Later on, bypassMatchedBlocks is used for monitor events when the + // target block is AIR which may mean the block was already removed, so + // ignore the block in the event, and just process it if it was not + // already mined? boolean bypassMatchedBlocks = pmEvent.getMine().getBounds().getTotalBlockCount() <= 25; if ( bypassMatchedBlocks ) { pmEvent.setDebugColorCodeWarning(); diff --git a/prison-spigot/src/main/resources/config.yml b/prison-spigot/src/main/resources/config.yml index 4730ba395..1e253a222 100644 --- a/prison-spigot/src/main/resources/config.yml +++ b/prison-spigot/src/main/resources/config.yml @@ -328,6 +328,7 @@ prison-mines: - GoldMine - SampleMineName world-guard: + WARNING: WorldGuard support is not yet available. Coming soon. region-mine: enable: true name-prefix: prison_mine_ From 6c5a67bec9d7ccfd76aa8fbe4f7cecf496bb9211 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 10 Dec 2023 02:07:23 -0500 Subject: [PATCH 09/92] 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. --- docs/changelog_v3.3.x.md | 6 +- .../prison/mines/commands/MinesCommands.java | 100 +++++++++++++++++- 2 files changed, 103 insertions(+), 3 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index fe5b1a96e..1d8e508d5 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.16 2023-12-06 +# 3.3.0-alpha.16 2023-12-10 + + +* **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.** 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 ce8fa6b90..3f26327b0 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 @@ -3737,8 +3737,8 @@ private void generateBlockEventListing( Mine m, ChatDisplay display, boolean inc FancyMessage msgCommand = new FancyMessage( String.format( " &a'&7%s&a'", blockEvent.getCommand() ) ) //.command("/mines blockEvent remove " + mineName + " " + blockEvent.getCommand() ) - .tooltip("Event Commands - You cannot change a command directly, " + - "delete it and then re-add it."); + .suggest( "/mines blockEvent update " + m.getName() + " " + rowNumber + " " + blockEvent.getCommand() ) + .tooltip("BlockEvent Command - Click to Edit"); row.addFancy( msgCommand ); @@ -3863,6 +3863,102 @@ public void blockEventRemove(CommandSender sender, } + @Command(identifier = "mines blockEvent update", + description = "Updates a mine BlockEvent; must be ran in console, or click on blockevent " + + "number in game when listing each block list. Due to limitations on auto editing " + + "you need to follow the special instructions as presented. First run this command " + + "to get a list of block events and their corresponding numbers. ", + onlyPlayers = false, permissions = "mines.set") + public void blockEventUpdate(CommandSender sender, + @Arg(name = "mineName" ) String mineName, + @Arg(name = "row", def = "0") Integer row, + @Arg(name = "command", def = "") @Wildcard String command ) { + + if (!performCheckMineExists(sender, mineName)) { + return; + } + + setLastMineReferenced(mineName); + + PrisonMines pMines = PrisonMines.getInstance(); + Mine m = pMines.getMine(mineName); + + if ( row == null || row <= 0 ) { + + ChatDisplay display = new ChatDisplay("BlockEvent Commands for " + m.getTag()); + display.addText("&8Hover over values for more information and clickable actions."); + generateBlockEventListing( m, display, true ); + + display.addText( + "&7Please provide a valid row number greater than zero. " + + "Was row=[&b%d&7]", + (row == null ? "null" : row) ); + + display.send(sender); + + return; + } + + + if (m.getBlockEvents() == null || m.getBlockEvents().size() == 0) { + Output.get().sendInfo(sender, "The mine '%s' contains no BlockEvent commands.", m.getTag()); + 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; + } + + MineBlockEvent blockEvent = m.getBlockEvents().get( row - 1 ); + + + + if ( blockEvent != null ) { + + String msg1 = String.format( "Original: '%s'", + blockEvent.getCommand() ); + sender.sendMessage(msg1); + + + if ( command == null || command.trim().length() == 0 ) { + sender.sendMessage( + String.format("&7Please resubmit this command and copy and paste the above original blockevent " + + "to the end. Edit the command prior to submitting. If you want to remove the " + + "blockevent, then use `/mines blockevent remove help`." )); + return; + } + else if (command.startsWith("/")) { + command = command.replaceFirst("/", ""); + } + + if ( blockEvent.getCommand().equals( command ) ) { + + sender.sendMessage( "&7No change detected. Will not update an existing command with the same commmand. " + + "Please review submitted updates and make changes if still needed."); + return; + } + + blockEvent.setCommand(command ); + + pMines.getMineManager().saveMine( m ); + + Output.get().sendInfo(sender, "Updated BlockEvent command '%s' in 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())); + } + + // Redisplay the event list: + blockEventList( sender, mineName ); + } + + @Command(identifier = "mines blockEvent add", description = "Adds a BlockBreak command to a mine. " + "For each block that is broke there will be a chance to run one of these commands. \n" + From 33fb99f7cfaeb06c9d7d492ab4f975cc7e508545 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 10 Dec 2023 02:08:40 -0500 Subject: [PATCH 10/92] Mine resets: If a suggested block is null, then set it to air. This was causing an NPE under some conditions. --- docs/changelog_v3.3.x.md | 3 +++ .../main/java/tech/mcprison/prison/mines/data/MineReset.java | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 1d8e508d5..3d790ee6d 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.16 2023-12-10 +* **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. 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 68e314919..8baf832f8 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 @@ -609,6 +609,10 @@ public void generateBlockListAsync() { PrisonBlock prisonBlock = mineLevelBlockList.randomlySelectPrisonBlock(); + if ( prisonBlock == null ) { + prisonBlock = PrisonBlock.AIR.clone(); + } + // PrisonBlock prisonBlock = randomlySelectPrisonBlock( random, currentLevel ); // Increment the mine's block count. This block is one of the control blocks: From db3327b230eb6517f3d21b0dd25c523673b012ce Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 10 Dec 2023 02:11:55 -0500 Subject: [PATCH 11/92] 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. --- docs/changelog_v3.3.x.md | 5 +++++ prison-spigot/src/main/resources/config.yml | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 3d790ee6d..5cea72cbc 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.16 2023-12-10 +* **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.** diff --git a/prison-spigot/src/main/resources/config.yml b/prison-spigot/src/main/resources/config.yml index 1e253a222..fdb50b29b 100644 --- a/prison-spigot/src/main/resources/config.yml +++ b/prison-spigot/src/main/resources/config.yml @@ -309,8 +309,8 @@ storageType: "json" prison-mines: reset-gap-ms: 5000 reset-paging: - max-page-elapsed-time-ms: 75 - page-submit-delay-ticks: 1 + max-page-elapsed-time-ms: 40 + page-submit-delay-ticks: 0 page-timeout-check-block-count: 250 reset-async-paging: async-page-size: 4000 From dd64e71a46eeed2d8d9b1dcf6fbfab91f512374c Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 16 Dec 2023 03:00:42 -0500 Subject: [PATCH 12/92] 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. --- .../prison/mines/commands/MinesCommands.java | 15 +++++++++ .../mcprison/prison/mines/data/MineReset.java | 6 ++++ .../prison/mines/data/MineScheduler.java | 32 +++++++++++++++++-- 3 files changed, 51 insertions(+), 2 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 3f26327b0..386a32e9c 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 @@ -1397,6 +1397,21 @@ public void resetCommand(CommandSender sender, sender.sendMessage( "&cMine is disabled&7. Use &a/mines info &7for possible cause." ); return; } + + if ( !m.getMineStateMutex().isMinable() ) { + long resetDuration = m.getMineResetStartTimestamp() == -1 ? 0 : + m.getMineResetStartTimestamp() - System.currentTimeMillis(); + + 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 4 minutes before the Mutex is releasable. " + + "The mine was reset %s seconds ago.", + dFmt.format( resetDuration / 1000.0d ) ) + ); + } try { 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 8baf832f8..8f576ab03 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 @@ -916,6 +916,12 @@ public void asynchronouslyResetFinalize( List jobResetActions incrementResetCount(); + try { + ((MineScheduler) this).setMineResetStartTimestamp( -1 ); + } catch (Exception e) { + // ignore... + } + if ( !getCurrentJob().getResetActions().contains( MineResetActions.NO_COMMANDS )) { // After reset commands: 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 cf68899db..044eee9ee 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 @@ -49,12 +49,16 @@ public abstract class MineScheduler // private MineJob currentJob; private Integer taskId = null; + private transient long mineResetStartTimestamp; + + public MineScheduler() { super(); this.jobWorkflow = new ArrayList<>(); this.jobStack = new Stack<>(); + this.mineResetStartTimestamp = -1; } /** @@ -803,11 +807,26 @@ public void manualReset( MineResetScheduleType resetType, List private void manualReset( MineResetScheduleType resetType, double delayActionSec, List resetActions ) { - if ( isVirtual() || !getMineStateMutex().isMinable() ) { - // Nope... nothing to reset... or it's locked out already with a reset + if ( isVirtual() ) { + // Nope... nothing to reset... return; } + if ( !getMineStateMutex().isMinable() && + getMineResetStartTimestamp() != -1 && + getMineResetStartTimestamp() - System.currentTimeMillis() > 4 * 60000 ) { + + // Mine reset was trying to run for more than 4 minutes... so it's locked out and failed? + + // reset mutex and allow the rest to be forced: + getMineStateMutex().setMineStateResetFinishedForced(); + + setMineResetStartTimestamp( -1 ); + + } + + + synchronized ( getMineStateMutex() ) { // The synchronized block will halt threads and will wait. @@ -823,6 +842,8 @@ private void manualReset( MineResetScheduleType resetType, double delayActionSec getMineStateMutex().setMineStateResetStart(); + + setMineResetStartTimestamp( System.currentTimeMillis() ); // // Lock the mine's mutex if it's still minable. Otherwise skip it since the @@ -901,4 +922,11 @@ public void setTaskId( Integer taskId ) this.taskId = taskId; } + public long getMineResetStartTimestamp() { + return mineResetStartTimestamp; + } + public void setMineResetStartTimestamp(long mineResetStartTimestamp) { + this.mineResetStartTimestamp = mineResetStartTimestamp; + } + } From d94f8f4bc7a9132e76f5c2ba0dfcabdc7f77bc02 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 16 Dec 2023 03:12:13 -0500 Subject: [PATCH 13/92] 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. --- docs/changelog_v3.3.x.md | 8 +++++++- .../autofeatures/AutoFeaturesFileConfig.java | 7 +++++++ .../spigot/autofeatures/AutoManagerFeatures.java | 16 +++++++++++++--- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 5cea72cbc..1bee5b997 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.16 2023-12-10 +# 3.3.0-alpha.16 2023-12-16 + + +* **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.** 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 b093c7a5a..bc2a9213e 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 @@ -262,6 +262,13 @@ 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, " + + "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, " + + "other than just turning off these perms, which is not advisable because " + + "players should not be playing as OP'd. To disable these perms, then " + + "use a value of 'disable'."), lore(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 79da13c74..4c0413e29 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 @@ -516,9 +516,19 @@ private int applyAutoEventsDetails( PrisonMinesBlockBreakEvent pmEvent ) { boolean isAutoFeaturesEnabled = isBoolean( AutoFeatures.isAutoFeaturesEnabled ); - boolean permPickup = isAutoFeaturesEnabled && player.isPermissionSet( getMessage( AutoFeatures.permissionAutoPickup )); - boolean permSmelt = isAutoFeaturesEnabled && player.isPermissionSet( getMessage( AutoFeatures.permissionAutoSmelt )); - boolean permBlock = isAutoFeaturesEnabled && player.isPermissionSet( getMessage( AutoFeatures.permissionAutoBlock )); + String permAutoPickup = getMessage( AutoFeatures.permissionAutoPickup ); + String permAutoSmelt = getMessage( AutoFeatures.permissionAutoSmelt ); + String permAutoBlock = getMessage( AutoFeatures.permissionAutoBlock ); + + boolean permPickup = isAutoFeaturesEnabled && + !"disable".equalsIgnoreCase( permAutoPickup ) && + player.isPermissionSet( permAutoPickup ); + boolean permSmelt = isAutoFeaturesEnabled && + !"disable".equalsIgnoreCase( permAutoSmelt ) && + player.isPermissionSet( permAutoSmelt ); + boolean permBlock = isAutoFeaturesEnabled && + !"disable".equalsIgnoreCase( permAutoBlock ) && + player.isPermissionSet( permAutoBlock ); boolean configPickup = isAutoFeaturesEnabled && isBoolean( AutoFeatures.autoPickupEnabled ); From 17248940ddc51e227437ddb54847527be470482c Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 16 Dec 2023 04:07:24 -0500 Subject: [PATCH 14/92] 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. --- docs/changelog_v3.3.x.md | 4 ++++ prison-spigot/src/main/resources/config.yml | 20 +++++++++++--------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 1bee5b997..687b08f80 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.16 2023-12-16 +* **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. diff --git a/prison-spigot/src/main/resources/config.yml b/prison-spigot/src/main/resources/config.yml index fdb50b29b..b2701fd0f 100644 --- a/prison-spigot/src/main/resources/config.yml +++ b/prison-spigot/src/main/resources/config.yml @@ -475,16 +475,18 @@ prisonCommandHandler: exclude-non-ops: exclude-related-aliases: true commands: - mines: - tp: - includeCmdPerms: true - includeCmdAltPerms: true - perms: - - prison.exclude.test + prison: + support: + colorTest: + includeCmdPerms: false + includeCmdAltPerms: false + perms: + - prison.exclude.test aliases: - mines: - tp: - - mines teleport + prison: + support: + colorTest: + - pColorTest From 2967fae9264ad457ca7e4c5bec162c12ad9e6071 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 21 Dec 2023 15:43:30 -0500 Subject: [PATCH 15/92] Upgrade XSeries from v9.7.0 to v9.8.0. Upgrade nbt-api from v2.12.0 to v2.12.2. --- docs/changelog_v3.3.x.md | 6 +++++- prison-spigot/build.gradle | 13 +++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 687b08f80..ecd5858e0 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.16 2023-12-16 +# 3.3.0-alpha.16 2023-12-21 + + +* **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.** diff --git a/prison-spigot/build.gradle b/prison-spigot/build.gradle index 6d4ab2f28..d568569e1 100644 --- a/prison-spigot/build.gradle +++ b/prison-spigot/build.gradle @@ -149,7 +149,7 @@ dependencies { // https://mvnrepository.com/artifact/com.github.cryptomorin/XSeries - implementation 'com.github.cryptomorin:XSeries:9.7.0' + implementation 'com.github.cryptomorin:XSeries:9.8.0' //implementation 'com.github.cryptomorin:XSeries:9.4.0' //implementation 'com.github.cryptomorin:XSeries:9.2.0' @@ -185,14 +185,15 @@ dependencies { // NOTE: mavenrepository.com is not the offical repo. - // NOTE: This item-nbt MUST use the API and not the plugini version! + // 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: This maven repo was failing to be accessable during online builds. So added to the /lib. // https://github.com/tr7zw/Item-NBT-API/wiki/Using-Gradle // https://www.spigotmc.org/resources/nbt-api.7939/ // https://mvnrepository.com/artifact/de.tr7zw/item-nbt-api-plugin - implementation 'de.tr7zw:item-nbt-api:2.12.0' + implementation 'de.tr7zw:item-nbt-api:2.12.2' +// implementation 'de.tr7zw:item-nbt-api:2.12.0' // implementation 'de.tr7zw:item-nbt-api-plugin:2.11.2' // implementation 'de.tr7zw:item-nbt-api-plugin:2.10.0' // implementation 'de.tr7zw:item-nbt-api-plugin:2.9.2' @@ -265,11 +266,7 @@ shadowJar { //include(dependency('me.clip:placeholderapi:2.10.9')) // https://mvnrepository.com/artifact/com.github.cryptomorin/XSeries - include(dependency('com.github.cryptomorin:XSeries:9.7.0')) - //include(dependency('com.github.cryptomorin:XSeries:9.4.0')) - //include(dependency('com.github.cryptomorin:XSeries:9.2.0')) - //include(dependency('com.github.cryptomorin:XSeries:9.0.0')) - //include(dependency('com.github.cryptomorin:XSeries:8.8.0')) + include(dependency('com.github.cryptomorin:XSeries:')) // https://mvnrepository.com/artifact/de.tr7zw/item-nbt-api-plugin From a7984e82faadb28cdcf5b9213aa04492caa7710b Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 21 Dec 2023 17:38:04 -0500 Subject: [PATCH 16/92] 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. --- docs/changelog_v3.3.x.md | 5 +++++ .../java/tech/mcprison/prison/mines/data/Mine.java | 13 +++++++++++++ .../spigot/autofeatures/AutoManagerFeatures.java | 4 +--- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index ecd5858e0..145051c1c 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.16 2023-12-21 +* **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.** 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 316f3639f..fcacbc647 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 @@ -438,6 +438,19 @@ else if (validateBlockNames.contains( blockTypeName ) ) { dirty = true; } + if ( prisonBlock == null && "grass".equalsIgnoreCase(docBlock) ) { + // For spigot v20.0.4 GRASS was changed to SHORT_GRASS + + String fixedName = "SHORT_GRASS".toLowerCase(); + + prisonBlock = PrisonBlockStatusData.parseFromSaveFileFormat( fixedName ); + dirty = true; + + Output.get().logInfo( "NOTE: Block named GRASS has ben changed to SHORT_GRASS " + + "due to XMaterial's support for spigot v20.0.4. Please verify that " + + "it's spawning correctly on mine resets." ); + } + if ( prisonBlock != null ) { totalBlockCount += prisonBlock.getBlockCountTotal(); 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 4c0413e29..e7325df58 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 @@ -39,8 +39,6 @@ import tech.mcprison.prison.output.ChatDisplay; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.output.Output.DebugTarget; -import tech.mcprison.prison.ranks.PrisonRanks; -import tech.mcprison.prison.ranks.data.RankPlayer; import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.SpigotUtil; import tech.mcprison.prison.spigot.api.PrisonMinesBlockBreakEvent; @@ -2627,7 +2625,7 @@ else if ( isBoolean( AutoFeatures.isCalculateAltFortuneEnabled ) ) { xMat == XMaterial.MELON_SEEDS || xMat == XMaterial.NETHER_WART || xMat == XMaterial.POTATO || - xMat == XMaterial.GRASS || + xMat == XMaterial.SHORT_GRASS || xMat == XMaterial.WHEAT ) { From a8f74c5ac5b3521028b04f2761cf7f213ff67f90 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 27 Dec 2023 23:44:27 -0500 Subject: [PATCH 17/92] 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. --- .../spigot/block/OnBlockBreakEventCore.java | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) 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 18409fcf7..fbf608e7b 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 @@ -33,7 +33,6 @@ 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.sellall.SellAllUtil; import tech.mcprison.prison.spigot.utils.BlockUtils; import tech.mcprison.prison.util.Text; @@ -924,20 +923,26 @@ else if ( results && pmEvent.getBbPriority().isMonitor() && mine != null ) { if ( SpigotPrison.getInstance().isSellAllEnabled() ) { - SellAllUtil sellAllUtil = SellAllUtil.get(); +// SellAllUtil sellAllUtil = SellAllUtil.get(); // This will return true (allow autosell) unless players can toggle autosell and they turned it off: // This is to be used with other auto sell setting, but never on it's own: boolean isPlayerAutosellEnabled = - (!sellAllUtil.isAutoSellPerUserToggleable || - sellAllUtil.isSellallPlayerUserToggleEnabled( - pmEvent.getPlayer() )); + pmEvent.getSpigotPlayer().isAutoSellEnabled( pmEvent.getDebugInfo() ); +// (!sellAllUtil.isAutoSellPerUserToggleable || +// sellAllUtil.isSellallPlayerUserToggleEnabled( +// pmEvent.getPlayer() )); + + + boolean isPlayerAutoSellByPerm = pmEvent.getSpigotPlayer().isAutoSellByPermEnabled( isPlayerAutosellEnabled ); + + // AutoSell on full inventory when using BLOCKEVENTS: if ( isBoolean( AutoFeatures.isAutoSellIfInventoryIsFullForBLOCKEVENTSPriority ) && - isPlayerAutosellEnabled && + ( isPlayerAutosellEnabled || isPlayerAutoSellByPerm ) && pmEvent.getSpigotPlayer().isInventoryFull() ) { pmEvent.performSellAllOnPlayerInventoryLogged("BLOCKEVENTS priority sellall"); From 96ba5ac1ec48dc498351ba97c4ae6a3a0741bc5d Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 22 Jan 2024 03:52:14 -0500 Subject: [PATCH 18/92] 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. --- docs/changelog_v3.3.x.md | 19 ++++++++++++++++--- .../prison/mines/commands/MinesCommands.java | 19 +++++++++---------- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 145051c1c..3b5722226 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.16 2023-12-21 +# 3.3.0-alpha.16 2024-01-22 + + + +* **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. @@ -22,8 +35,8 @@ Setup a converter to automatically convert all GRASS to SHORT_GRASS as the mines -* **Upgrade XSeries from v9.7.0 to v9.8.0. -Upgrade nbt-api from v2.12.0 to v2.12.2.** +* **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.** 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 386a32e9c..4b5dd29db 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 @@ -2413,7 +2413,8 @@ else if ( action.equalsIgnoreCase( "disable" ) && m.isUseNotificationPermission( altPermissions = "mines.notification.[mineName]") public void setMinePermissionCommand(CommandSender sender, @Arg(name = "mineName", - description = "The name of the mine to add a permission to. Use '*all*' for all mines.") String mineName, + description = "The name of the mine to add a permission to. Use '*all*' for all mines.") + String mineName, @Arg(name = "permission", def="enable", description = "Permission. Can use a placeholder '{mmine}' to dynamically apply " + "the mine name when using '*all*'. Example using placeholder: 'mines.{mine}' " + @@ -2429,21 +2430,19 @@ public void setMinePermissionCommand(CommandSender sender, 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); } - else { - for ( Mine m : pMines.getMines() ) { - - minesSetAccessPermission(sender, permission, pMines, m); - } - } - - } } From 507c996779fe3bbe78d553e1b49535a7b3e6067b Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 22 Jan 2024 06:07:41 -0500 Subject: [PATCH 19/92] 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. --- docs/changelog_v3.3.x.md | 4 ++ .../prison/internal/block/PrisonBlock.java | 29 +++++++++-- .../internal/block/PrisonBlockStatusData.java | 40 +++++++++++++-- .../mcprison/prison/spigot/SpigotUtil.java | 12 +++-- .../prison/spigot/block/SpigotItemStack.java | 9 +++- .../prison/spigot/sellall/SellAllUtil.java | 50 +++++++++++++++---- 6 files changed, 125 insertions(+), 19 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 3b5722226..abc72d6e6 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.16 2024-01-22 +* **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 hoo 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. 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 2f997747a..2679d178f 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 @@ -77,6 +77,11 @@ public boolean isCustomBlockType() { public PrisonBlock( String blockName ) { this( PrisonBlockType.minecraft, blockName, 0, 0); } + public PrisonBlock( String blockName, String displayName ) { + this( PrisonBlockType.minecraft, blockName, 0, 0); + + setDisplayName( displayName ); + } public PrisonBlock( PrisonBlockType blockType, String blockName ) { this( blockType, blockName, 0, 0); } @@ -169,8 +174,16 @@ public String getBlockNameFormal() { * @return */ public String getBlockNameSearch() { - return getBlockType() != PrisonBlockType.minecraft ? - getBlockType().name() + ":" + getBlockName() : getBlockName(); + + String blockType = getBlockType() != PrisonBlockType.minecraft ? + getBlockType().name() + ":" : ""; + + String blockName = getBlockName().toLowerCase(); + + String displayName = getDisplayName() != null ? + ":" + getDisplayName().toLowerCase() : ""; + + return blockType + blockName + displayName; } @@ -359,7 +372,17 @@ public int compareTo( PrisonBlock block ) results = 1; } else { - results = getBlockName().compareToIgnoreCase( block.getBlockName() ); + + results = getBlockType() == block.getBlockType() ? 0 : 1; + + if ( results == 0 ) { + + results = getBlockName().compareToIgnoreCase( block.getBlockName() ); + + if ( results == 0 && getDisplayName() != null && block.getDisplayName() != null ) { + results = getDisplayName().compareToIgnoreCase( block.getDisplayName() ); + } + } } return results; 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 2f699fcba..ce4074868 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 @@ -3,7 +3,6 @@ import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; -import java.util.Random; import tech.mcprison.prison.Prison; import tech.mcprison.prison.internal.block.PrisonBlock.PrisonBlockType; @@ -15,6 +14,9 @@ public abstract class PrisonBlockStatusData { private PrisonBlockType blockType; private String blockName; + // displayName is an optional custom name + private String displayName; + private double chance; private int constraintMin; @@ -43,12 +45,23 @@ public abstract class PrisonBlockStatusData { private transient boolean includeInLayerCalculations; - public PrisonBlockStatusData( PrisonBlockType blockType, String blockName, double chance, long blockCountTotal ) { + public PrisonBlockStatusData( + PrisonBlockType blockType, String blockName, String displayName, + double chance, long blockCountTotal ) { + this( blockType, blockName, chance, blockCountTotal ); + + this.displayName = displayName; + } + + public PrisonBlockStatusData( + PrisonBlockType blockType, String blockName, double chance, long blockCountTotal ) { super(); this.blockType = blockType; this.blockName = blockName; + this.displayName = null; + this.chance = chance; this.constraintMin = 0; @@ -76,6 +89,12 @@ public PrisonBlockStatusData( PrisonBlockType blockType, String blockName, doubl + /** + *

Checks to see if both the blockType and the blockName are equal, + * and if there is a displayName set, then both need to have their + * displayName is also set to the same value. + *

+ */ @Override public boolean equals( Object obj ) { @@ -84,7 +103,15 @@ public boolean equals( Object obj ) if ( obj instanceof PrisonBlockStatusData ) { PrisonBlockStatusData pbsBlock = (PrisonBlockStatusData) obj; - results = getBlockName().equalsIgnoreCase( pbsBlock.getBlockName() ); + results = getBlockType() == getBlockType() && + getBlockName().equalsIgnoreCase( pbsBlock.getBlockName() ); + + if ( results ) { + + results = getDisplayName() == null && pbsBlock.getDisplayName() == null || + getDisplayName() != null && pbsBlock.getDisplayName() != null && + getDisplayName().equalsIgnoreCase( pbsBlock.getDisplayName() ); + } } return results; @@ -409,6 +436,13 @@ public void setBlockName( String blockName ) { this.blockName = blockName; } + public String getDisplayName() { + return displayName; + } + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + public PrisonBlockType getBlockType() { return blockType; } 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 c37f9f0c3..e9bb0fcd6 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 @@ -736,8 +736,11 @@ public static List getAllCustomBlockTypes() { * @return */ public static PrisonBlock getPrisonBlock( String blockName ) { + return getPrisonBlock( blockName, null ); + } + public static PrisonBlock getPrisonBlock( String blockName, String displayName ) { - PrisonBlock results = new PrisonBlock( blockName ); + PrisonBlock results = new PrisonBlock( blockName, displayName ); results.setValid( false ); // BlockType bTypeObsolete = null; @@ -766,16 +769,19 @@ public static PrisonBlock getPrisonBlock( String blockName ) { } public static PrisonBlock getPrisonBlock( XMaterial xMat ) { + return getPrisonBlock( xMat, null ); + } + public static PrisonBlock getPrisonBlock( XMaterial xMat, String displayName ) { PrisonBlock results = null; if ( xMat != null ) { - results = new PrisonBlock( xMat.name() ); + results = new PrisonBlock( xMat.name(), displayName ); } if ( results == null ) { - results = getPrisonBlock( xMat.name() ); + results = getPrisonBlock( xMat.name(), displayName ); } return results; 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 fa3c32710..8d1a6bc1a 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 @@ -82,7 +82,6 @@ private void setupBukkitStack( org.bukkit.inventory.ItemStack bukkitStack ) { - PrisonBlock type = SpigotUtil.getPrisonBlock( xMat ); // BlockType type = SpigotCompatibility.getInstance() // .getBlockType( bukkitStack ); @@ -98,6 +97,10 @@ private void setupBukkitStack( org.bukkit.inventory.ItemStack bukkitStack ) { // displayName = type.getBlockName().toLowerCase(); // } + + PrisonBlock type = SpigotUtil.getPrisonBlock( xMat, displayName ); + + List lores = new ArrayList<>(); if ( meta.hasLore() ) { @@ -148,6 +151,10 @@ public void setPrisonBlock( PrisonBlock pBlock ) { String displayName = pBlock.getBlockName(); + if ( pBlock.getDisplayName() != null ) { + displayName = pBlock.getDisplayName(); + } + setDisplayName( displayName ); setMaterial( pBlock ); 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 1acf5a8eb..25c44ac94 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 @@ -737,7 +737,8 @@ public List sellPlayerItemStacks(Player p, } - private List sellInventoryItems( tech.mcprison.prison.internal.inventory.Inventory inventory, double multiplier ) { + private List sellInventoryItems( tech.mcprison.prison.internal.inventory.Inventory inventory, + double multiplier ) { List soldItems = new ArrayList<>(); if ( inventory != null ) { @@ -808,8 +809,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 + // displayName if that is set on the itemStack. PrisonBlock pBlockInv = iStack.getMaterial(); - PrisonBlock pBlockSellAll = sellAllItems.get( pBlockInv.getBlockName().toLowerCase() ); + + PrisonBlock pBlockSellAll = sellAllItems.get( pBlockInv.getBlockNameSearch() ); if ( pBlockSellAll != null ) { double amount = iStack.getAmount() * pBlockSellAll.getSalePrice() * multiplier; @@ -1155,6 +1159,12 @@ public HashMap initSellAllItems(){ PrisonBlock pBlock = Prison.get().getPlatform().getPrisonBlock(itemID); if ( pBlock != null ) { + + String itemDisplayName = sellAllConfig.getString("Items." + itemName + ".ITEM_DISPLAY_NAME"); + if ( itemDisplayName != null ) { + pBlock.setDisplayName( itemDisplayName ); + } + String saleValueString = sellAllConfig.getString("Items." + itemName + ".ITEM_VALUE"); if ( saleValueString != null ) { @@ -1174,7 +1184,8 @@ public HashMap initSellAllItems(){ } catch (NumberFormatException ignored) { } } - sellAllItems.put( pBlock.getBlockName().toLowerCase(), pBlock ); + + sellAllItems.put( pBlock.getBlockNameSearch(), pBlock ); } // Optional iMatOptional = XMaterial.matchXMaterial(itemID); @@ -1259,14 +1270,19 @@ public ArrayList initSellAllItemTrigger(){ * * @return boolean. * */ - public boolean addSellAllBlock(XMaterial xMaterial, double value){ + public boolean addSellAllBlock(XMaterial xMaterial, double value) { + return addSellAllBlock( xMaterial, null, value ); + } + + public boolean addSellAllBlock(XMaterial xMaterial, String displayName, double value) { PrisonBlock pBlockKey = Prison.get().getPlatform().getPrisonBlock( xMaterial.name() ); if ( pBlockKey == null ) { Output.get().logDebug( "sellall add: invalid block name (%s)", xMaterial.name()); return false; } - String key = pBlockKey.getBlockName().toLowerCase(); + String key = pBlockKey.getBlockNameSearch(); +// String key = pBlockKey.getBlockName().toLowerCase(); PrisonBlock pBlock = sellAllItems.get( key ); @@ -1284,6 +1300,11 @@ public boolean addSellAllBlock(XMaterial xMaterial, double value){ FileConfiguration conf = YamlConfiguration.loadConfiguration(sellAllFile); conf.set("Items." + itemName + ".ITEM_ID", xMaterial.name()); conf.set("Items." + itemName + ".ITEM_VALUE", value); + + 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") + xMaterial.name()); @@ -1292,7 +1313,7 @@ public boolean addSellAllBlock(XMaterial xMaterial, double value){ updateConfig(); pBlockKey.setSalePrice( value ); - sellAllItems.put( pBlockKey.getBlockName().toLowerCase(), pBlockKey ); + sellAllItems.put( pBlockKey.getBlockNameSearch(), pBlockKey ); } catch (IOException e) { e.printStackTrace(); @@ -1584,10 +1605,13 @@ public boolean canPlayerSell(Player p, boolean isUsingSign){ * * @return boolean. * */ - public boolean editPrice(XMaterial xMaterial, double value){ + public boolean editPrice(XMaterial xMaterial, double value) { + return editPrice( xMaterial, null, value ); + } + public boolean editPrice(XMaterial xMaterial, String displayName, double value) { PrisonBlock pBlockKey = Prison.get().getPlatform().getPrisonBlock( xMaterial.name() ); - String key = pBlockKey.getBlockName().toLowerCase(); + String key = pBlockKey.getBlockNameSearch(); PrisonBlock pBlock = sellAllItems.get( key ); @@ -1614,6 +1638,14 @@ public boolean editPrice(XMaterial xMaterial, double value){ conf.set("Items." + itemName + ".ITEM_ID", key ); conf.set("Items." + itemName + ".ITEM_VALUE", value); + 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() ); @@ -1683,7 +1715,7 @@ public boolean editPrestigeMultiplier(String prestigeName, double multiplier) { public boolean removeSellAllBlock(XMaterial xMaterial){ PrisonBlock pBlockKey = Prison.get().getPlatform().getPrisonBlock( xMaterial.name() ); - String key = pBlockKey.getBlockName().toLowerCase(); + String key = pBlockKey.getBlockNameSearch(); PrisonBlock pBlock = sellAllItems.get( key ); From 5f40aae0cd27fc66c3147fb57b17222e1fe7b966 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 24 Jan 2024 05:28:33 -0500 Subject: [PATCH 20/92] 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. --- .../discord/PrisonSupportFilesTest.java | 8 +++++++ .../tech/mcprison/prison/mines/data/Mine.java | 21 ++++++++++++++++++ .../mines/data/PrisonSortableMinesTest.java | 22 ++++++++++++++----- .../mines/managers/MineManagerTest.java | 22 ++++++++++++------- 4 files changed, 59 insertions(+), 14 deletions(-) diff --git a/prison-core/src/test/java/tech/mcprison/prison/discord/PrisonSupportFilesTest.java b/prison-core/src/test/java/tech/mcprison/prison/discord/PrisonSupportFilesTest.java index 69d495bdd..830ebc306 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/discord/PrisonSupportFilesTest.java +++ b/prison-core/src/test/java/tech/mcprison/prison/discord/PrisonSupportFilesTest.java @@ -44,6 +44,14 @@ public void test() { assertEquals(r5, convertColorCodes(t5) ); + +// String t6 = "&3This is &-a &1test & a&r &c&+fun &1sample"; +// String r6 = "This is a " +// + "test & a" +// + " fun sample\n"; +// +// assertEquals(r6, convertColorCodes(t6) ); + } } 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 fcacbc647..2b225d881 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 @@ -69,6 +69,10 @@ public static MineType fromString( String mineType ) { return results; } } + + public enum MineUnitTestUsage { + TRUE; + } /** * Creates a new, empty mine instance @@ -80,6 +84,23 @@ public Mine() { initialize(); } + /** + *

This constructor should ONLY be used in unit test since it will NOT run + * any of the initialization code so the automated services will not be started, + * which are not needed for unit tests. + *

+ * + * @param unitTestUsage + */ + public Mine( MineUnitTestUsage unitTestUsage, String mineName ) { + super(); + + setName( mineName ); + + // Kick off the initialize: + //initialize(); + } + /** *

This is called when a mine is first created. 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 c93683e37..6b9d26292 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 @@ -8,6 +8,8 @@ import org.junit.Test; +import tech.mcprison.prison.mines.data.Mine.MineUnitTestUsage; + @SuppressWarnings("deprecation") public class PrisonSortableMinesTest extends PrisonSortableMines @@ -19,12 +21,20 @@ public class PrisonSortableMinesTest @Test public void testGetSortedSet() { - Mine a = new Mine(); - a.setName( "A" ); - Mine b = new Mine(); - b.setName( "b" ); - Mine c = new Mine(); - c.setName( "C" ); + /** + * The following mine constructor will not initialize the mines since that + * is not needed in unit tests. + */ + Mine a = new Mine( MineUnitTestUsage.TRUE, "A" ); + 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 ); 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 7851dd110..58ea9cc4f 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 @@ -9,6 +9,7 @@ import tech.mcprison.prison.mines.data.Mine; import tech.mcprison.prison.mines.data.PrisonSortableResults; +import tech.mcprison.prison.mines.data.Mine.MineUnitTestUsage; public class MineManagerTest extends @@ -17,14 +18,19 @@ public class MineManagerTest private List getTestMines() { List mines = new ArrayList<>(); - 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" ); + Mine a = new Mine( MineUnitTestUsage.TRUE, "A" ); + Mine b = new Mine( MineUnitTestUsage.TRUE, "b" ); + 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 ); From 78f1793d7951cdf0138715204263c39c3f44119e Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 24 Jan 2024 05:45:20 -0500 Subject: [PATCH 21/92] 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. --- docs/changelog_v3.3.x.md | 10 +++++++++- .../java/tech/mcprison/prison/mines/PrisonMines.java | 5 +++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index abc72d6e6..3293a09e6 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.16 2024-01-22 +# 3.3.0-alpha.16a 2024-01-24 + + +* **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.** 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 d827c336d..d4d0739f6 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 @@ -89,6 +89,11 @@ public PrisonMines(String version) { } public static PrisonMines getInstance() { + if ( i == null ) { + PrisonMines temp = new PrisonMines("(not loaded yet)"); + temp.setEnabled(false); + return temp; + } return i; } From 67d52196e15d5f6c767f7e39bd8e915b7cc24564 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 24 Jan 2024 05:47:01 -0500 Subject: [PATCH 22/92] 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. --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 01d7ea2a1..1ab6e11a4 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.16 +version=3.3.0-alpha.16a From 3a7c86ea56c002fe27120f953c65b94ac0cec724 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 17 Feb 2024 16:30:21 -0500 Subject: [PATCH 23/92] 2023-12-28 alpha.16a -- was not committed back when it was made - changelog only. --- 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 3293a09e6..30673aef3 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.16a 2024-01-24 +* **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. From c464b6c5acd5745bb1ba402e1d6fafa1d230fd44 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 17 Feb 2024 20:54:14 -0500 Subject: [PATCH 24/92] 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. --- docs/changelog_v3.3.x.md | 8 +++++++- .../mcprison/prison/mines/commands/MinesCommands.java | 7 ++++++- .../prison/mines/data/MineLevelBlockListData.java | 2 +- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 30673aef3..204f19aaf 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.16a 2024-01-24 +# 3.3.0-alpha.16a 2024-02-17 + + +* **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** 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 4b5dd29db..7f3b73589 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 @@ -196,7 +196,12 @@ public void listBlockCommand(CommandSender sender, @Override @Command(identifier = "mines block constraint", permissions = "mines.block", - description = "Optionally enable constraints on a mine's block generation.") + description = "Optionally enable constraints on a mine's block generation. " + + "Please note that 'excludeTop' and 'excludeBottom' uses the layer " + + "count from the top, where the top layer is 1. If " + + "a mine has 20 layers and you want to exclude a block from the " + + "bottomm 5 layers, then you need to use a value of 15, so it will " + + "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, 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 35c7c78fe..7bb028471 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 @@ -91,7 +91,7 @@ private void initialize() { (pBlock.getConstraintExcludeBottomLayers() == 0 || pBlock.getConstraintExcludeBottomLayers() > 0 && - pBlock.getConstraintExcludeBottomLayers() < currentMineLevel) + currentMineLevel < pBlock.getConstraintExcludeBottomLayers() ) ) { int targetBlockPosition = mine.getMineTargetPrisonBlocks().size(); From ac31dd0a6ce276a68419e60f56f3e324bbb51721 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 17 Feb 2024 21:02:49 -0500 Subject: [PATCH 25/92] Add debug statements to identify how each block was calculated during a mine reset. --- docs/changelog_v3.3.x.md | 3 ++ .../mcprison/prison/mines/data/MineReset.java | 31 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 204f19aaf..0f64cc259 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.16a 2024-02-17 +* **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.** 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 8f576ab03..29f206f86 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 @@ -640,6 +640,37 @@ public void generateBlockListAsync() { constraintsApplyMin(); + if ( Output.get().isDebug() ) { + + DecimalFormat dFmt = Prison.get().getDecimalFormatDouble(); + DecimalFormat iFmt = Prison.get().getDecimalFormatInt(); + + for ( PrisonBlockStatusData b : getPrisonBlocks() ) { + + int rangeLow = b.getRangeBlockCountLowLimit(); + int rangeHigh = b.getRangeBlockCountHighLimit(); + int rangeCount = b.getRangeBlockCountHighLimit() - b.getRangeBlockCountLowLimit() + 1; + double rangePercent = rangeCount / (double) getBounds().getTotalBlockCount(); + + String msg = String.format( + " Block: %-14s : placed: %-5d PlacementRange: (%d - %d) " + + "%d out of %d %s " + + "min: %d max: %d ExcldTop: %d ExcldBottom: %d ", + b.getBlockName(), b.getBlockPlacedCount(), + rangeLow, rangeHigh, + rangeCount, + getBounds().getTotalBlockCount(), + dFmt.format( rangePercent ), + + b.getConstraintMin(), b.getConstraintMax(), + b.getConstraintExcludeTopLayers(), + b.getConstraintExcludeBottomLayers() + ); + + Output.get().logInfo( msg ); + } + } + // 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. From 827a203e55dfbe2f8b96ba17d557a860325f05f0 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 18 Feb 2024 00:29:40 -0500 Subject: [PATCH 26/92] 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. --- docs/changelog_v3.3.x.md | 3 ++ .../prison/ranks/managers/PlayerManager.java | 44 +++++++++---------- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 0f64cc259..7aa26b9e2 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.16a 2024-02-17 +* **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.** 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 c068b8955..4fdf2a7d9 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 @@ -196,26 +196,26 @@ public void savePlayer(RankPlayer player) { * @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); - } - } - } +// 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 @@ -330,8 +330,8 @@ public RankPlayer getPlayer(UUID uid, String playerName) { // dirty = results != null; } - // Save if dirty (change or new): - if ( results != null ) { + // Save if dirty (changed or new): + if ( results != null && results.isDirty() ) { savePlayer( results ); } From 9bfda731950e21d4f152f84351db07194af85883 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 19 Feb 2024 02:34:00 -0500 Subject: [PATCH 27/92] 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. --- docs/changelog_v3.3.x.md | 6 +++++- .../tech/mcprison/prison/ranks/managers/RankManager.java | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 7aa26b9e2..192cb3864 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.16a 2024-02-17 +# 3.3.0-alpha.16a 2024-02-19 + + +* **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. 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 c4d6d20d8..b0cc82250 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 @@ -947,7 +947,7 @@ public String getTranslateRanksPlaceHolder( PlaceholderIdentifier identifier ) { { RankPlayer topRankPlayer = getTopNRankPlayer( sequence ); - if ( topRankPlayer != null ) { + if ( topRankPlayer != null && topRankPlayer.getPlayerRankPrestiges() != null) { results = topRankPlayer.getPlayerRankPrestiges().getRank().getTag(); } @@ -962,7 +962,7 @@ public String getTranslateRanksPlaceHolder( PlaceholderIdentifier identifier ) { { RankPlayer topRankPlayer = getTopNRankPlayer( sequence ); - if ( topRankPlayer != null ) { + if ( topRankPlayer != null && topRankPlayer.getPlayerRankPrestiges() != null ) { results = topRankPlayer.getPlayerRankDefault().getRank().getTag(); } From eb3861437195a1d79df7eecd70171e368d34325e Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 19 Feb 2024 22:49:01 -0500 Subject: [PATCH 28/92] 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. --- docs/changelog_v3.3.x.md | 4 +++ .../prison/commands/CommandHandler.java | 31 ++++++++++++------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 192cb3864..b104c873c 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.16a 2024-02-19 +* **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. 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 f5357509b..e4a561769 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 @@ -801,19 +801,28 @@ private void hasCommandAccess( CommandSender sender, RegisteredCommand rootComma if ( !sender.isOp() ) { - 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 ); + boolean hasAccess = rootCommand.testPermission(sender); - if ( results.isAccess() && sLabelAlias != null ) { - - commandAccessPermChecks( sender, rootCommand.getParentOfAlias(), sLabelAlias, results ); + 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 ); + } + } + } From ca0683bcb39ef9aecf1419ac088d53ba9e3e29f9 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 19 Feb 2024 22:51:52 -0500 Subject: [PATCH 29/92] 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. --- docs/changelog_v3.3.x.md | 3 +++ .../tech/mcprison/prison/ranks/commands/LadderCommands.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 b104c873c..cae1dfe61 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.16a 2024-02-19 +* **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. 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 abd6901ac..a5e73fa1f 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 @@ -474,7 +474,8 @@ public void ladderApplyRankCostMultiplier( CommandSender sender, @Arg( name = "ladderName" ) String ladderName, @Arg( name = "applyRankCostMultiplier", def = "apply", description = "Applies or disables the ranks on this ladder " - + "from applying the rank multiplier to the rank cost for players." + + "from applying the rank multiplier to the rank cost for players. " + + "Use a value of 'apply' or 'true'; anything else is treated as 'false'." ) String applyRankCostMultiplier ) { @@ -487,7 +488,8 @@ public void ladderApplyRankCostMultiplier( CommandSender sender, } boolean applyRCM = applyRankCostMultiplier != null && - applyRankCostMultiplier.equalsIgnoreCase( "apply" ); + (applyRankCostMultiplier.equalsIgnoreCase( "apply" ) || + applyRankCostMultiplier.equalsIgnoreCase( "true" ) ); boolean applyRCMOld = ladder.isApplyRankCostMultiplierToLadder(); From 4affe2c41b5645ab1f708539aa32f16f2f1eb22b Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 19 Feb 2024 22:53:12 -0500 Subject: [PATCH 30/92] Mines set resetTime: fix typo in the description where it shows '*all' instead of '*all*'. --- docs/changelog_v3.3.x.md | 3 +++ .../tech/mcprison/prison/mines/commands/MinesCommands.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 cae1dfe61..aece98288 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.16a 2024-02-19 +* **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. 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 7f3b73589..b49e41977 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 @@ -1905,7 +1905,7 @@ public void skipResetCommand(CommandSender sender, @Command(identifier = "mines set resetTime", permissions = "mines.set", description = "Set a mine's auto reset time as expressed in seconds.") public void resetTimeCommand(CommandSender sender, - @Arg(name = "mineName", description = "The name of the mine to edit, or '*all' to apply to all mines.") String mineName, + @Arg(name = "mineName", description = "The name of the mine to edit, or '*all*' to apply to all mines.") String mineName, @Arg(name = "time", description = "Time in seconds for the mine to auto reset. " + "With a minimum value of "+ MineData.MINE_RESET__TIME_SEC__MINIMUM + " seconds. " + "Using '*disable*' will turn off the auto reset. Use of " From e4e7f2a63f17e689f21005d53a4a5c622f8eb9be Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 19 Feb 2024 23:40:35 -0500 Subject: [PATCH 31/92] 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. --- docs/changelog_v3.3.x.md | 5 +++++ .../tech/mcprison/prison/ranks/managers/RankManager.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 aece98288..0ee1c06b9 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.16a 2024-02-19 +* **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*'.** 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 b0cc82250..561bb8c87 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 @@ -962,7 +962,7 @@ public String getTranslateRanksPlaceHolder( PlaceholderIdentifier identifier ) { { RankPlayer topRankPlayer = getTopNRankPlayer( sequence ); - if ( topRankPlayer != null && topRankPlayer.getPlayerRankPrestiges() != null ) { + if ( topRankPlayer != null && topRankPlayer.getPlayerRankDefault() != null ) { results = topRankPlayer.getPlayerRankDefault().getRank().getTag(); } From a7cb7d0ee6705d41111a230ac2b0f692ac1d389a Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 20 Feb 2024 11:38:40 -0500 Subject: [PATCH 32/92] v3.3.0-alpha.16b 2024-02-20 --- 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 0ee1c06b9..ecf7b9831 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.16a 2024-02-19 +# 3.3.0-alpha.16b 2024-02-20 + + + +**3.3.0-alpha.16b 2024-02-20** * **Placeholders: Top player rank was using the wrong ladder, which was incorrectly the prestiges rank and not the default rank.** diff --git a/gradle.properties b/gradle.properties index 1ab6e11a4..3c083d648 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.16a +version=3.3.0-alpha.16b From c34bf9b60d7ab3837f9a5a84bd502d59a95a8d64 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 22 Feb 2024 12:38:55 -0500 Subject: [PATCH 33/92] 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. --- docs/changelog_v3.3.x.md | 5 ++++- .../tech/mcprison/prison/spigot/SpigotPlatform.java | 10 +++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index ecf7b9831..ca1e4e769 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -18,7 +18,10 @@ These change logs represent the work that has been going on within prison. -**3.3.0-alpha.16b 2024-02-20** +**3.3.0-alpha.16b 2024-02-22** + +* **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.** 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 3bfc67237..70eeebf09 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 @@ -2998,7 +2998,15 @@ public void testPlayerUtil( UUID uuid ) @Override public void saveResource( String fileName, boolean replace ) { - SpigotPrison.getInstance().saveResource( fileName, replace ); + + try { + SpigotPrison.getInstance().saveResource( fileName, replace ); + } catch (Exception e) { + Output.get().logInfo( + "SpigotPlatformm.saveResource(): Error trying to save a resource '%s' replace=%s : %s", + fileName, Boolean.toString(replace), e.getMessage() + ); + } } @Override From 8ce44a2726f37baadbd4cc6600602d33aa49759b Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 24 Feb 2024 03:03:36 -0500 Subject: [PATCH 34/92] Add prison debug option to filter on blockConstraints when regenerating the blocks within the mines. --- docs/changelog_v3.3.x.md | 7 ++++++- .../src/main/java/tech/mcprison/prison/PrisonCommand.java | 2 +- .../src/main/java/tech/mcprison/prison/output/Output.java | 3 ++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index ca1e4e769..7398d33d0 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -18,7 +18,12 @@ These change logs represent the work that has been going on within prison. -**3.3.0-alpha.16b 2024-02-22** +**3.3.0-alpha.16b 2024-02-24** + + + +* **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. 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 fe810f237..ffe1a943c 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java +++ b/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java @@ -1126,7 +1126,7 @@ public void toggleDebug(CommandSender sender, @Arg(name = "targets", def = " ", description = "Optional. Enable or disable a debugging target, or set a count down timer. " + "[on, off, targets, (count-down-timer), selective, jarScan, " + - "testPlayerUtil, testLocale, rankup, player= ] " + + "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 " + 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 85b5ef47d..82c28624a 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 @@ -81,8 +81,9 @@ public enum DebugTarget { targetBlockMismatch, - rankup + rankup, // support + blockConstraints ; public static DebugTarget fromString( String target ) { From b5234b5db59d74645f16a57eb59de7374a98717d Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 24 Feb 2024 03:05:54 -0500 Subject: [PATCH 35/92] 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. --- docs/changelog_v3.3.x.md | 2 + .../prison/spigot/configs/GuiConfig.java | 41 +++++++++++++------ 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 7398d33d0..e75ab007f 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -21,6 +21,8 @@ These change logs represent the work that has been going on within prison. **3.3.0-alpha.16b 2024-02-24** +* **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.** 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 bdf924b1b..9e95e5d6f 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 @@ -204,9 +204,15 @@ public void initialize() { map.put("NoMineAccess", XMaterial.REDSTONE_BLOCK.name() ); - for ( Mine mine : PrisonMines.getInstance().getMineManager().getMines() ) { - if ( mine.getPrisonBlocks().size() > 0 ) { - map.put( mine.getName(), mine.getPrisonBlocks().get(0).getBlockName() ); + + if ( PrisonMines.getInstance().getMineManager() != null && + PrisonMines.getInstance().getMineManager().getMines() != null && + PrisonMines.getInstance().getMineManager().getMines().size() > 0 ) { + + for ( Mine mine : PrisonMines.getInstance().getMineManager().getMines() ) { + if ( mine.getPrisonBlocks().size() > 0 ) { + map.put( mine.getName(), mine.getPrisonBlocks().get(0).getBlockName() ); + } } } @@ -232,12 +238,17 @@ else if ( conf.get( "Options.Mines.MaterialType.NoMineAccess" ) == null ) { map.put("NoRankAccess", XMaterial.REDSTONE_BLOCK.name() ); - // Example to preset all ranks: Only do the first 10: - int count = 0; - for ( Rank rank : PrisonRanks.getInstance().getRankManager().getRanks() ) { - map.put( rank.getName(), XMaterial.TRIPWIRE_HOOK.name() ); - if ( ++count >= 10 ) { - break; + if ( PrisonRanks.getInstance().getRankManager() != null && + PrisonRanks.getInstance().getRankManager().getRanks() != null && + PrisonRanks.getInstance().getRankManager().getRanks().size() > 0 ) { + + // Example to preset all ranks: Only do the first 10: + int count = 0; + for ( Rank rank : PrisonRanks.getInstance().getRankManager().getRanks() ) { + map.put( rank.getName(), XMaterial.TRIPWIRE_HOOK.name() ); + if ( ++count >= 10 ) { + break; + } } } @@ -265,8 +276,11 @@ else if ( conf.get( "Options.Ranks.MaterialType.NoMineAccess" ) == null ) { if ( conf.get( "Options.Mines.GuiItemNames" ) == null ) { - if ( PrisonMines.getInstance() != null ) { - + if ( PrisonMines.getInstance() != null && + PrisonMines.getInstance().getMineManager() != null && + PrisonMines.getInstance().getMineManager().getMines() != null && + PrisonMines.getInstance().getMineManager().getMines().size() > 0 ) { + LinkedHashMap map = new LinkedHashMap<>(); // Example to preset all mines: Only do the first 10: @@ -293,7 +307,10 @@ else if ( conf.get( "Options.Ranks.MaterialType.NoMineAccess" ) == null ) { } if ( conf.get( "Options.Ranks.GuiItemNames" ) == null ) { - if ( PrisonRanks.getInstance() != null ) { + if ( PrisonRanks.getInstance() != null && + PrisonRanks.getInstance().getRankManager() != null && + PrisonRanks.getInstance().getRankManager().getRanks() != null && + PrisonRanks.getInstance().getRankManager().getRanks().size() > 0 ) { LinkedHashMap map = new LinkedHashMap<>(); From 4c24fd2440efc6c7e12363a0be66428a16756e61 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 24 Feb 2024 03:12:42 -0500 Subject: [PATCH 36/92] 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. --- docs/changelog_v3.3.x.md | 3 ++ .../java/tech/mcprison/prison/Prison.java | 41 ++++++++++++++++--- .../tech/mcprison/prison/output/Output.java | 8 +++- .../prison/selection/SelectionTest.java | 5 ++- .../prison/spigot/SpigotPlatform.java | 8 +++- .../mcprison/prison/spigot/SpigotPrison.java | 11 ++++- 6 files changed, 64 insertions(+), 12 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index e75ab007f..fa9c90b68 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -21,6 +21,9 @@ These change logs represent the work that has been going on within prison. **3.3.0-alpha.16b 2024-02-24** +* **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.** 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 d1ee294a2..8c8b4d5a5 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/Prison.java +++ b/prison-core/src/main/java/tech/mcprison/prison/Prison.java @@ -213,7 +213,13 @@ public LocaleManager getLocaleManager() { if ( this.localeManager == null ) { - this.localeManager = new LocaleManager(this, "lang/core"); + synchronized ( this ) { + if ( this.localeManager == null ) { + + this.localeManager = new LocaleManager(this, "lang/core"); + } + } + } return localeManager; } @@ -228,7 +234,13 @@ public LocaleManager getLocaleManager() { public File getModuleDataFolder() { if ( moduleDataFolder == null ) { - this.moduleDataFolder = Module.setupModuleDataFolder( "core" ); + if ( this.localeManager == null ) { + if ( moduleDataFolder == null ) { + + this.moduleDataFolder = Module.setupModuleDataFolder( "core" ); + + } + } } return moduleDataFolder; } @@ -237,18 +249,37 @@ public void setupJUnitInstance( Platform platform ) { this.platform = platform; } + + + + /** + * Initializes prison-core. In the implementations, this should be called when the plugin is + * enabled. After this is called, every getter in this class will return a value. + *

+ * 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; + + } + + /** * Initializes prison-core. In the implementations, this should be called when the plugin is * enabled. After this is called, every getter in this class will return a value. *

* Note that modules should not call this method. This is solely for the implementations. */ - public boolean init(Platform platform, String minecraftVersion, File dataFolder ) { + public boolean init( File dataFolder ) { long startTime = System.currentTimeMillis(); - this.platform = platform; - this.minecraftVersion = minecraftVersion; +// this.platform = platform; +// this.minecraftVersion = minecraftVersion; this.dataFolder = dataFolder; 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 82c28624a..ed904cf6d 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 @@ -142,7 +142,13 @@ private Output() { public static Output get() { if (instance == null) { - new Output(); + synchronized ( Output.class ) { + if (instance == null) { + + new Output(); + + } + } } return instance; } 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 ecf00ca7d..188c13c4a 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 @@ -48,8 +48,9 @@ public class SelectionTest { @Before public void setUp() throws Exception { TestPlatform testPlatform = new TestPlatform(temporaryFolder.newFolder("test"), false); - Prison.get() - .init(testPlatform, "1.12.X-test.1", new File("plugins/Prison")); + Prison.get().init(testPlatform, "1.13.X-test.1"); + + Prison.get().init(new File("plugins/Prison")); } @Test public void testSelection() throws Exception { 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 70eeebf09..d7348840c 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 @@ -187,14 +187,17 @@ public SpigotPlatform(SpigotPrison plugin) { this.plugin = plugin; this.scoreboardManager = new SpigotScoreboardManager(); - this.storage = initStorage(); + + + this.storage = null; +// this.storage = initStorage(); this.placeholders = new SpigotPlaceholders(); ActionBarUtil.init(plugin); } - private Storage initStorage() { + public Storage initStorage() { String confStorage = plugin.getConfig().getString("storage", "file"); Storage storage = new FileStorage(plugin.getDataDirectory()); @@ -205,6 +208,7 @@ private Storage initStorage() { "Note: In this version of Prison 3, 'file' is the only supported type of storage. We're working to bring other storage types soon."); } + this.storage = storage; return storage; } 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 1945db12c..561acbbbd 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 @@ -218,13 +218,20 @@ public void onEnable() { // prior to starting up: initCommandMap(); this.scheduler = new SpigotScheduler(this); + + + Prison.get(); SpigotPlatform platform = new SpigotPlatform(this); + + Prison.get().init( platform, Bukkit.getVersion() ); + // Initialize storage after setting the platformm in the Prison.get(): + platform.initStorage(); + // Show Prison's splash screen and setup the core components: - Prison.get() - .init( platform, Bukkit.getVersion(), getDataFolder() ); + Prison.get().init( getDataFolder() ); From fb00fa11033289811d29d4a0fd0ed09fff784513 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 24 Feb 2024 03:13:11 -0500 Subject: [PATCH 37/92] Add prison debug option to filter on blockConstraints when regenerating the blocks within the mines. --- .../main/java/tech/mcprison/prison/mines/data/MineReset.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 29f206f86..2b5d83389 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 @@ -28,6 +28,7 @@ import tech.mcprison.prison.mines.tasks.MinePagedResetAsyncTask; import tech.mcprison.prison.mines.tasks.MineTeleportTask; import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.output.Output.DebugTarget; import tech.mcprison.prison.tasks.PrisonCommandTaskData; import tech.mcprison.prison.tasks.PrisonCommandTasks; import tech.mcprison.prison.tasks.PrisonRunnable; @@ -640,7 +641,7 @@ public void generateBlockListAsync() { constraintsApplyMin(); - if ( Output.get().isDebug() ) { + if ( Output.get().isDebug() && Output.get().isSelectiveTarget( DebugTarget.blockConstraints ) ) { DecimalFormat dFmt = Prison.get().getDecimalFormatDouble(); DecimalFormat iFmt = Prison.get().getDecimalFormatInt(); From 54c927ebd6be5956c2d968e983fcb577bceffc68 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 24 Feb 2024 03:20:50 -0500 Subject: [PATCH 38/92] File saving: alternative technique for saving files. 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. --- docs/changelog_v3.3.x.md | 6 ++ .../tech/mcprison/prison/file/FileIO.java | 90 +++++++++++++++---- prison-spigot/src/main/resources/config.yml | 12 ++- 3 files changed, 89 insertions(+), 19 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index fa9c90b68..3e9d1dca5 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -21,6 +21,12 @@ These change logs represent the work that has been going on within prison. **3.3.0-alpha.16b 2024-02-24** +* **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. 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 f6564604a..67edac0ea 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 @@ -4,6 +4,7 @@ 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.Arrays; import java.util.Date; @@ -85,31 +86,86 @@ protected void saveFile( File file, String data ) // String tempFileName = file.getName() + "." + getTimestampFormat() + ".tmp"; // File tempFile = new File(file.getParentFile(), tempFileName); - try - { - // Write as a .tmp file: + boolean disableAdvancedSaves = + Prison.get().getPlatform().getConfigBooleanFalse( + "storage.file.disable-advanced-saves.enabled" ); + + if ( !disableAdvancedSaves ) { - // Add json data to lines, splitting on \n: - List lines = Arrays.asList( data.split( "\n" )); + try + { + // Write as a .tmp file: + + // Add json data to lines, splitting on \n: + List lines = Arrays.asList( data.split( "\n" )); + + // 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() ) + { + file.delete(); + } + + tempFile.renameTo( file ); + } + catch ( IOException e ) + { + logException( "Failed to create file", file, e ); + } + } + else { - // Write as an UTF-8 stream: - Files.write( tempFile.toPath(), lines, StandardCharsets.UTF_8 ); + boolean keepTempFiles = + Prison.get().getPlatform().getConfigBooleanFalse( + "storage.file.disable-advanced-saves.debug-keep-temp-files" ); + try + { + // Write as a .tmp file: + + // Add json data to lines, splitting on \n: + List lines = Arrays.asList( data.split( "\n" )); + + + // Write to both temp file and the actual file: + + // Write as an UTF-8 stream: + Files.write( tempFile.toPath(), lines, StandardCharsets.UTF_8 ); + + + StandardOpenOption sooW = StandardOpenOption.WRITE; + StandardOpenOption sooTe = StandardOpenOption.TRUNCATE_EXISTING; + + 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() ) + + // If original target exists, then delete it: +// if ( file.exists() ) +// { +// file.delete(); +// } +// +// tempFile.renameTo( file ); + + + if ( !keepTempFiles ) { + tempFile.delete(); + } + + } + catch ( IOException e ) { - file.delete(); + logException( "Failed to create file", file, e ); } - - tempFile.renameTo( file ); - } - catch ( IOException e ) - { - logException( "Failed to create file", file, e ); } + } } diff --git a/prison-spigot/src/main/resources/config.yml b/prison-spigot/src/main/resources/config.yml index b2701fd0f..88e72d001 100644 --- a/prison-spigot/src/main/resources/config.yml +++ b/prison-spigot/src/main/resources/config.yml @@ -274,10 +274,18 @@ number-format-location: en_US # The storage engine that Prison should use to store data. -# The only valid storageType is json. -storageType: "json" +# The only valid storageType is file. +storageType: "file" +# The following is experimental and should only be used if advised by a +# Prison support team member. +# +storage: + file: + disable-advanced-saves: + enabled: false + debug-keep-temp-files: false # Prison mines reset gap is the number of milliseconds that are used to From a427d38901811570cee38b62e423354dd5c9a191 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 24 Feb 2024 20:22:35 -0500 Subject: [PATCH 39/92] 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. --- docs/changelog_v3.3.x.md | 4 + .../prison/commands/CommandHandler.java | 115 ++++++++++++------ .../spigot/game/SpigotCommandSender.java | 14 ++- prison-spigot/src/main/resources/config.yml | 6 + 4 files changed, 102 insertions(+), 37 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 3e9d1dca5..ed7aa097d 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -21,6 +21,10 @@ These change logs represent the work that has been going on within prison. **3.3.0-alpha.16b 2024-02-24** +* **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. 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 e4a561769..c30b7f975 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 @@ -52,6 +52,8 @@ 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"; @@ -98,14 +100,30 @@ public CommandHandler() { registerArgumentHandler(PrisonBlock.class, new BlockArgumentHandler()); + this.rootCommmand = remapRootCmdIdentifiers( DefaultSettings.COMMAND_PRIMARY_ROOT_COMMAND ); + this.commandFallback = remapRootCmdIdentifiers( DefaultSettings.COMMAND_FALLBACK_PREFIX ); + Output.get().logInfo( "&3Root command: &7/%s &3fallback-prefix: &7%s", - DefaultSettings.COMMAND_PRIMARY_ROOT_COMMAND, DefaultSettings.COMMAND_FALLBACK_PREFIX ); + rootCommmand, commandFallback ); +// Output.get().logInfo( "&3Root command: &7/%s &3fallback-prefix: &7%s", +// DefaultSettings.COMMAND_PRIMARY_ROOT_COMMAND, DefaultSettings.COMMAND_FALLBACK_PREFIX ); } - private PermissionHandler permissionHandler = (sender, permissions) -> { + public String getRootCommmand() { + return rootCommmand; + } + + public String getCommandFallback() { + return commandFallback; + } + + + + + private PermissionHandler permissionHandler = (sender, permissions) -> { for (String perm : permissions) { if (!sender.hasPermission(perm)) { return false; @@ -290,8 +308,11 @@ public ChatDisplay getHelpMessage(CommandSender sender, RegisteredCommand comman } } - if ( command.getLabel().equalsIgnoreCase( DefaultSettings.COMMAND_PRIMARY_ROOT_COMMAND ) && + + 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 ) { @@ -367,19 +388,20 @@ private ArrayList buildHelpRootCommands() { ArrayList message = new ArrayList<>(); message.add(ChatColor.DARK_AQUA + "Root Commands:"); - // Force a sorting by use of a TreeSet. Collections.sort() would not work. - TreeSet rootCommandSet = new TreeSet<>(); - // 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) ) { + // Force a sorting by use of a TreeSet. Collections.sort() would not work. + TreeSet rootCommandSet = new TreeSet<>(); + + // 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() ) { // @@ -391,22 +413,22 @@ private ArrayList buildHelpRootCommands() { // new StringBuilder().append( ChatColor.DARK_AQUA ). // append( "Aliases: " ).append( ChatColor.AQUA )); // } - String rootCmd = - String.format( "%s %s", - rootKey.getUsage(), sbAliases.toString() ); - - rootCommandSet.add( rootCmd ); - } + 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; + } /** * This builds a list of all the aliases that exist. @@ -647,11 +669,15 @@ private RegisteredCommand commandRegisterConfig( Method method, Command commandA private RegisteredCommand commandRegisterConfig( Method method, Command commandAnno, Object methodInstance, String alias ) { - String[] identifiers = ( alias == null ? commandAnno.identifier() : alias).split(" "); + + String cmdIdentifiers = remapRootCmdIdentifiers( commandAnno.identifier() ); + String cmdAlias = remapRootCmdIdentifiers( alias ); + + String[] identifiers = ( cmdAlias == null ? cmdIdentifiers : cmdAlias).split(" "); - if (identifiers.length == 0) { - throw new RegisterCommandMethodException(method, "Invalid identifiers"); - } + if (identifiers.length == 0) { + throw new RegisterCommandMethodException(method, "Invalid identifiers"); + } String label = identifiers[0]; @@ -738,7 +764,28 @@ private RegisteredCommand commandRegisterConfig( Method method, Command commandA } - public static String[] addConfigAliases( String label, String[] aliases ) + 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)); + } + } + + return identifier; + } + + public static String[] addConfigAliases( String label, String[] aliases ) { String[] results = aliases; 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 8e4b0d890..104f7c775 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 @@ -29,6 +29,7 @@ import tech.mcprison.prison.Prison; import tech.mcprison.prison.PrisonAPI; +import tech.mcprison.prison.commands.CommandHandler; import tech.mcprison.prison.integration.PermissionIntegration; import tech.mcprison.prison.internal.CommandSender; import tech.mcprison.prison.internal.Player; @@ -68,12 +69,19 @@ public String getName() { * it then uses the mapped command. *

*/ - @Override public void dispatchCommand(String command) { - String registeredCmd = Prison.get().getCommandHandler().findRegisteredCommand( command ); + @Override + public void dispatchCommand(String command) { + + command = CommandHandler.remapRootCmdIdentifiers( command ); + + String registeredCmd = Prison.get().getCommandHandler() + .findRegisteredCommand( command ); + Bukkit.getServer().dispatchCommand(bukkitSender, registeredCmd); } - @Override public boolean doesSupportColors() { + @Override + public boolean doesSupportColors() { return (this instanceof ConsoleCommandSender) && Bukkit.getConsoleSender() != null; } diff --git a/prison-spigot/src/main/resources/config.yml b/prison-spigot/src/main/resources/config.yml index 88e72d001..db8394e8d 100644 --- a/prison-spigot/src/main/resources/config.yml +++ b/prison-spigot/src/main/resources/config.yml @@ -479,6 +479,12 @@ prisonCommandHandler: exclude-worlds: - miniGameWorld - playerPlotWorld + command-roots: + prison: prison + mines: mines + ranks: ranks + gui: gui + sellall: sellall disable-player-placeholders-in-excluded-worlds: false exclude-non-ops: exclude-related-aliases: true From 355eb611fe918fc3833143fca90230bc6a59f73b Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 24 Feb 2024 20:41:44 -0500 Subject: [PATCH 40/92] Import Mines: Added the ability to import mines from JetPrisonMines config files. --- docs/changelog_v3.3.x.md | 4 + .../prison/internal/platform/Platform.java | 7 + .../tech/mcprison/prison/TestPlatform.java | 12 +- .../prison/mines/commands/MinesCommands.java | 43 +- .../mines/commands/MinesImportCommands.java | 381 ++++++++++++++++++ .../mcprison/prison/mines/data/MineData.java | 21 +- .../mines/features/MineLinerBuilder.java | 13 +- .../prison/spigot/SpigotPlatform.java | 110 ++++- .../mcprison/prison/spigot/SpigotPrison.java | 9 + 9 files changed, 587 insertions(+), 13 deletions(-) create mode 100644 prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesImportCommands.java diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index ed7aa097d..729343f5d 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -21,6 +21,10 @@ These change logs represent the work that has been going on within prison. **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. 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 d0ac90ea1..fc11e767a 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 @@ -359,6 +359,9 @@ public void autoCreateMineLinerAssignment( List rankMineNames, boolean forceLinersBottom, boolean forceLinersWalls ); + public String autoCreateMineLinerAssignment(ModuleElement eMine, + boolean forceLinersBottom, boolean forceLinersWalls); + public void autoCreateConfigureMines(); @@ -477,4 +480,8 @@ public void autoCreateMineLinerAssignment( List rankMineNames, public String getRankByFileName(String name); + + public Map loadYaml(File file); + + } 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 a1d5ca6d6..ad688cbd5 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/TestPlatform.java +++ b/prison-core/src/test/java/tech/mcprison/prison/TestPlatform.java @@ -385,7 +385,13 @@ public void autoCreateMineLinerAssignment( List rankMineNames, boolean forceLinersBottom, boolean forceLinersWalls ) { } - + + @Override + public String autoCreateMineLinerAssignment(ModuleElement eMine, + boolean forceLinersBottom, boolean forceLinersWalls) { + return null; + } + @Override public void autoCreateConfigureMines() { @@ -562,4 +568,8 @@ public String getLadderByFileName(String name) { public String getRankByFileName(String name) { return "a"; } + + public Map loadYaml(File file) { + return new TreeMap(); + } } 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 b49e41977..f5a54fe79 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 MinesBlockCommands { + extends MinesImportCommands { public MinesCommands() { super( "MinesCommands" ); @@ -94,6 +94,47 @@ public void minesSetSubcommands(CommandSender sender) { } + /* + * NOTE: The mines import commands are from the class MinesImportCommands. + * The command handler setups is 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" ); + } + + @Command(identifier = "mines import jetsPrisonMines", + description = "Imports mines that were created within the plugin JetsPrisonMines. " + + "Most settings will be brought over to prison. If the mine already " + + "exits within prison, it will be skipped. First run this command " + + "without the option 'save' to confirm what can be imported." + + " Prison will use the path " + + "'JetsPrisonMines/mines/' to search for all yaml files that are " + + "used to store the mine configs, but his can be overridden with the " + + "'path=' option. Use the option 'world=' to save to a different world " + + "which can be useful if the world does not exist on your server. " + + "", + onlyPlayers = true, permissions = "mines.set") + public void minesImportJetsPrisonMines( CommandSender sender, + @Wildcard(join=true) + @Arg(name = "options", + description = "Options. The following options can customize how prison will perform " + + "the imports. [addLiner path= world= save] " + + "'addLiner' will randomly generate a liner for each mine. " + + "'path=' the default path is 'JetsPrisonMines/mines/' and " + + "this option will override this path. " + + "'world=' is the world name to use for mine and spawn placemments, " + + "which will override the yaml file's world even if it exists on the server. " + + "'save' must be specified or the imported mines will not be saved.") + String options ) { + + super.importJetsPrisonMines(sender, options); + } + + /* * NOTE: Block commands from the class MinesBlockCommands need to have the "command" references here * so the prison command handler can pick them up properly. 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 new file mode 100644 index 000000000..ddb5e7088 --- /dev/null +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesImportCommands.java @@ -0,0 +1,381 @@ +package tech.mcprison.prison.mines.commands; + +import java.io.File; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import tech.mcprison.prison.Prison; +import tech.mcprison.prison.internal.CommandSender; +import tech.mcprison.prison.internal.World; +import tech.mcprison.prison.internal.block.PrisonBlock; +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.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; + +public class MinesImportCommands + extends MinesBlockCommands { + + + 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(); +// } + + if ( options.contains( "save" ) ) { + save = true; + options = options.replace( "save", "" ).trim(); + } + + if ( options.contains( "addLiner" ) ) { + addLiner = true; + options = options.replace( "addLiner", "" ).trim(); + } + + String pathStr = extractParameter("path=", options); + if ( pathStr != null ) { + options = options.replace( pathStr, "" ); + pathStr = pathStr.replace( "path=", "" ).trim(); + + path = pathStr; + } + + String worldStr = extractParameter("world=", options); + if ( worldStr != null ) { + options = options.replace( worldStr, "" ); + worldStr = worldStr.replace( "world=", "" ).trim(); + + worldForced = worldStr; + } + + File dirPlugins = Prison.get().getPlatform().getPluginDirectory().getParentFile(); + File dirMines = new File( dirPlugins, path ); + + if ( !dirMines.exists() || !dirMines.isDirectory() ) { + sender.sendMessage( + String.format( + "Error: The path for JetsPrisonMines' mines does not exist: '%s'", + dirMines.getAbsolutePath() ) ); + + return; + } + + DecimalFormat iFmt = Prison.get().getDecimalFormatInt(); + List files = Arrays.asList( dirMines.listFiles() ); + + PrisonMines pMines = PrisonMines.getInstance(); + + sender.sendMessage( + String.format( + "Prison import from JetsPrisonMines' mines: '%s'", + dirMines.getAbsolutePath() ) ); + sender.sendMessage( + String.format( + "Mines to import: '%d'", + files.size() ) ); + + int alreadyExists = 0; + int failed = 0; + int saved = 0; + int savable = 0; + + for ( File f : files ) { + + if ( f.exists() && f.isFile() ) { + + Mine mine = convertJetsPrisonMines( f, worldForced ); + + String status = ""; + if ( mine == null ) { + failed++; + status = "(failed)"; + } + else if ( pMines.getMine( mine.getName() ) != null ) { + alreadyExists++; + status = "(alreadyExists)"; + } + else if ( save ) { + pMines.getMineManager().add(mine); + pMines.getMineManager().saveMine( mine ); + + if ( addLiner ) { + Prison.get().getPlatform().autoCreateMineLinerAssignment( + mine, true, true ); + } + + saved++; + status = "(saved)"; + } + else { + savable++; + status = "(savable)"; + } + + sender.sendMessage( + String.format( + " %-14s %7s bytes %s", + f.getName(), iFmt.format(f.length()), + status ) ); + } + } + + if ( addLiner ) { + List mines = new ArrayList<>(); + + 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 ); + } + + } + } + } + + sender.sendMessage( + String.format( + "Impored Mines: Saved: %d AlreadyExists: %d Saveable: %d Failed: %d", + saved, alreadyExists, savable, failed )); + } + + + + + private Mine convertJetsPrisonMines(File f, String worldForced ) { + Mine mine = null; + + Map yaml = null; + + try { + yaml = Prison.get().getPlatform().loadYaml( f ); + + String mineName = (String) yaml.get( "mine_name" ); + + + List blocks = getYamlListString( yaml, "blocks" ); + + String spawnWorld = worldForced != null && worldForced.length() > 0 ? + worldForced : + getYamlString( yaml, "teleport_location.world" ); + double spawnX = getYamlDouble( yaml, "teleport_location.x" ); + double spawnY = getYamlDouble( yaml, "teleport_location.y" ); + double spawnZ = getYamlDouble( yaml, "teleport_location.z" ); + double spawnPitch = getYamlDouble( yaml, "teleport_location.pitch" ); + double spawnYaw = getYamlDouble( yaml, "teleport_location.yaw" ); + + String locWorld = worldForced != null && worldForced.length() > 0 ? + worldForced : + getYamlString( yaml, "region.world" ); + double xMin = getYamlInteger( yaml, "region.xmin" ); + double yMin = getYamlInteger( yaml, "region.ymin" ); + double zMin = getYamlInteger( yaml, "region.zmin" ); + double xMax = getYamlInteger( yaml, "region.xmax" ); + double yMax = getYamlInteger( yaml, "region.ymax" ); + double zMax = getYamlInteger( yaml, "region.zmax" ); + + + boolean rUseTimer = getYamlBoolean( yaml, "reset.use_timer" ); + int rTimer = getYamlInteger( yaml, "reset.timer" ); + boolean rUsePercentage = getYamlBoolean( yaml, "reset.use_percentage" ); + double rPercentage = getYamlDouble( yaml, "reset.percentage" ); + + boolean rUseMessages = getYamlBoolean( yaml, "reset.use_messages" ); + int rBlocksMined = getYamlInteger( yaml, "reset.blocks_mined" ); + + + World sWorld = Prison.get().getPlatform().getWorld( spawnWorld ).orElse(null); + Location spawn = new Location( sWorld, spawnX, spawnY, spawnZ, + (float) spawnPitch, (float) spawnYaw ); + + + World lWorld = Prison.get().getPlatform().getWorld( locWorld ).orElse(null); + Location locMin = new Location( lWorld, xMin, yMin, zMin ); + Location locMax = new Location( lWorld, xMax, yMax, zMax ); + Selection mSel = new Selection( locMin, locMax); + + + boolean logInfo = false; + mine = new Mine( mineName, mSel, MineType.primary, logInfo ); + + String tag = "&5[&d+" + mineName + "&5]"; + mine.setTag( tag ); + + mine.setHasSpawn( false ); + + if ( spawn != null ) { + mine.setSpawn( spawn ); + mine.setHasSpawn( true ); + } + + if ( rUseTimer ) { + // reset time in seconds: + int time = rTimer * 60; + mine.setResetTime(time); + } + else { + // value of -1 disables resets by time: + mine.setResetTime( -1 ); + } + + if ( rUsePercentage ) { + mine.setResetThresholdPercent( rPercentage ); + } + + if ( rUseMessages ) { + mine.setNotificationMode( MineNotificationMode.within ); + } + else { + mine.setNotificationMode( MineNotificationMode.disabled ); + } + + mine.setBlockBreakCount(rBlocksMined); + + PrisonBlockTypes prisonBlockTypes = Prison.get().getPlatform().getPrisonBlockTypes(); + + for (String blockDetails : blocks) { + + String[] bd = blockDetails.split( ":" ); + + String blockName = bd.length > 0 ? bd[0] : null; + String chanceStr = bd.length > 1 ? bd[1] : "1.0"; + + PrisonBlock prisonBlock = prisonBlockTypes.getBlockTypesByName( blockName ); + + if ( prisonBlock != null ) { + + double chance = 1.0; + + try { + chance = Double.parseDouble(chanceStr); + } + catch (NumberFormatException e) { + } + + prisonBlock.setChance( chance ); + + mine.addPrisonBlock( prisonBlock ); + } + } + + + // Check if one of the blocks is effected by gravity, and if so, set that indicator. + mine.checkGravityAffectedBlocks(); + } + catch (Exception e) { + + String message = String.format( "Could not %s: %s [%s]", + (yaml == null ? "parse mine file" : + mine == null ? "generate mine" : + "fully configure mine"), + f.getName(), + e.getMessage()); + Output.get().logInfo( message ); + } + + return mine; + } + + private String getYamlString( Map yaml, String key ) { + String results = null; + + try { + results = (String) yaml.get( key ); + } + catch (Exception e) { + } + + return results; + } + private double getYamlDouble( Map yaml, String key ) { + double results = 0; + + try { + results = (Double) yaml.get( key ); + } + catch (Exception e) { + } + + return results; + } + private int getYamlInteger( Map yaml, String key ) { + int results = 0; + + try { + results = (Integer) yaml.get( key ); + } + catch (Exception e) { + } + + return results; + } + private boolean getYamlBoolean( Map yaml, String key ) { + boolean results = false; + + try { + results = (Boolean) yaml.get( key ); + } + catch (Exception e) { + } + + return results; + } + @SuppressWarnings("unchecked") + private List getYamlListString( Map yaml, String key ) { + List results = new ArrayList<>(); + + try { + results = new ArrayList<>( (List) yaml.get(key) ); + } + catch (Exception e) { + } + + return results; + } + +} + \ No newline at end of file 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 703fbe3e7..ab62c20f4 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 @@ -406,6 +406,10 @@ public Bounds getBounds() { return bounds; } + public void setBounds(Bounds bounds ) { + setBounds( bounds, true ); + } + /** *

(Re)defines the boundaries for this mine. *

@@ -427,7 +431,7 @@ public Bounds getBounds() { * * @param bounds the new boundaries */ - public void setBounds(Bounds bounds) { + 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: @@ -454,7 +458,10 @@ else if ( isVirtual() || !getWorld().isPresent() || setVirtual( false ); setEnabled( true ); - Output.get().logInfo( "&7Mine " + getTag() + "&7: world has been set and is now enabled." ); + if ( logInfo ) { + Output.get().logInfo( "&7Mine " + getTag() + "&7: world has been set and is now enabled." ); + } + } else { setEnabled( false ); @@ -1084,14 +1091,20 @@ public void setHasSpawn( boolean hasSpawn ) { this.hasSpawn = hasSpawn; } - /* + /** *

This is the reset time for the mine, in seconds. * A value of -1 means no timed resets. They will have to be done manually. *

- */ + **/ public int getResetTime() { return resetTime; } + /** + *

This is the reset time for the mine, in seconds. + * A value of -1 means no timed resets. They will have to be done manually. + *

+ * @param resetTime + */ public void setResetTime( int resetTime ) { this.resetTime = resetTime; } 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 250e24613..2e6430a58 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 @@ -175,7 +175,8 @@ protected MineLinerBuilder() { } - public MineLinerBuilder( Mine mine, Edges edge, LinerPatterns pattern, boolean isForced ) { + public MineLinerBuilder( Mine mine, Edges edge, LinerPatterns pattern, + boolean isForced, boolean useTracer ) { super(); this.pattern3d = new ArrayList<>(); @@ -193,12 +194,20 @@ public MineLinerBuilder( Mine mine, Edges edge, LinerPatterns pattern, boolean i this.isForced = isForced; if ( pattern != null ) { - mine.enableTracer( MineResetType.clear ); + if ( useTracer ) { + + mine.enableTracer( MineResetType.clear ); + } generatePattern( edge ); } } + public MineLinerBuilder( Mine mine, Edges edge, LinerPatterns pattern, boolean isForced ) { + this( mine, edge, pattern, isForced, true ); + + } + private void generatePattern( Edges edge ) { World world = getLiner().getMin().getWorld(); 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 d7348840c..57b5c8518 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 @@ -19,6 +19,9 @@ package tech.mcprison.prison.spigot; import java.io.File; +import java.io.IOException; +import java.io.StringReader; +import java.nio.file.Files; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Collections; @@ -1767,25 +1770,48 @@ public void autoCreateMineLinerAssignment( List rankMineNames, for ( String mineName : rankMineNames ) { Mine mine = mm.getMine( mineName ); + + String msg = + autoCreateMineLinerAssignment( mine, forceLinersBottom, forceLinersWalls ); + if ( msg != null ) { + + Output.get().logInfo( msg ); + } + } + } + + @Override + public String autoCreateMineLinerAssignment( ModuleElement eMine, + boolean forceLinersBottom, boolean forceLinersWalls ) { + String message = null; + + if ( eMine instanceof Mine ) { + + MineManager mm = PrisonMines.getInstance().getMineManager(); +// List mines = mm.getMines(); + + Mine mine = (Mine) eMine; + String mineLinerData = mine.getLinerData().toSaveString(); boolean createLiner = mineLinerData.trim().isEmpty(); if ( createLiner ) { mine.getLinerData().setLiner( Edges.walls, getRandomLinerType(), forceLinersWalls ); mine.getLinerData().setLiner( Edges.bottom, getRandomLinerType(), forceLinersBottom ); - + mineLinerData = mine.getLinerData().toSaveString(); mm.saveMine( mine ); } - - String message = String.format( "Mine Liner status: %s %s : %s", + + message = String.format( "Mine Liner status: %s %s : %s", mine.getName(), (createLiner ? "(Created)" : "(AlreadyExists)"), mineLinerData ); - Output.get().logInfo( message ); - } + } + + return message; } private LinerPatterns getRandomLinerType() { @@ -3360,4 +3386,78 @@ public String getRankByFileName(String name) { return results; } + + /** + * This loadYaml function will load only text based yaml files, but if the + * file contains a class serialization (prefixed with '==:') then it will + * purge all references to such classes so the data is loaded as plain text. + */ + @Override + public Map loadYaml( File file ) { + Map values = null; + + try { + List lines = Files.readAllLines( file.toPath() ); + + StringBuilder sb = new StringBuilder(); + for (String line : lines ) { + // remove object mapping from yaml files: + if ( !line.startsWith(" ==: " ) ) { + sb.append( line ).append( "\n" ); + } + } + + try ( + StringReader sr = new StringReader( sb.toString() ); + ) + { + YamlConfiguration yaml = SpigotPrison.getInstance().loadExternalConfig( sr ); + + if ( yaml != null ) { + values = yaml.getValues( true ); + } + + } + + } + catch (IOException e1) { + e1.printStackTrace(); + } + +// try { +// Class worldClass = Class.forName( "org.bukkit.World" ); +// YamlConfiguration yaml = SpigotPrison.getInstance().loadExternalConfig( file ); +// +// if ( yaml != null ) { +// values = yaml.getValues( true ); +// +// +// if ( yaml.contains( "teleport_location" ) ) { +// +// org.bukkit.Location loc = +// (org.bukkit.Location) yaml.getObject( +// "teleport_location", org.bukkit.Location.class ); +// +// org.bukkit.World world = loc.getWorld(); +// +// if ( loc != null ) { +// values.put( "teleport_location.world", world.getName() ); +// values.put( "teleport_location.x", Double.valueOf( loc.getX()) ); +// values.put( "teleport_location.y", Double.valueOf( loc.getY()) ); +// values.put( "teleport_location.z", Double.valueOf( loc.getZ()) ); +// values.put( "teleport_location.pitch", Double.valueOf( loc.getPitch()) ); +// values.put( "teleport_location.yaw", Double.valueOf( loc.getYaw()) ); +// +// } +// } +// } +// +// } catch (ClassNotFoundException e) { +// // TODO Auto-generated catch block +// e.printStackTrace(); +// } + + + return values; + } } 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 561acbbbd..8d5b1d05b 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 @@ -20,6 +20,7 @@ import java.io.File; import java.io.IOException; +import java.io.Reader; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; @@ -1337,6 +1338,14 @@ public YamlConfiguration loadConfig(String file) { return YamlConfiguration.loadConfiguration(getBundledFile(file)); } + public YamlConfiguration loadExternalConfig(File file) { + return YamlConfiguration.loadConfiguration( file ); + } + + public YamlConfiguration loadExternalConfig( Reader reader ) { + return YamlConfiguration.loadConfiguration( reader ); + } + public void saveConfig(String fileName, YamlConfiguration config ) { if ( config != null ) { File file = getBundledFile(fileName); From 3288a0c760f021b2b03d982f32a3dc945c03f820 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 24 Feb 2024 20:50:55 -0500 Subject: [PATCH 41/92] Import Mines: Added the ability to import mines from JetPrisonMines config files. --- .../mines/commands/MinesCoreCommands.java | 21 +++++++++++++++++++ .../tech/mcprison/prison/mines/data/Mine.java | 9 ++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesCoreCommands.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesCoreCommands.java index 7e82c09a5..238d71e59 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesCoreCommands.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesCoreCommands.java @@ -78,4 +78,25 @@ public String formatStringPadRight( String text, int totalLength, Object... args return sb.toString(); } + + protected String extractParameter( String key, String options ) { + return extractParameter( key, options, true ); + } + + protected String extractParameter( String key, String options, boolean tryLowerCase ) { + String results = null; + int idx = options.indexOf( key ); + if ( idx != -1 ) { + int idxEnd = options.indexOf( " ", idx ); + if ( idxEnd == -1 ) { + idxEnd = options.length(); + } + results = options.substring( idx, idxEnd ); + } + else if ( tryLowerCase ) { + // try again, but lowercase the key + results = extractParameter( key.toLowerCase(), options, false ); + } + return results; + } } 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 2b225d881..19d422f1f 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 @@ -113,7 +113,7 @@ public Mine(String name, Selection selection) { this( name, selection, MineType.primary ); } - public Mine(String name, Selection selection, MineType mineType) { + public Mine(String name, Selection selection, MineType mineType, boolean logInfo ) { super(); setName(name); @@ -125,7 +125,7 @@ public Mine(String name, Selection selection, MineType mineType) { } else { - setBounds(selection.asBounds()); + setBounds(selection.asBounds(), logInfo ); setWorldName( getBounds().getMin().getWorld().getName()); @@ -136,6 +136,11 @@ public Mine(String name, Selection selection, MineType mineType) { initialize(); } + public Mine(String name, Selection selection, MineType mineType) { + this( name, selection, mineType, true ); + + } + /** *

Loads a mine from a document. *

From df44436913e06a96db931fd0272d213ec512b138 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 26 Feb 2024 03:31:56 -0500 Subject: [PATCH 42/92] 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. --- docs/changelog_v3.3.x.md | 8 +- .../prison/internal/CommandSender.java | 4 + .../prison/ranks/data/RankPlayer.java | 8 ++ .../java/tech/mcprison/prison/TestPlayer.java | 5 + .../prison/ranks/commands/RanksCommands.java | 5 + .../spigot/game/SpigotCommandSender.java | 17 +++ .../spigot/game/SpigotOfflinePlayer.java | 19 +++ .../prison/spigot/sellall/SellAllUtil.java | 121 +++++++++++++++--- 8 files changed, 171 insertions(+), 16 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 729343f5d..e02f156df 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.16b 2024-02-20 +# 3.3.0-alpha.16b 2024-02-26 + + + +* **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. 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 de11fcc05..19ee168ab 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 @@ -18,6 +18,8 @@ package tech.mcprison.prison.internal; +import java.util.List; + /** * Represents any entity that may send commands and receive output. * @@ -90,4 +92,6 @@ public interface CommandSender public boolean isPlayer(); + List getSellAllMultiplierListings(); + } 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 06af55f65..cbf7a1272 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 @@ -1826,6 +1826,14 @@ public void setRankScorePenalty( double rankScorePenalty ) { this.rankScorePenalty = rankScorePenalty; } + @Override + public List getSellAllMultiplierListings() { + + Player player = Prison.get().getPlatform().getPlayer(getUUID()).orElse(null); + + return player == null ? new ArrayList<>() : player.getSellAllMultiplierListings(); + } + // 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 7ef2a4d27..113270066 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/TestPlayer.java +++ b/prison-core/src/test/java/tech/mcprison/prison/TestPlayer.java @@ -251,5 +251,10 @@ public void incrementMinecraftStatsMineBlock( Player player, String blockName, i public void incrementMinecraftStatsDropCount( Player player, String blockName, int quantity) { } + + @Override + public List getSellAllMultiplierListings() { + return new ArrayList<>(); + } } 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 3dcb370cd..ee97cad9f 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 @@ -1763,6 +1763,11 @@ public void rankPlayer(CommandSender sender, msgs.add( messageSellallMultiplier ); // sendToPlayerAndConsole( sender, messageSellallMultiplier ); + List sellallDetails = player.getSellAllMultiplierListings(); + for (String sellallDetail : sellallDetails) { + msgs.add( " " + sellallDetail ); + } + msgs.add( "" ); 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 104f7c775..ea04397af 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 @@ -184,6 +184,23 @@ public double getSellAllMultiplier() { // 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; + } + public List getPermissionsIntegrations( boolean detailed ) { 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 044dc3dab..c840c0649 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 @@ -20,6 +20,8 @@ import tech.mcprison.prison.output.Output; import tech.mcprison.prison.ranks.PrisonRanks; import tech.mcprison.prison.ranks.data.RankPlayer; +import tech.mcprison.prison.spigot.SpigotPrison; +import tech.mcprison.prison.spigot.sellall.SellAllUtil; import tech.mcprison.prison.util.Gamemode; import tech.mcprison.prison.util.Location; @@ -320,6 +322,23 @@ public double getSellAllMultiplier() { 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; + } + @Override public void setTitle( String title, String subtitle, int fadeIn, int stay, int fadeOut ) { } 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 25c44ac94..fdc2ae0c5 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 @@ -7,6 +7,7 @@ import java.util.HashMap; import java.util.List; import java.util.Optional; +import java.util.Set; import org.bukkit.Bukkit; import org.bukkit.Sound; @@ -29,6 +30,7 @@ import tech.mcprison.prison.ranks.PrisonRanks; import tech.mcprison.prison.ranks.data.PlayerRank; import tech.mcprison.prison.ranks.data.Rank; +import tech.mcprison.prison.ranks.data.RankLadder; import tech.mcprison.prison.ranks.data.RankPlayer; import tech.mcprison.prison.sellall.messages.SpigotVariousGuiMessages; import tech.mcprison.prison.spigot.SpigotPrison; @@ -401,34 +403,37 @@ public HashMap getPrestigeMultipliers() { public double getPlayerMultiplier(Player p){ if (!isSellAllMultiplierEnabled){ - return 1; + return 1d; } // long tPoint1 = System.nanoTime(); -// // Get Ranks module. -// ModuleManager modMan = Prison.get().getModuleManager(); -// Module module = modMan == null ? null : modMan.getModule(PrisonRanks.MODULE_NAME).orElse(null); SpigotPlayer sPlayer = new SpigotPlayer(p); - double multiplier = defaultMultiplier; + double multiplier = 0d; + if ( PrisonRanks.getInstance() != null && PrisonRanks.getInstance().isEnabled() ) { RankPlayer rPlayer = sPlayer.getRankPlayer(); -// rPlayer.getSellAllMultiplier(); // NOTE: This actually calls this function - PlayerRank pRank = rPlayer.getPlayerRankPrestiges(); - Rank rank = pRank == null ? null : pRank.getRank(); - if ( pRank != null ) { - String rankName = rank.getName(); + 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 )){ - multiplier = sellAllPrestigeMultipliers.get( rankName ); + multiplier += sellAllPrestigeMultipliers.get( rankName ); } - } - + } } + if ( multiplier == 0 ) { + multiplier = defaultMultiplier; + } + + + // long tPoint2 = System.nanoTime(); @@ -463,10 +468,13 @@ public double getPlayerMultiplier(Player p){ List perms = sPlayer.getPermissions("prison.sellall.multiplier."); double multiplierExtraByPerms = 0; for (String multByPerm : perms) { + double multByPermDouble = Double.parseDouble(multByPerm.substring(26)); - if (!isSellAllPermissionMultiplierOnlyHigherEnabled) { + + if ( !isSellAllPermissionMultiplierOnlyHigherEnabled ) { multiplierExtraByPerms += multByPermDouble; - } else if (multByPermDouble > multiplierExtraByPerms) { + } + else if (multByPermDouble > multiplierExtraByPerms) { multiplierExtraByPerms = multByPermDouble; } } @@ -483,6 +491,89 @@ public double getPlayerMultiplier(Player p){ 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; + } + + // /** // * 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, From 456d298adf3e9d3fb8e6a6ad1f1667b5b33d7656 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 26 Feb 2024 03:34:33 -0500 Subject: [PATCH 43/92] 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=' --- docs/changelog_v3.3.x.md | 3 ++ .../resources/lang/mines/de_DE.properties | 3 +- .../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 | 3 +- .../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 | 3 +- .../resources/lang/mines/zh_TW.properties | 3 +- .../mcprison/prison/mines/data/MineReset.java | 7 ++- .../mcprison/prison/mines/data/MineTasks.java | 51 +++++++++++++++++++ 16 files changed, 86 insertions(+), 14 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index e02f156df..e8fd732a2 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.16b 2024-02-26 +* **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. 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 da99ff80f..502cddbd9 100644 --- a/prison-core/src/main/resources/lang/mines/de_DE.properties +++ b/prison-core/src/main/resources/lang/mines/de_DE.properties @@ -60,7 +60,7 @@ # -messages__version=4 +messages__version=5 messages__auto_refresh=true @@ -69,6 +69,7 @@ messages__auto_refresh=true reset_warning=&7Alle Minen %1 wurden zurückgesetzt in &3%2&7. reset_message=&7Alle Minen %1 wurden zurückgesetzt. +skip_reset_message= not_allowed=&7Hier darfst du nicht verminen. autosmelt_enable=&bAutosmelt &7wurde aktiviert. autosmelt_disable=&bAutosmelt &7wurde deaktiviert. 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 d7c409967..b21d897fe 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=4 +messages__version=5 messages__auto_refresh=true @@ -69,6 +69,7 @@ messages__auto_refresh=true reset_warning=&7Mine %1 will reset in &3%2&7. reset_message=&7The mine %1 has been reset. +skip_reset_message= not_allowed=&7You are not allowed to mine here. autosmelt_enable=&bAutosmelt &7has been &aenabled&7. autosmelt_disable=&bAutosmelt &7has been &cdisabled&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 11692e63a..e2baf94f9 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=4 +messages__version=5 messages__auto_refresh=true @@ -69,6 +69,7 @@ messages__auto_refresh=true 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= not_allowed=&7No tienes permitido minar aquí. autosmelt_enable=&7La &bFundición Automática &7ha sido &aactivada&7. autosmelt_disable=&7La &bFundición Automática &7ha sido &cdesactivada&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 4d8607849..a17a07eae 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=4 +messages__version=5 messages__auto_refresh=true @@ -69,6 +69,7 @@ messages__auto_refresh=true reset_warning=&7Mine %1 resettaa &3%2&7. reset_message=&7mine %1 on resetattu. +skip_reset_message= not_allowed=&7Et voi mainata täällä. autosmelt_enable=&bAutosmelt &7on &akäytössä&7. autosmelt_disable=&bAutosmelt &7on &cdisabloitu&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 d6cf696c7..fccacf7cb 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=4 +messages__version=5 messages__auto_refresh=true @@ -69,6 +69,7 @@ messages__auto_refresh=true reset_warning=&7La mine %1 va se réinitialiser dans &3%2&7. reset_message=&7La mine %1 a été réinitialisée. +skip_reset_message= not_allowed=&7Tu n'es pas autorisé à miner ici. autosmelt_enable=&bL'Autosmelt &7a été &aactivé&7. autosmelt_disable=&bL'Autosmelt &7a été &cdésactivé&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 e1d896577..cd2424220 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=4 +messages__version=5 messages__auto_refresh=true @@ -69,6 +69,7 @@ messages__auto_refresh=true reset_warning=&7Minden %1 bánya újratöltve &3%2&7. reset_message=&7Az összes %1 bánya vissza lett állítva. +skip_reset_message= not_allowed=&7A bányászás nem megengedett. autosmelt_enable=&bAz auto. égetés &7engedélyezve. autosmelt_disable=&bAz auto. égetés &7letiltva. 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 e3e9aea98..2c5b126ff 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=4 +messages__version=5 messages__auto_refresh=true @@ -69,6 +69,7 @@ messages__auto_refresh=true reset_warning=&7Tutte le miniere %1 stanno per essere resettate tra &3%2&7. reset_message=&7Tutte le miniere %1 sono state resettate. +skip_reset_message= not_allowed=&7Non sei ammesso a scvare qua. autosmelt_enable=&bAutoFusione &7è stata &aabilitata&7. autosmelt_disable=&bAutoFusione &7è stata &cdisabilitata&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 e56e952e1..41c35aa61 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=4 +messages__version=5 messages__auto_refresh=true @@ -69,6 +69,7 @@ messages__auto_refresh=true reset_warning=&7Alle mijnen %1 worden hersteld in &3%2&7. reset_message=&7Alle mijnen %1 zijn hersteld. +skip_reset_message= not_allowed=&7Je mag hier niet mijnen. autosmelt_enable=&bAutosmelt &7is aangezet. autosmelt_disable=&bAutosmelt &7is afgezet. 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 3ae2e01cb..b93443167 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=4 +messages__version=5 messages__auto_refresh=true @@ -69,6 +69,7 @@ messages__auto_refresh=true reset_warning=&Alle mijnen %1 worden hersteld in &3%2&7. reset_message=&7Alle mijnen %1 zijn hersteld. +skip_reset_message= not_allowed=&7Je mag hier niet mijnen. autosmelt_enable=&bAutosmelt &7is aangezet. autosmelt_disable=&bAutosmelt &7is afgezet. 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 ede5b9ef7..af7aa2c7b 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=4 +messages__version=5 messages__auto_refresh=true @@ -69,6 +69,7 @@ messages__auto_refresh=true reset_warning=&7A Mina %1 vai resetar em &3%2&7. reset_message=&7A mina %1 resetou. +skip_reset_message= not_allowed=&7Não podes minerar aqui. autosmelt_enable=&bAutosmelt &7foi &aativado&7. autosmelt_disable=&bAutosmelt &7foi &cdisativado&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 97432e42f..cfb6d17c9 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=4 +messages__version=5 messages__auto_refresh=true @@ -69,6 +69,7 @@ messages__auto_refresh=true reset_warning=&7Mina %1 va fi resetată &3%2&7. reset_message=&7Mina %1 a fost resetată. +skip_reset_message= not_allowed=&7Nu ai voie să minezi aici. autosmelt_enable=&bAutosmelt-ul &7a fost &aactivat&7. autosmelt_disable=&bAutosmelt-ul &7a fost &cdezactivat&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 29973987e..d5e632a9b 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=3 +messages__version=4 messages__auto_refresh=true @@ -69,6 +69,7 @@ messages__auto_refresh=true reset_warning=&7矿区%1将在&3%2分钟åŽ&7é‡ç½® reset_message=&7矿区%1å·²ç»é‡ç½® +skip_reset_message= not_allowed=&7你没有在此处挖矿所需è¦çš„æƒé™ autosmelt_enable=&bAutoMelt&7å·²å¯ç”¨&7 autosmelt_disable=&bAutoMelt&7å·²ç¦ç”¨&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 1ad538fbb..78a6e3e5d 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=5 +messages__version=6 messages__auto_refresh=true @@ -69,6 +69,7 @@ messages__auto_refresh=true reset_warning=&7礦場 %1 將在 &3%2&7 分é˜å¾Œé‡ç½® reset_message=&7礦場 %1 已經é‡ç½® +skip_reset_message= not_allowed=&7您沒有權é™åœ¨æ­¤æŒ–礦 autosmelt_enable=&b自動冶煉 &7已被 &a啟用&7 autosmelt_disable=&b自動冶煉 &7已被 &cåœç”¨&7 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 2b5d83389..31724a843 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 @@ -476,7 +476,9 @@ public void saveIfUnsavedBlockCounts() { protected abstract void broadcastPendingResetMessageToAllPlayersWithRadius(MineJob mineJob); - + protected abstract void broadcastSkipResetMessageToAllPlayersWithRadius(); + + public int getPlayerCount() { int count = 0; @@ -1608,6 +1610,9 @@ else if ( getPercentRemainingBlockCount() > getSkipResetPercent() ) { if ( getSkipResetBypassCount() < getSkipResetBypassLimit() ) { // Skip Reset!! + + broadcastSkipResetMessageToAllPlayersWithRadius(); + return; } 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 ce8b92aca..7e64551c7 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 @@ -299,6 +299,57 @@ protected void broadcastResetMessageToAllPlayersWithRadius() { // setStatsMessageBroadcastTimeMS( stop - start ); } + + @Override + protected void broadcastSkipResetMessageToAllPlayersWithRadius() { +// long start = System.currentTimeMillis(); + + if ( isVirtual() || getResetTime() <= 0 ) { + // ignore: + } + else if ( PrisonMines.getInstance().getMinesMessages() + .getLocalizable("skip_reset_message").localize().trim().length() == 0 ) { + + // NOTE: The mine_skip_reset_message is blank, so do not broadcast it... + } + else + if ( getNotificationMode() != MineNotificationMode.disabled ) { + World world = getBounds().getCenter().getWorld(); + + if ( world != null ) { + List players = (world.getPlayers() != null ? 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.within && + getBounds().withinIncludeTopBottomOfMine(player.getLocation() ) || + getNotificationMode() == MineNotificationMode.radius && + getBounds().within(player.getLocation(), getNotificationRadius()) ) { + + if ( !isUseNotificationPermission() || + isUseNotificationPermission() && + player.hasPermission( getMineNotificationPermissionName() ) ) { + + + PrisonMines.getInstance().getMinesMessages() + .getLocalizable("skip_reset_message").withReplacements( getTag() ) + .sendTo(player); + +// player.sendMessage( "The mine " + getName() + " has just reset." ); + } + } + } + + } + + } + +// long stop = System.currentTimeMillis(); + +// setStatsMessageBroadcastTimeMS( stop - start ); + } + @Override protected void broadcastPendingResetMessageToAllPlayersWithRadius(MineJob mineJob) { From c09e2506e01e3ff0ec50331a4fec925da88c5054 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 26 Feb 2024 03:36:45 -0500 Subject: [PATCH 44/92] Mine imports: Fix some minor issues to get this to work even better. --- docs/changelog_v3.3.x.md | 3 +++ .../prison/mines/commands/MinesImportCommands.java | 8 +++++++- .../tech/mcprison/prison/mines/managers/MineManager.java | 7 ++++++- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index e8fd732a2..6fd0688a4 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.16b 2024-02-26 +* **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='** 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 ddb5e7088..78fcde3ef 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 @@ -147,7 +147,7 @@ else if ( save ) { sender.sendMessage( String.format( - " %-14s %7s bytes %s", + " %-18s %7s bytes %s", f.getName(), iFmt.format(f.length()), status ) ); } @@ -188,6 +188,12 @@ else if ( save ) { private Mine convertJetsPrisonMines(File f, String worldForced ) { Mine mine = null; + + + if ( !f.isFile() || !f.canRead() || f.length() == 0 ) { + return mine; + } + Map yaml = 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 f53f77ae6..2a1513338 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 @@ -303,7 +303,12 @@ public boolean add(Mine mine) { */ private boolean add(Mine mine, boolean save, int offsetTimingMs ) { boolean results = false; - if (!getMines().contains(mine)){ + + // 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 ); } From 052c92756f58e195a1ab89bf0e5fc47fa3c76cd1 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 26 Feb 2024 03:40:36 -0500 Subject: [PATCH 45/92] 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. --- docs/changelog_v3.3.x.md | 6 ++++ .../PrisonSpigotGUIBackPackCommands.java | 10 ++++-- .../commands/PrisonSpigotGUICommands.java | 24 ++++++++----- .../commands/PrisonSpigotSellAllCommands.java | 35 +++++++++++++++---- .../spigot/gui/ListenersPrisonManager.java | 5 ++- 5 files changed, 62 insertions(+), 18 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 6fd0688a4..8923fb376 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.16b 2024-02-26 + +* **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.** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotGUIBackPackCommands.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotGUIBackPackCommands.java index b301ba73e..8c8f3a7d8 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotGUIBackPackCommands.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotGUIBackPackCommands.java @@ -40,7 +40,10 @@ private void backpackGUIOpenCommand(CommandSender sender, } if (getBoolean(BackpacksUtil.get().getBackpacksConfig().getString("Options.BackPack_Use_Permission_Enabled")) && !p.hasPermission(BackpacksUtil.get().getBackpacksConfig().getString("Options.BackPack_Use_Permission"))){ - Output.get().sendWarn(sender, SpigotPrison.format(messages.getString(MessagesConfig.StringID.spigot_message_missing_permission) + " [" + BackpacksUtil.get().getBackpacksConfig().getString("Options.BackPack_Use_Permission") + "]")); + Output.get().sendWarn(sender, SpigotPrison.format( + messages.getString(MessagesConfig.StringID.spigot_message_missing_permission) +// + " [" + BackpacksUtil.get().getBackpacksConfig().getString("Options.BackPack_Use_Permission") + "]" + )); return; } @@ -71,7 +74,10 @@ private void backpackListGUICommand(CommandSender sender){ // New method. if (getBoolean(BackpacksUtil.get().getBackpacksConfig().getString("Options.Multiple-BackPacks-For-Player-Enabled"))){ if (getBoolean(BackpacksUtil.get().getBackpacksConfig().getString("Options.BackPack_Use_Permission_Enabled")) && !p.hasPermission(BackpacksUtil.get().getBackpacksConfig().getString("Options.BackPack_Use_Permission"))){ - Output.get().sendWarn(sender, SpigotPrison.format(messages.getString(MessagesConfig.StringID.spigot_message_missing_permission) + " [" + BackpacksUtil.get().getBackpacksConfig().getString("Options.BackPack_Use_Permission") + "]")); + Output.get().sendWarn(sender, SpigotPrison.format( + messages.getString(MessagesConfig.StringID.spigot_message_missing_permission) +// + " [" + BackpacksUtil.get().getBackpacksConfig().getString("Options.BackPack_Use_Permission") + "]" + )); return; } BackpacksListPlayerGUI gui = new BackpacksListPlayerGUI(p); 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 2481f67dc..c93825121 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 @@ -86,8 +86,10 @@ protected void cmdPrisonManagerPrestiges( CommandSender sender, int page, String String perm = getConfig( "Options.Prestiges.Permission_GUI"); if ( !sender.hasPermission( perm ) ){ - Output.get().sendInfo(sender, SpigotPrison.format(messages.getString(MessagesConfig.StringID.spigot_message_missing_permission) + " [" + - perm + "]")); + Output.get().sendInfo(sender, SpigotPrison.format( + messages.getString(MessagesConfig.StringID.spigot_message_missing_permission) +// + " [" + perm + "]" + )); return; } } @@ -142,8 +144,10 @@ protected void cmdPrisonManagerMines( CommandSender sender, int page, String cmd String perm = getConfig( "Options.Mines.Permission_GUI"); if ( !sender.hasPermission( perm ) ){ - Output.get().sendInfo(sender, SpigotPrison.format( getMessages().getString(MessagesConfig.StringID.spigot_message_missing_permission) + " [" + - perm + "]")); + Output.get().sendInfo(sender, SpigotPrison.format( + getMessages().getString(MessagesConfig.StringID.spigot_message_missing_permission) +// + " [" + perm + "]" + )); return; } } @@ -225,8 +229,10 @@ protected void cmdPrisonManagerRanks(CommandSender sender, int page, String cmdP String perm = getConfig( "Options.Ranks.Permission_GUI"); if (!sender.hasPermission(perm)) { - Output.get().sendInfo(sender, SpigotPrison.format( getMessages().getString(MessagesConfig.StringID.spigot_message_missing_permission) + " [" + - perm + "]")); + Output.get().sendInfo(sender, SpigotPrison.format( + getMessages().getString(MessagesConfig.StringID.spigot_message_missing_permission) +// + " [" + perm + "]" + )); return; } } @@ -345,8 +351,10 @@ protected void cmdPrisonManagerLadders(CommandSender sender, int page, String cm String perm = getConfig( "Options.Ranks.Permission_GUI"); if (!sender.hasPermission(perm)) { - Output.get().sendInfo(sender, SpigotPrison.format( getMessages().getString(MessagesConfig.StringID.spigot_message_missing_permission) + " [" + - perm + "]")); + Output.get().sendInfo(sender, SpigotPrison.format( + getMessages().getString(MessagesConfig.StringID.spigot_message_missing_permission) +// + " [" + perm + "]" + )); return; } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java index cb5c734cc..e568d25ce 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 @@ -320,7 +320,10 @@ else if (p == null){ if (sellAllUtil.isSellAllSellPermissionEnabled){ String permission = sellAllUtil.permissionSellAllSell; if (permission == null || !p.hasPermission(permission)){ - Output.get().sendWarn(new SpigotPlayer(p), messages.getString(MessagesConfig.StringID.spigot_message_missing_permission) + " [" + permission + "]"); + Output.get().sendWarn(new SpigotPlayer(p), + messages.getString(MessagesConfig.StringID.spigot_message_missing_permission) +// + " [" + permission + "]" + ); return; } } @@ -360,7 +363,10 @@ public void sellAllSellHandCommand(CommandSender sender){ if (sellAllUtil.isSellAllSellPermissionEnabled){ String permission = sellAllUtil.permissionSellAllSell; if (permission == null || !p.hasPermission(permission)){ - Output.get().sendWarn(new SpigotPlayer(p), messages.getString(MessagesConfig.StringID.spigot_message_missing_permission) + " [" + permission + "]"); + Output.get().sendWarn(new SpigotPlayer(p), + messages.getString(MessagesConfig.StringID.spigot_message_missing_permission) +// + " [" + permission + "]" + ); return; } } @@ -393,7 +399,10 @@ public void sellAllSell(Player p){ if (sellAllUtil.isSellAllSellPermissionEnabled){ String permission = sellAllUtil.permissionSellAllSell; if (permission == null || !p.hasPermission(permission)){ - Output.get().sendWarn(new SpigotPlayer(p), messages.getString(MessagesConfig.StringID.spigot_message_missing_permission) + " [" + permission + "]"); + Output.get().sendWarn(new SpigotPlayer(p), + messages.getString(MessagesConfig.StringID.spigot_message_missing_permission) +// + " [" + permission + "]" + ); return; } } @@ -468,7 +477,10 @@ else if (p == null){ if (sellAllUtil.isSellAllSellPermissionEnabled){ String permission = sellAllUtil.permissionSellAllSell; if (permission == null || !p.hasPermission(permission)){ - Output.get().sendWarn(new SpigotPlayer(p), messages.getString(MessagesConfig.StringID.spigot_message_missing_permission) + " [" + permission + "]"); + Output.get().sendWarn(new SpigotPlayer(p), + messages.getString(MessagesConfig.StringID.spigot_message_missing_permission) +// + " [" + permission + "]" + ); return; } } @@ -510,7 +522,10 @@ public void sellAllValueOfHandCommand(CommandSender sender){ if (sellAllUtil.isSellAllSellPermissionEnabled){ String permission = sellAllUtil.permissionSellAllSell; if (permission == null || !p.hasPermission(permission)){ - Output.get().sendWarn(new SpigotPlayer(p), messages.getString(MessagesConfig.StringID.spigot_message_missing_permission) + " [" + permission + "]"); + Output.get().sendWarn(new SpigotPlayer(p), + messages.getString(MessagesConfig.StringID.spigot_message_missing_permission) +// + " [" + permission + "]" + ); return; } } @@ -550,7 +565,10 @@ public void sellAllSellWithDelayCommand(CommandSender sender){ if (sellAllUtil.isSellAllSellPermissionEnabled){ String permission = sellAllUtil.permissionSellAllSell; if (permission == null || !p.hasPermission(permission)){ - Output.get().sendWarn(new SpigotPlayer(p), messages.getString(MessagesConfig.StringID.spigot_message_missing_permission) + " [" + permission + "]"); + Output.get().sendWarn(new SpigotPlayer(p), + messages.getString(MessagesConfig.StringID.spigot_message_missing_permission) +// + " [" + permission + "]" + ); return; } } @@ -598,7 +616,10 @@ private void sellAllAutoEnableUser(CommandSender sender){ String permission = sellAllUtil.permissionAutoSellPerUserToggleable; if (sellAllUtil.isAutoSellPerUserToggleablePermEnabled && (permission != null && !p.hasPermission(permission))){ - Output.get().sendWarn(sender, messages.getString(MessagesConfig.StringID.spigot_message_missing_permission) + " [" + permission + "]"); + Output.get().sendWarn(sender, + messages.getString(MessagesConfig.StringID.spigot_message_missing_permission) +// + " [" + permission + "]" + ); return; } 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 cfe91068e..5497f41af 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 @@ -263,7 +263,10 @@ public void onPlayerInteractEvent(PlayerInteractEvent e){ if (sign.getLine(0).equalsIgnoreCase(SpigotPrison.format(signTag))) { String permissionUseSign = sellAllUtil.permissionUseSign; if (sellAllUtil.isSellAllSignPermissionToUseEnabled && !p.hasPermission(permissionUseSign)) { - Output.get().sendWarn(new SpigotPlayer(p), messages.getString(MessagesConfig.StringID.spigot_message_missing_permission) + " [&3" + permissionUseSign + "&7]"); + Output.get().sendWarn(new SpigotPlayer(p), + messages.getString(MessagesConfig.StringID.spigot_message_missing_permission) +// + " [&3" + permissionUseSign + "&7]" + ); return; } From 337892b3a16d39676f11117c038dcfa78b57b666 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 26 Feb 2024 03:43:35 -0500 Subject: [PATCH 46/92] 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. --- docs/changelog_v3.3.x.md | 3 +++ .../prison/mines/tasks/MinePagedResetAsyncTask.java | 9 ++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 8923fb376..c89660b00 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.16b 2024-02-26 +* **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. 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 25e7ed617..66a3f2263 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 @@ -194,8 +194,15 @@ public void run() { } // Isolate the sub-list from the main targetBlocks list: + List subList = new ArrayList<>(); + + for ( int i = position; i < endIndex; i++ ) { + subList.add( targetBlocks.get( i ) ); + } +// targetBlocks.subList( position, endIndex ) ); + List tBlocks = new ArrayList<>(); - for (MineTargetPrisonBlock mtpb : targetBlocks.subList( position, endIndex )) { + for (MineTargetPrisonBlock mtpb : subList ) { tBlocks.add(mtpb); } From 11c9203fd517b492501ed20859a556a06d1ae783 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 27 Feb 2024 06:11:39 -0500 Subject: [PATCH 47/92] Mine skip reset messaging: Did not have it hooked up in the correct location, so the skip messages were not happening. --- docs/changelog_v3.3.x.md | 5 ++++- .../java/tech/mcprison/prison/mines/data/MineScheduler.java | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index c89660b00..bf4df91eb 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.16b 2024-02-26 +# 3.3.0-alpha.16b 2024-02-27 + + +* **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.** 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 044eee9ee..27b1d8791 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 @@ -398,8 +398,10 @@ public void run() resetTask.submitTaskAsync(); // resetAsynchonously(); - } else { + } + else { incrementSkipResetBypassCount(); + broadcastSkipResetMessageToAllPlayersWithRadius(); } break; From 5c4133deb48d5e8e17c7807cae17c816d64156ea Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 27 Feb 2024 06:21:48 -0500 Subject: [PATCH 48/92] 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. --- docs/changelog_v3.3.x.md | 4 + .../autofeatures/AutoManagerFeatures.java | 4 +- .../events/AutoManagerBlockBreakEvents.java | 3 +- .../spigot/block/OnBlockBreakEventCore.java | 3 +- .../prison/spigot/game/SpigotPlayer.java | 76 +++++++++++++------ 5 files changed, 61 insertions(+), 29 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index bf4df91eb..9c08c12c9 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.16b 2024-02-27 +* **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.** 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 e7325df58..b4cbcba66 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 @@ -939,7 +939,7 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, // !"false".equalsIgnoreCase( getMessage( AutoFeatures.permissionAutoSellPerBlockBreakEnabled ) ) && // player.hasPermission( getMessage( AutoFeatures.permissionAutoSellPerBlockBreakEnabled ) ); - boolean autoSellByPerm = pmEvent.getSpigotPlayer().isAutoSellByPermEnabled( isPlayerAutosellEnabled ); + boolean autoSellByPerm = pmEvent.getSpigotPlayer().isAutoSellByPermEnabled( isPlayerAutosellEnabled, pmEvent.getDebugInfo() ); // Try to autosell if enabled in any of the following ways: @@ -1468,7 +1468,7 @@ protected void dropExtra( HashMap extra, boolean isPlayerAutosellEnabled = sPlayer.isAutoSellEnabled( debugInfo ); - boolean isPlayerAutoSellByPerm = sPlayer.isAutoSellByPermEnabled( isPlayerAutosellEnabled ); + boolean isPlayerAutoSellByPerm = sPlayer.isAutoSellByPermEnabled( isPlayerAutosellEnabled, debugInfo ); if ( isPlayerAutosellEnabled || isPlayerAutoSellByPerm ) { 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 c5726ea9f..c9b02bc88 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 @@ -516,7 +516,8 @@ else if ( cancelBy == EventListenerCancelBy.drops ) { // isBoolean(AutoFeatures.isAutoSellPerBlockBreakEnabled); - boolean isPlayerAutoSellByPerm = pmEvent.getSpigotPlayer().isAutoSellByPermEnabled( isPlayerAutosellEnabled ); + boolean isPlayerAutoSellByPerm = pmEvent.getSpigotPlayer().isAutoSellByPermEnabled( + isPlayerAutosellEnabled, 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 fbf608e7b..a42e23388 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 @@ -935,7 +935,8 @@ else if ( results && pmEvent.getBbPriority().isMonitor() && mine != null ) { // pmEvent.getPlayer() )); - boolean isPlayerAutoSellByPerm = pmEvent.getSpigotPlayer().isAutoSellByPermEnabled( isPlayerAutosellEnabled ); + boolean isPlayerAutoSellByPerm = pmEvent.getSpigotPlayer() + .isAutoSellByPermEnabled( isPlayerAutosellEnabled, pmEvent.getDebugInfo() ); 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 453d6bcc6..f91c07b8c 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 @@ -864,22 +864,36 @@ public boolean isAutoSellEnabled( StringBuilder debugInfo ) { if ( SpigotPrison.getInstance().isSellAllEnabled() ) { - boolean isAutoSellPerUserToggleable = SellAllUtil.get().isAutoSellPerUserToggleable; - - boolean isPlayerAutoSellTurnedOff = isAutoSellPerUserToggleable && - !SellAllUtil.get().isSellallPlayerUserToggleEnabled( - getWrapper() ); - - if ( debugInfo != null && isPlayerAutoSellTurnedOff ) { - debugInfo.append( Output.get().getColorCodeWarning() ); - debugInfo.append( "(Player toggled off autosell) " ); - debugInfo.append( Output.get().getColorCodeDebug() ); + if ( SellAllUtil.get().isAutoSellPerUserToggleable ) { + debugInfo.append( "(sellallEnabled:userToggleable)" ); + +// boolean isAutoSellPerUserToggleable = SellAllUtil.get().isAutoSellPerUserToggleable; + + boolean isPlayerAutoSellTurnedOn = + SellAllUtil.get().isSellallPlayerUserToggleEnabled( getWrapper() ); + + if ( debugInfo != null ) { + debugInfo.append( Output.get().getColorCodeWarning() ); + debugInfo.append( + String.format( + "(Player toggled %s autosell) ", + isPlayerAutoSellTurnedOn ? "on" : "off" ) ); + debugInfo.append( Output.get().getColorCodeDebug() ); + } + + // This will return true (allow autosell) unless players can toggle autosell and they turned it off: + // This is to be used with other auto sell setting, but never on it's own: + results = isPlayerAutoSellTurnedOn; + + } + else { + debugInfo.append( "(sellallEnabled)" ); + results = true; } - // This will return true (allow autosell) unless players can toggle autosell and they turned it off: - // This is to be used with other auto sell setting, but never on it's own: - results = !isAutoSellPerUserToggleable || - isPlayerAutoSellTurnedOff; + } + else { + debugInfo.append( "(sellallDisabled)" ); } return results; @@ -898,8 +912,8 @@ public boolean isAutoSellEnabled( StringBuilder debugInfo ) { * * @return */ - public boolean isAutoSellByPermEnabled() { - return isAutoSellByPermEnabled( isAutoSellEnabled() ); + public boolean isAutoSellByPermEnabled( StringBuilder debugInfo ) { + return isAutoSellByPermEnabled( isAutoSellEnabled(), debugInfo ); } /** @@ -915,7 +929,7 @@ public boolean isAutoSellByPermEnabled() { * @param isPlayerAutosellEnabled * @return */ - public boolean isAutoSellByPermEnabled( boolean isPlayerAutosellEnabled ) { + public boolean isAutoSellByPermEnabled( boolean isPlayerAutosellEnabled, StringBuilder debugInfo ) { boolean autoSellByPerm = false; @@ -923,18 +937,30 @@ public boolean isAutoSellByPermEnabled( boolean isPlayerAutosellEnabled ) { boolean isSellallEnabled = SpigotPrison.getInstance().isSellAllEnabled(); - if ( isSellallEnabled && isPlayerAutosellEnabled && !isOp() ) { + if ( isSellallEnabled && isPlayerAutosellEnabled && + afw.isBoolean(AutoFeatures.isAutoSellPerBlockBreakEnabled) ) { String perm = afw.getMessage( AutoFeatures.permissionAutoSellPerBlockBreakEnabled ); - - autoSellByPerm = + + if ( !"disable".equalsIgnoreCase( perm ) && + !"false".equalsIgnoreCase( perm ) ) { + + if ( isOp() ) { + debugInfo.append( "(autosellByPerm:Op-Disabled)" ); + } + else { + + autoSellByPerm = hasPermission( perm ); - afw.isBoolean(AutoFeatures.isAutoSellPerBlockBreakEnabled) && - !"disable".equalsIgnoreCase( perm ) && - !"false".equalsIgnoreCase( perm ) && - hasPermission( perm ); + debugInfo.append( + String.format( + "(autosellByPerm:%s)", + autoSellByPerm ? "hasPerm" : "noPerm") ); + } + + } + } - return autoSellByPerm; } From c714319dbacfd51a40a9bc5f56babc69b3656d8c Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 1 Mar 2024 00:51:36 -0500 Subject: [PATCH 49/92] Mines import: prevent the processing of an importing of a mine if there are problems with the mine's name, or locations. --- docs/changelog_v3.3.x.md | 7 ++++++- .../prison/mines/commands/MinesImportCommands.java | 7 +++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 9c08c12c9..5bf1875c5 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.16b 2024-02-27 +# 3.3.0-alpha.16b 2024-03-01 + + + + +* **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.** 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 78fcde3ef..1ca912e33 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 @@ -233,6 +233,13 @@ private Mine convertJetsPrisonMines(File f, String worldForced ) { boolean rUseMessages = getYamlBoolean( yaml, "reset.use_messages" ); int rBlocksMined = getYamlInteger( yaml, "reset.blocks_mined" ); + + if ( mineName == null || mineName.trim().length() == 0 || + spawnWorld == null || spawnWorld.trim().length() == 0 || + locWorld == null || locWorld.trim().length() == 0 ) { + return mine; + } + World sWorld = Prison.get().getPlatform().getWorld( spawnWorld ).orElse(null); Location spawn = new Location( sWorld, spawnX, spawnY, spawnZ, From 761adb95de36507aa9f686f6070ed5e0ab5e4127 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 1 Mar 2024 00:58:55 -0500 Subject: [PATCH 50/92] 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. --- docs/changelog_v3.3.x.md | 1 + .../autofeatures/AutoManagerFeatures.java | 16 +- .../events/AutoManagerBlockBreakEvents.java | 12 +- .../spigot/block/OnBlockBreakEventCore.java | 6 +- .../commands/PrisonSpigotSellAllCommands.java | 32 +++- .../prison/spigot/game/SpigotPlayer.java | 174 ++++++++++++++---- .../prison/spigot/sellall/SellAllUtil.java | 108 +++++------ 7 files changed, 238 insertions(+), 111 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 5bf1875c5..6804f4fe7 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,7 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.16b 2024-03-01 +* **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.** 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 b4cbcba66..587cf4839 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 @@ -917,6 +917,9 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, // SellAllUtil.get().isSellallPlayerUserToggleEnabled( // pmEvent.getSpigotPlayer().getWrapper() )); + + // isAutoSellEnabled should include perms check too: + boolean isPlayerAutosellEnabled = pmEvent.getSpigotPlayer().isAutoSellEnabled( pmEvent.getDebugInfo() ); @@ -939,11 +942,12 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, // !"false".equalsIgnoreCase( getMessage( AutoFeatures.permissionAutoSellPerBlockBreakEnabled ) ) && // player.hasPermission( getMessage( AutoFeatures.permissionAutoSellPerBlockBreakEnabled ) ); - boolean autoSellByPerm = pmEvent.getSpigotPlayer().isAutoSellByPermEnabled( isPlayerAutosellEnabled, pmEvent.getDebugInfo() ); +// boolean autoSellByPerm = pmEvent.getSpigotPlayer().isAutoSellByPermEnabled( isPlayerAutosellEnabled, pmEvent.getDebugInfo() ); // Try to autosell if enabled in any of the following ways: - boolean autoSell = ( forceAutoSell || autoSellBySettings || autoSellByPerm ); + boolean autoSell = ( forceAutoSell || autoSellBySettings ); +// boolean autoSell = ( forceAutoSell || autoSellBySettings || autoSellByPerm ); for ( SpigotItemStack itemStack : drops ) { @@ -999,7 +1003,8 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, // AutoSell failure... some items may be unsellable due to not being setup in the sellall shop: - if ( forceAutoSell || autoSellBySettings || autoSellByPerm ) { + if ( forceAutoSell || autoSellBySettings ) { +// if ( forceAutoSell || autoSellBySettings || autoSellByPerm ) { // Force debug printing for this entry even if debug mode is turned off: pmEvent.setForceDebugLogging( true ); @@ -1468,9 +1473,10 @@ protected void dropExtra( HashMap extra, boolean isPlayerAutosellEnabled = sPlayer.isAutoSellEnabled( debugInfo ); - boolean isPlayerAutoSellByPerm = sPlayer.isAutoSellByPermEnabled( isPlayerAutosellEnabled, debugInfo ); +// boolean isPlayerAutoSellByPerm = sPlayer.isAutoSellByPermEnabled( isPlayerAutosellEnabled, debugInfo ); - if ( isPlayerAutosellEnabled || isPlayerAutoSellByPerm ) { + if ( isPlayerAutosellEnabled ) { +// if ( isPlayerAutosellEnabled || isPlayerAutoSellByPerm ) { SellAllUtil sellAllUtil = SellAllUtil.get(); 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 c9b02bc88..79de1dcb8 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 @@ -516,14 +516,16 @@ else if ( cancelBy == EventListenerCancelBy.drops ) { // isBoolean(AutoFeatures.isAutoSellPerBlockBreakEnabled); - boolean isPlayerAutoSellByPerm = pmEvent.getSpigotPlayer().isAutoSellByPermEnabled( - isPlayerAutosellEnabled, pmEvent.getDebugInfo() ); +// boolean isPlayerAutoSellByPerm = pmEvent.getSpigotPlayer().isAutoSellByPermEnabled( +// isPlayerAutosellEnabled, pmEvent.getDebugInfo() ); if ( isBoolean( AutoFeatures.isForceSellAllOnInventoryWhenBukkitBlockBreakEventFires ) && - ( isPlayerAutosellEnabled || isPlayerAutoSellByPerm )) { + isPlayerAutosellEnabled ) { + +// ( isPlayerAutosellEnabled || isPlayerAutoSellByPerm )) { pmEvent.getDebugInfo().append( Output.get().getColorCodeWarning()); pmEvent.performSellAllOnPlayerInventoryLogged( "FORCED BlockBreakEvent sellall"); @@ -531,7 +533,9 @@ else if ( cancelBy == EventListenerCancelBy.drops ) { } if ( isBoolean( AutoFeatures.isEnabledDelayedSellAllOnInventoryWhenBukkitBlockBreakEventFires ) && - ( isPlayerAutosellEnabled || isPlayerAutoSellByPerm ) ) { + isPlayerAutosellEnabled ) { + +// ( isPlayerAutosellEnabled || isPlayerAutoSellByPerm ) ) { if ( !getDelayedSellallPlayers().contains( pmEvent.getSpigotPlayer() ) ) { 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 a42e23388..b9a1eeba6 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 @@ -935,15 +935,15 @@ else if ( results && pmEvent.getBbPriority().isMonitor() && mine != null ) { // pmEvent.getPlayer() )); - boolean isPlayerAutoSellByPerm = pmEvent.getSpigotPlayer() - .isAutoSellByPermEnabled( isPlayerAutosellEnabled, pmEvent.getDebugInfo() ); +// boolean isPlayerAutoSellByPerm = pmEvent.getSpigotPlayer() +// .isAutoSellByPermEnabled( isPlayerAutosellEnabled, pmEvent.getDebugInfo() ); // AutoSell on full inventory when using BLOCKEVENTS: if ( isBoolean( AutoFeatures.isAutoSellIfInventoryIsFullForBLOCKEVENTSPriority ) && - ( isPlayerAutosellEnabled || isPlayerAutoSellByPerm ) && + isPlayerAutosellEnabled && pmEvent.getSpigotPlayer().isInventoryFull() ) { pmEvent.performSellAllOnPlayerInventoryLogged("BLOCKEVENTS priority sellall"); 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 e568d25ce..543490482 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 @@ -597,9 +597,13 @@ private void sellAllAutoEnableUser(CommandSender sender){ if (!isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ return; } + StringBuilder debugInfo = new StringBuilder(); + debugInfo.append( "[sellall autoSellToggle] " ); + SellAllUtil sellAllUtil = SellAllUtil.get(); Player p = getSpigotPlayer(sender); + SpigotPlayer sPlayer = new SpigotPlayer(p); // Sender must be a Player, not something else like the Console. if (p == null) { @@ -614,8 +618,11 @@ private void sellAllAutoEnableUser(CommandSender sender){ return; } - String permission = sellAllUtil.permissionAutoSellPerUserToggleable; - if (sellAllUtil.isAutoSellPerUserToggleablePermEnabled && (permission != null && !p.hasPermission(permission))){ + boolean hasAutosellPerms = sPlayer.checkAutoSellTogglePerms( debugInfo ); + +// String permission = sellAllUtil.permissionAutoSellPerUserToggleable; + if ( sellAllUtil.isAutoSellPerUserToggleablePermEnabled && !hasAutosellPerms ) { +// if (sellAllUtil.isAutoSellPerUserToggleablePermEnabled && (permission != null && !p.hasPermission(permission))){ Output.get().sendWarn(sender, messages.getString(MessagesConfig.StringID.spigot_message_missing_permission) // + " [" + permission + "]" @@ -623,14 +630,23 @@ private void sellAllAutoEnableUser(CommandSender sender){ return; } - boolean isplayerAutosellEnabled = sellAllUtil.isPlayerAutoSellEnabled(p); - if (sellAllUtil.setAutoSellPlayer(p, !isplayerAutosellEnabled)){ - if ( !isplayerAutosellEnabled ){ // Note this variable was negated then saved, so we need to check the negative: - Output.get().sendInfo(new SpigotPlayer(p), messages.getString(MessagesConfig.StringID.spigot_message_sellall_auto_disabled)); - } else { - Output.get().sendInfo(new SpigotPlayer(p), messages.getString(MessagesConfig.StringID.spigot_message_sellall_auto_enabled)); + boolean isplayerAutosellEnabled = sellAllUtil.isSellallPlayerUserToggleEnabled(p); + if (sellAllUtil.setAutoSellPlayer(p, !isplayerAutosellEnabled)) { + if ( isplayerAutosellEnabled ){ + String msg = messages.getString(MessagesConfig.StringID.spigot_message_sellall_auto_disabled); + + Output.get().sendInfo( sPlayer, msg ); + } + else { + String msg = messages.getString(MessagesConfig.StringID.spigot_message_sellall_auto_enabled); + + Output.get().sendInfo( sPlayer, msg ); } } + + if ( Output.get().isDebug() ) { + Output.get().logInfo( debugInfo.toString() ); + } } // // @Command(identifier = "sellall gui", 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 f91c07b8c..57083996d 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 @@ -854,15 +854,32 @@ public boolean isInventoryFull() { * autosell capabilities ('/sellall autoSellToggle`). *

* + *

Please note that for sellall, autosell happens upon a + * full inventory event, and only when sellall detects it, which + * it may not alway detect it as soon as it happens. + *

y + * + *

Autosell in auto features behaves differently, it sells all + * blocks that are mined, before they even enter the player's + * inventory. This is also a performance boost since the player's + * inventory does not have to be accessed or manipulated. + * As such, auto feature's autsell only is applied within the + * block handling of auto feature's code, it should never be applied + * outside of auto features, and as such, should not be included in + * the processing of this function. + *

+ * * @return */ - public boolean isAutoSellEnabled() { - return isAutoSellEnabled( null ); - } +// public boolean isAutoSellEnabled() { +// return isAutoSellEnabled( null ); +// } + public boolean isAutoSellEnabled( StringBuilder debugInfo ) { boolean results = false; - if ( SpigotPrison.getInstance().isSellAllEnabled() ) { + if ( SpigotPrison.getInstance().isSellAllEnabled() && + SellAllUtil.get().isAutoSellEnabled ) { if ( SellAllUtil.get().isAutoSellPerUserToggleable ) { debugInfo.append( "(sellallEnabled:userToggleable)" ); @@ -873,48 +890,62 @@ public boolean isAutoSellEnabled( StringBuilder debugInfo ) { SellAllUtil.get().isSellallPlayerUserToggleEnabled( getWrapper() ); if ( debugInfo != null ) { - debugInfo.append( Output.get().getColorCodeWarning() ); - debugInfo.append( - String.format( - "(Player toggled %s autosell) ", - isPlayerAutoSellTurnedOn ? "on" : "off" ) ); - debugInfo.append( Output.get().getColorCodeDebug() ); + debugInfo.append( "(autosellPlayerToggled: " ) + .append( Output.get().getColorCodeWarning() ) + .append( isPlayerAutoSellTurnedOn ? "enabled" : "disabled" ) + .append( Output.get().getColorCodeDebug() ) + .append( ")"); } // This will return true (allow autosell) unless players can toggle autosell and they turned it off: // This is to be used with other auto sell setting, but never on it's own: results = isPlayerAutoSellTurnedOn; + + // if autosell is enabled, then need to check to see if perms permit + // it to remain enabled... if not, then set results to false: + if ( results ) { + results = checkAutoSellTogglePerms( debugInfo ); + } + } else { - debugInfo.append( "(sellallEnabled)" ); + debugInfo.append( "(autosell" ) + .append( Output.get().getColorCodeWarning() ) + .append( "Enabled" ) + .append( Output.get().getColorCodeDebug() ) + .append( ")" ); results = true; } } else { - debugInfo.append( "(sellallDisabled)" ); + debugInfo.append( "(autosell" ) + .append( Output.get().getColorCodeWarning() ) + .append( "Disabled" ) + .append( Output.get().getColorCodeDebug() ) + .append( ")" ); } 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 ); - } +// /** +// *

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 @@ -929,40 +960,105 @@ public boolean isAutoSellByPermEnabled( StringBuilder debugInfo ) { * @param isPlayerAutosellEnabled * @return */ - public boolean isAutoSellByPermEnabled( boolean isPlayerAutosellEnabled, StringBuilder debugInfo ) { + private boolean isAutoSellByPermEnabledAutoFeatures( StringBuilder debugInfo ) { - boolean autoSellByPerm = false; + boolean autoSellByPerm = true; AutoFeaturesWrapper afw = AutoFeaturesWrapper.getInstance(); - boolean isSellallEnabled = SpigotPrison.getInstance().isSellAllEnabled(); - - if ( isSellallEnabled && isPlayerAutosellEnabled && - afw.isBoolean(AutoFeatures.isAutoSellPerBlockBreakEnabled) ) { + if ( afw.isBoolean(AutoFeatures.isAutoSellPerBlockBreakEnabled) ) { String perm = afw.getMessage( AutoFeatures.permissionAutoSellPerBlockBreakEnabled ); if ( !"disable".equalsIgnoreCase( perm ) && !"false".equalsIgnoreCase( perm ) ) { + debugInfo.append( "(autosellAutoFeaturesByPerm: " ) + .append( Output.get().getColorCodeWarning() ) + ; + if ( isOp() ) { - debugInfo.append( "(autosellByPerm:Op-Disabled)" ); + debugInfo.append( "Op-Disabled" ); + autoSellByPerm = false; } else { autoSellByPerm = hasPermission( perm ); - debugInfo.append( - String.format( - "(autosellByPerm:%s)", - autoSellByPerm ? "hasPerm" : "noPerm") ); + debugInfo.append( autoSellByPerm ? "hasPerm" : "noPerm" ); } + debugInfo.append( Output.get().getColorCodeDebug() ) + .append( ")" ); } - } return autoSellByPerm; } + + public boolean checkAutoSellPermsAutoFeatures() { + boolean results = false; + + AutoFeaturesWrapper afw = AutoFeaturesWrapper.getInstance(); + if ( afw.isBoolean(AutoFeatures.isAutoSellPerBlockBreakEnabled) ) { + + String perm = afw.getMessage( AutoFeatures.permissionAutoSellPerBlockBreakEnabled ); + + if ( !"disable".equalsIgnoreCase( perm ) && + !"false".equalsIgnoreCase( perm ) ) { + if ( isOp() ) { + results = false; + } + else { + + results = hasPermission( perm ); + + } + } + } + + return results; + } + + /** + *

This is using the sellall perms check to see if the player has + * the perms to use the player toggle. + *

+ * + * @return + */ + public boolean checkAutoSellTogglePerms( StringBuilder debugInfo ) { + boolean results = true; + + if ( SellAllUtil.get().isAutoSellPerUserToggleablePermEnabled ) { + + debugInfo.append( "(autosellToggleByPerm: " ) + .append( Output.get().getColorCodeWarning() ) + ; + + String perm = SellAllUtil.get().permissionAutoSellPerUserToggleable; + + if ( !"disable".equalsIgnoreCase( perm ) && + !"false".equalsIgnoreCase( perm ) ) { + if ( isOp() ) { + + debugInfo.append( "Op-Disabled" ); + + results = false; + } + else { + + results = hasPermission( perm ); + + debugInfo.append( results ? "hasPerm" : "noPerm" ); + } + } + + debugInfo.append( Output.get().getColorCodeDebug() ) + .append( ")" ); + } + + 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 fdc2ae0c5..168eb2948 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 @@ -1076,49 +1076,49 @@ private SellAllData sellItemStack( SpigotItemStack iStack, double multiplier ) { // 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 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; +//// } // -// if (sellAllConfig.getString("Users." + p.getUniqueId() + ".isEnabled") == null){ -// return true; -// } - -// return getBooleanValue("Users." + p.getUniqueId() + ".isEnabled"); - return results; - } +//// return getBooleanValue("Users." + p.getUniqueId() + ".isEnabled"); +// return results; +// } /** *

This function only checks to see if the user can toggle autosell @@ -1135,17 +1135,21 @@ public boolean isPlayerAutoSellEnabled(Player p){ public boolean isSellallPlayerUserToggleEnabled( Player p ) { boolean results = false; - if ( isAutoSellPerUserToggleable ) { + // If autosell isn't enabled, then return false + if ( isAutoSellEnabled ) { - if ( !isAutoSellPerUserToggleablePermEnabled || - isAutoSellPerUserToggleablePermEnabled && - p.hasPermission(permissionAutoSellPerUserToggleable)){ - - String settingName = "Users." + p.getUniqueId() + ".isEnabled"; - - results = sellAllConfig.getString( settingName ) == null || - getBooleanValue( settingName ); - } + if ( isAutoSellPerUserToggleable ) { + + if ( !isAutoSellPerUserToggleablePermEnabled || + isAutoSellPerUserToggleablePermEnabled && + p.hasPermission(permissionAutoSellPerUserToggleable)){ + + String settingName = "Users." + p.getUniqueId() + ".isEnabled"; + + results = sellAllConfig.getString( settingName ) == null || + getBooleanValue( settingName ); + } + } } return results; From ede2856b76602fefa2c2395ee77dfff6f693796c Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 1 Mar 2024 21:29:35 -0500 Subject: [PATCH 51/92] Mine bombs: Ability to prevent a bomb's blocks from count towards the player's block totals. --- docs/changelog_v3.3.x.md | 3 +++ .../mcprison/prison/bombs/MineBombData.java | 17 +++++++++++++++++ .../prison/bombs/MineBombsConfigData.java | 2 +- .../spigot/api/PrisonMinesBlockBreakEvent.java | 14 ++++++++++++++ ...ManagerPrisonsExplosiveBlockBreakEvents.java | 4 ++++ .../spigot/block/OnBlockBreakEventCore.java | 10 +++++++--- 6 files changed, 46 insertions(+), 4 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 6804f4fe7..a3abb8a5b 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.16b 2024-03-01 +* **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. 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 9f2744a9d..b31b7169f 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 @@ -203,6 +203,12 @@ public class MineBombData { + /** + * + */ + private boolean applyToPlayersBlockCount = true; + + /** *

Internal just to indicated if a mine bomb is activated or not. * This has not purpose if used in a save file. @@ -274,6 +280,9 @@ public MineBombData( String name, String itemType, String explosionShape, this.autosell = false; this.customModelData = 0; + + this.applyToPlayersBlockCount = true; + } @@ -326,6 +335,7 @@ public MineBombData clone() { cloned.getPreventedMines().add( mine ); } + cloned.setApplyToPlayersBlockCount( isApplyToPlayersBlockCount() ); for ( MineBombEffectsData soundEffect : getSoundEffects() ) { @@ -541,6 +551,13 @@ public void setActivated( boolean activated ) { this.activated = activated; } + public boolean isApplyToPlayersBlockCount() { + return applyToPlayersBlockCount; + } + public void setApplyToPlayersBlockCount(boolean applyToPlayersBlockCount) { + this.applyToPlayersBlockCount = applyToPlayersBlockCount; + } + public TreeSet getSoundEffects() { return soundEffects; } 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 14861671c..2f39f4dec 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombsConfigData.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombsConfigData.java @@ -16,7 +16,7 @@ public class MineBombsConfigData * data. *

*/ - public static final int MINE_BOMB_DATA_FORMAT_VERSION = 2; + public static final int MINE_BOMB_DATA_FORMAT_VERSION = 3; private int dataFormatVersion = 0; 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 d20bf0304..415085e15 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 @@ -140,6 +140,9 @@ public class PrisonMinesBlockBreakEvent private List unprocessedRawBlocks; + private boolean applyToPlayersBlockCount; + + private StringBuilder debugInfo; private boolean forceDebugLogging; @@ -194,6 +197,8 @@ public PrisonMinesBlockBreakEvent( this.forceDebugLogging = false; + this.applyToPlayersBlockCount = true; + } public PrisonMinesBlockBreakEvent( Block theBlock, Player player, @@ -224,6 +229,8 @@ public PrisonMinesBlockBreakEvent( Block theBlock, Player player, this.debugInfo = debugInfo; + this.applyToPlayersBlockCount = true; + } /** @@ -507,6 +514,13 @@ public void setForceIfAirBlock( boolean forceIfAirBlock ) { this.forceIfAirBlock = forceIfAirBlock; } + public boolean isApplyToPlayersBlockCount() { + return applyToPlayersBlockCount; + } + public void setApplyToPlayersBlockCount(boolean applyToPlayersBlockCount) { + this.applyToPlayersBlockCount = applyToPlayersBlockCount; + } + @Override public HandlerList getHandlers() { return handlers; 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 20680ca16..c429dc195 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 @@ -334,6 +334,10 @@ protected void handleExplosiveBlockBreakEvent( ExplosiveBlockBreakEvent e, // removed, then it's removed within this funciton. removeEventTriggerBlocksFromExplosions( pmEvent ); + + + pmEvent.setApplyToPlayersBlockCount( + e.getMineBomb().isApplyToPlayersBlockCount() ); if ( !validateEvent( 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 b9a1eeba6..30d12655c 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 @@ -1167,9 +1167,13 @@ private boolean countBlocksMined( PrisonMinesBlockBreakEvent pmEvent, if ( mine.incrementBlockMiningCount( targetBlock ) ) { results = true; - // Now in AutoManagerFeatures.autoPickup and calculateNormalDrop: - PlayerCache.getInstance().addPlayerBlocks( pmEvent.getSpigotPlayer(), - mine.getName(), targetBlock.getPrisonBlock(), 1 ); + + if ( pmEvent.isApplyToPlayersBlockCount() ) { + + // Now in AutoManagerFeatures.autoPickup and calculateNormalDrop: + PlayerCache.getInstance().addPlayerBlocks( pmEvent.getSpigotPlayer(), + mine.getName(), targetBlock.getPrisonBlock(), 1 ); + } } } From 10b064be3a8371da505409a6cf6628c5c174f376 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 5 Mar 2024 03:09:03 -0500 Subject: [PATCH 52/92] 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. --- docs/changelog_v3.3.x.md | 6 +++++- .../src/main/java/tech/mcprison/prison/file/FileIO.java | 5 ++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index a3abb8a5b..692afa9c3 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.16b 2024-03-01 +# 3.3.0-alpha.16b 2024-03-05 + + +* **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.** 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 67edac0ea..3975f1b0c 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 @@ -136,9 +136,12 @@ protected void saveFile( File file, String data ) // Write as an UTF-8 stream: Files.write( tempFile.toPath(), lines, StandardCharsets.UTF_8 ); + boolean exists = file.exists(); StandardOpenOption sooW = StandardOpenOption.WRITE; - StandardOpenOption sooTe = StandardOpenOption.TRUNCATE_EXISTING; + StandardOpenOption sooTe = exists ? + StandardOpenOption.TRUNCATE_EXISTING : + StandardOpenOption.CREATE; Files.write( file.toPath(), lines, StandardCharsets.UTF_8, sooW, sooTe ); From 466d1b9d977705759f2b0805d32ff478a132fc3d Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 5 Mar 2024 03:14:13 -0500 Subject: [PATCH 53/92] Block lists: Added the total chance percentage to be displayed with the blocks. --- docs/changelog_v3.3.x.md | 3 +++ .../mines/commands/MinesBlockCommands.java | 25 ++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 692afa9c3..5b68d07db 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.16b 2024-03-05 +* **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. 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 61b967958..304a5a21e 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 @@ -15,6 +15,7 @@ import tech.mcprison.prison.output.BulletedListComponent; import tech.mcprison.prison.output.ChatDisplay; import tech.mcprison.prison.output.LogLevel; +import tech.mcprison.prison.output.Output; import tech.mcprison.prison.output.RowComponent; import tech.mcprison.prison.placeholders.PlaceholdersUtil; @@ -202,6 +203,8 @@ protected BulletedListComponent getBlocksList( Mine m, CommandPagedData cmdPageD if ( includeTotals ) { + totals.setChance( totalChance ); + addBlockStats( m, totals, maxBlockNameLength, iFmt, dFmt, builder ); } @@ -230,7 +233,9 @@ private void addBlockStats( Mine mine, PrisonBlockStatusData block, if ( totals ) { - String text = String.format( "&d%" + maxBlockNameLength + "s Totals: ", " " ); + String percent = dFmt.format( block.getChance() ) + "%"; + int length = maxBlockNameLength - ( percent.length() == 7 ? -1 : 0); + String text = String.format( "&d%-" + length + "s Totals: ", percent ); row.addTextComponent( text ); } else @@ -849,5 +854,23 @@ public void constraintsBlockCommand(CommandSender sender, } + public void listBlockLayerStatsCommand( CommandSender sender, String mineName ) { + + setLastMineReferenced(mineName); + + PrisonMines pMines = PrisonMines.getInstance(); + Mine m = pMines.getMine(mineName); + + if ( m != null ) { + + Output.get().logInfo( "Mine %s Block Layer Stats:", m.getName() ); + + List layers = m.getTargetBlockStatsPerLevel(); + for ( String layer : layers ) { + Output.get().logInfo( " " + layer ); + } + + } + } } From 1ef64b38cc56a1f05cdf8bea08728eb83366fa09 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 5 Mar 2024 03:20:04 -0500 Subject: [PATCH 54/92] 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. --- docs/changelog_v3.3.x.md | 4 + .../tech/mcprison/prison/util/Bounds.java | 32 ++++-- .../prison/mines/commands/MinesCommands.java | 12 ++- .../mcprison/prison/mines/data/MineReset.java | 102 ++++++++++++++++++ 4 files changed, 143 insertions(+), 7 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 5b68d07db..3f8c1868d 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.16b 2024-03-05 +* **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.** 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 0bcb4dba5..707f2b3bf 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 @@ -37,6 +37,10 @@ public class Bounds { private final int totalBlockCount; + private final int blockCountPerLayer; + + private final int totalLayers; + public enum Edges { top, @@ -135,10 +139,14 @@ public Bounds(Location min, Location max) { this.center = new Location(this.min.getWorld(), centerX, centerY, centerZ ); + + this.totalLayers = (getyBlockMax() - getyBlockMin() + 1); + + this.blockCountPerLayer = (getxBlockMax() - getxBlockMin() + 1) * + (getzBlockMax() - getzBlockMin() + 1); + this.totalBlockCount = - (getyBlockMax() - getyBlockMin() + 1) * - (getxBlockMax() - getxBlockMin() + 1) * - (getzBlockMax() - getzBlockMin() + 1); + totalLayers * blockCountPerLayer; } @@ -279,10 +287,14 @@ public Bounds( Bounds bounds, Edges edge, int amount ) { this.center = new Location(this.min.getWorld(), centerX, centerY, centerZ ); + + this.totalLayers = (getyBlockMax() - getyBlockMin() + 1); + + this.blockCountPerLayer = (getxBlockMax() - getxBlockMin() + 1) * + (getzBlockMax() - getzBlockMin() + 1); + this.totalBlockCount = - (getyBlockMax() - getyBlockMin() + 1) * - (getxBlockMax() - getxBlockMin() + 1) * - (getzBlockMax() - getzBlockMin() + 1); + totalLayers * blockCountPerLayer; } @@ -550,6 +562,14 @@ public double getzMax() return zMax; } + public int getBlockCountPerLayer() { + return blockCountPerLayer; + } + + public int getTotalLayers() { + return totalLayers; + } + public int getTotalBlockCount() { return totalBlockCount; 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 f5a54fe79..d445c0d64 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 @@ -225,6 +225,17 @@ public void searchBlockAllCommand(CommandSender sender, "mine" ); } + @Override + @Command(identifier = "mines block layerStats", permissions = "mines.block", onlyPlayers = false, + description = "A Mine's list layer stats") + 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 ); + } + + @Override @Command(identifier = "mines block list", permissions = "mines.block", description = "Lists all of the blocks assigned to a mine.") @@ -235,7 +246,6 @@ public void listBlockCommand(CommandSender sender, } @Override - @Command(identifier = "mines block constraint", permissions = "mines.block", description = "Optionally enable constraints on a mine's block generation. " + "Please note that 'excludeTop' and 'excludeBottom' uses the layer " 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 31724a843..836257a1b 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 @@ -3,9 +3,12 @@ import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; +import java.util.Map.Entry; import java.util.Optional; import java.util.Random; +import java.util.Set; import java.util.TreeMap; +import java.util.TreeSet; import tech.mcprison.prison.Prison; import tech.mcprison.prison.internal.Player; @@ -891,6 +894,105 @@ public void generateBlockListAsync() { // // } + + + public List getTargetBlockStatsPerLevel() { + List layers = new ArrayList<>(); + + int blocksPerLayer = getBounds().getBlockCountPerLayer(); + //int totalLayers = getBounds().getTotalLayers(); + + // BlockName = BlockLetter + TreeMap translator = new TreeMap<>(); + TreeMap map = new TreeMap<>(); + + // 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++ ) ); + } + + + for ( int i = 0; i < getMineTargetPrisonBlocks().size(); i++ ) { + MineTargetPrisonBlock tBlock = getMineTargetPrisonBlocks().get(i); + int level = (int) ((i / (double) blocksPerLayer) + 1); + + String keyPrime = tBlock.getPrisonBlock() == null ? + PrisonBlock.AIR.getBlockName() : + 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 last block of the layer: + if ( (int) (((i + 1) / (double) blocksPerLayer) + 1) > level ) { + StringBuilder sb = new StringBuilder(); + + sb.append( "Layer " ).append( level ).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: " ); + + for ( Entry eSet : translator.entrySet()) { + String blockName = eSet.getKey(); + sb.append( eSet.getValue() ).append( ":" ).append( blockName ).append( " " ); + } + + layers.add( sb.toString() ); + + } + + + return layers; + } + + public void asynchronouslyResetSetup() { // Reset the block break count before resetting the blocks: From f3f3e7c549a52ecd872e7fb24a32ef8912240b19 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 5 Mar 2024 03:23:52 -0500 Subject: [PATCH 55/92] 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. --- docs/changelog_v3.3.x.md | 4 ++++ .../tech/mcprison/prison/spigot/SpigotPlatform.java | 12 ++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 3f8c1868d..832c03eaa 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.16b 2024-03-05 +* **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. 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 57b5c8518..92dfed8bd 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 @@ -204,12 +204,12 @@ public Storage initStorage() { String confStorage = plugin.getConfig().getString("storage", "file"); Storage storage = new FileStorage(plugin.getDataDirectory()); - if (!confStorage.equalsIgnoreCase("file")) { - Output.get().logError("Unknown file storage type in configuration \"" + confStorage - + "\". Using file storage."); - Output.get().logWarn( - "Note: In this version of Prison 3, 'file' is the only supported type of storage. We're working to bring other storage types soon."); - } +// if (!confStorage.equalsIgnoreCase("file")) { +// Output.get().logError("Unknown file storage type in configuration \"" + confStorage +// + "\". Using file storage."); +// Output.get().logWarn( +// "Note: In this version of Prison 3, 'file' is the only supported type of storage. We're working to bring other storage types soon."); +// } this.storage = storage; return storage; From cf483f9779e2ffd7e5f7b5b1dcd8df197b07961f Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 5 Mar 2024 03:27:57 -0500 Subject: [PATCH 56/92] 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. --- docs/changelog_v3.3.x.md | 4 ++ .../prison/mines/data/MineScheduler.java | 46 ++++++++++--------- 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 832c03eaa..51bcd2ff4 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.16b 2024-03-05 +* **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. 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 27b1d8791..2fa4e5add 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 @@ -816,7 +816,7 @@ private void manualReset( MineResetScheduleType resetType, double delayActionSec if ( !getMineStateMutex().isMinable() && getMineResetStartTimestamp() != -1 && - getMineResetStartTimestamp() - System.currentTimeMillis() > 4 * 60000 ) { + System.currentTimeMillis() - getMineResetStartTimestamp() > 4 * 60000 ) { // Mine reset was trying to run for more than 4 minutes... so it's locked out and failed? @@ -872,29 +872,31 @@ private void manualReset( MineResetScheduleType resetType, double delayActionSec // } // // } + + + + // cancel existing job: + if ( getTaskId() != null ) { + PrisonTaskSubmitter.cancelTask( getTaskId() ); + } + + // Clear jobStack and set currentJob to run the RESET with zero delay: + getJobStack().clear(); + + MineJobAction action = MineJobAction.RESET_ASYNC; // : MineJobAction.RESET_SYNC; + + MineJob mineJob = new MineJob( action, delayActionSec, 0, resetType ); + mineJob.setResetType( resetType ); + mineJob.setResetActions( resetActions ); + + setCurrentJob( mineJob ); + + // Force reset even if skip is enabled: + + // Submit to run: + submitTask(); } - - // cancel existing job: - if ( getTaskId() != null ) { - PrisonTaskSubmitter.cancelTask( getTaskId() ); - } - - // Clear jobStack and set currentJob to run the RESET with zero delay: - getJobStack().clear(); - - MineJobAction action = MineJobAction.RESET_ASYNC; // : MineJobAction.RESET_SYNC; - - MineJob mineJob = new MineJob( action, delayActionSec, 0, resetType ); - mineJob.setResetType( resetType ); - mineJob.setResetActions( resetActions ); - - setCurrentJob( mineJob ); - - // Force reset even if skip is enabled: - - // Submit to run: - submitTask(); } public List getJobWorkflow() From cc86030040e9d1360166a0c6fe514a2ff5a10c98 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 5 Mar 2024 04:06:30 -0500 Subject: [PATCH 57/92] Version 3.3.0-alpha.16c 2024-03-05 --- 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 51bcd2ff4..7d197f993 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.16b 2024-03-05 +# 3.3.0-alpha.16c 2024-03-05 + + + +**3.3.0-alpha.16c 2024-03-05** + * **Bug fix: the check for the time the reset has been going on was incorrect and was fixed.** diff --git a/gradle.properties b/gradle.properties index 3c083d648..3173b2ca5 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.16b +version=3.3.0-alpha.16c From dda5f0680f20f494aed42a62811af80c67b098b1 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 7 Mar 2024 01:03:23 -0500 Subject: [PATCH 58/92] 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. --- docs/changelog_v3.3.x.md | 6 ++- .../prison/mines/commands/MinesCommands.java | 41 +++++++++++++------ .../prison/mines/data/MineScheduler.java | 18 ++++---- 3 files changed, 45 insertions(+), 20 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 7d197f993..602e6b78d 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -18,7 +18,11 @@ These change logs represent the work that has been going on within prison. -**3.3.0-alpha.16c 2024-03-05** +**3.3.0-alpha.16c 2024-03-07** + + +* **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. 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 d445c0d64..1f9614a61 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 @@ -1384,7 +1384,7 @@ public void resetCommand(CommandSender sender, "or '*all*' to reset all the mines, " + "or '*cancel*' to cancel the resetting of all mines.") String mineName, @Wildcard(join=true) - @Arg(name = "options", description = "Optional settings [noCommands details] " + + @Arg(name = "options", description = "Optional settings [noCommands details force] " + "'noCommands' prevents the running of mine commands. " + "'details' shows progress on reset *all*.", def = "") String options ) { @@ -1395,18 +1395,23 @@ public void resetCommand(CommandSender sender, MineResetScheduleType resetType = MineResetScheduleType.FORCED; List resetActions = new ArrayList<>(); + boolean force = false; if ( options.contains( "nocommands" )) { options = options.replace( "nocommands", "" ).trim(); resetActions.add( MineResetActions.NO_COMMANDS ); } - // The value of chained is an internal value and should not be shown to users: if ( options.contains( "details" ) ) { options = options.replace( "details", "" ).trim(); resetActions.add( MineResetActions.DETAILS ); } + if ( options.contains( "force" ) ) { + 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(); @@ -1454,19 +1459,31 @@ public void resetCommand(CommandSender sender, return; } - if ( !m.getMineStateMutex().isMinable() ) { + 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 ); + } + + else if ( !m.getMineStateMutex().isMinable() ) { long resetDuration = m.getMineResetStartTimestamp() == -1 ? 0 : - m.getMineResetStartTimestamp() - System.currentTimeMillis(); + 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 4 minutes before the Mutex is releasable. " - + "The mine was reset %s seconds ago.", - dFmt.format( resetDuration / 1000.0d ) ) - ); + "&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 { @@ -2208,12 +2225,12 @@ public void resetThresholdPercentCommand(CommandSender sender, Mine m = pMines.getMine(mineName); - changeMinePercentThreshhold(sender, percent, pMines, m); + changeMinePercentThreshold(sender, percent, pMines, m); } else { for ( Mine m : pMines.getMines() ) { - changeMinePercentThreshhold(sender, percent, pMines, m); + changeMinePercentThreshold(sender, percent, pMines, m); } } @@ -2225,7 +2242,7 @@ public void resetThresholdPercentCommand(CommandSender sender, } } - private void changeMinePercentThreshhold(CommandSender sender, String percent, PrisonMines pMines, Mine m) { + private void changeMinePercentThreshold(CommandSender sender, String percent, PrisonMines pMines, Mine m) { double thresholdPercent = 0.0d; try { 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 2fa4e5add..82bbc534e 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 @@ -496,7 +496,8 @@ private void submitTask() { // Submit currentJob using delay in the job. Must be a one time run, no repeats. int taskId = PrisonTaskSubmitter.runTaskLater(this, ticksToWait); setTaskId( taskId ); - } else { + } + else { Output.get().logError("Mine " + getName() + " failed to resubmit itself so it will not auto reset. Manually reset " + "this mine to re-enable the auto reset."); @@ -752,11 +753,14 @@ public boolean checkZeroBlockReset() { if ( !isVirtual() && getMineStateMutex().isMinable() ) { + int totalBlocks = getBounds().getTotalBlockCount(); + int remaining = getRemainingBlockCount(); + double threshold = getResetThresholdPercent() == 0 ? 0 : + totalBlocks * getResetThresholdPercent() / 100.0d; + if ( - getRemainingBlockCount() <= 0 && !isZeroBlockResetDisabled() || - getResetThresholdPercent() > 0 && - getRemainingBlockCount() < (getBounds().getTotalBlockCount() * - getResetThresholdPercent() / 100.0d) + remaining <= 0 && !isZeroBlockResetDisabled() || + remaining <= threshold ) { // submit a manual reset since the mine is empty: @@ -816,9 +820,9 @@ private void manualReset( MineResetScheduleType resetType, double delayActionSec if ( !getMineStateMutex().isMinable() && getMineResetStartTimestamp() != -1 && - System.currentTimeMillis() - getMineResetStartTimestamp() > 4 * 60000 ) { + System.currentTimeMillis() - getMineResetStartTimestamp() > 3 * 60000 ) { - // Mine reset was trying to run for more than 4 minutes... so it's locked out and failed? + // Mine reset was trying to run for more than 3 minutes... so it's locked out and failed? // reset mutex and allow the rest to be forced: getMineStateMutex().setMineStateResetFinishedForced(); From 521d5275eb311ee1a90c517d047427271cb1e611 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 7 Mar 2024 12:18:22 -0500 Subject: [PATCH 59/92] 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. --- docs/changelog_v3.3.x.md | 3 + .../internal/block/MineTargetPrisonBlock.java | 18 ++ .../mcprison/prison/mines/data/MineReset.java | 225 ++++++++++++++++-- 3 files changed, 226 insertions(+), 20 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 602e6b78d..e14a69507 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -21,6 +21,9 @@ These change logs represent the work that has been going on within prison. **3.3.0-alpha.16c 2024-03-07** +* **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. 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 7af56bcf7..ac1c522f6 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 @@ -24,6 +24,10 @@ public class MineTargetPrisonBlock private boolean ignoreAllBlockEvents = false; + private transient boolean checkAir; + private transient boolean checkSame; + + public MineTargetPrisonBlock( PrisonBlockStatusData prisonBlock, World world, @@ -191,6 +195,20 @@ public void setIgnoreAllBlockEvents( boolean ignoreAllBlockEvents ) { this.ignoreAllBlockEvents = ignoreAllBlockEvents; } + public boolean isCheckAir() { + return checkAir; + } + public void setCheckAir(boolean checkAir) { + this.checkAir = checkAir; + } + + public boolean isCheckSame() { + return checkSame; + } + public void setCheckSame(boolean checkSame) { + this.checkSame = checkSame; + } + @Override public int compareTo( MineTargetPrisonBlock block ) { return block.getBlockKey().compareTo( block.getBlockKey() ); 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 836257a1b..162b955e5 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 @@ -899,42 +899,79 @@ public void generateBlockListAsync() { public List getTargetBlockStatsPerLevel() { List layers = new ArrayList<>(); - int blocksPerLayer = getBounds().getBlockCountPerLayer(); + + // 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<>(); + + // Always add the air block: + translator.put( PrisonBlock.AIR.getBlockName(), "" ); + + + String colors = "12345789abcde"; // Build translations: char blk = 'A'; - double chance = 0; - boolean hasAir = false; +// 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(); +// chance += b.getChance(); translator.put( b.getBlockName(), "" ); - if ( b.isAir() ) { - hasAir = true; - } +// if ( b.isAir() ) { +// hasAir = true; +// } } - if ( !hasAir && chance < 100.0d ) { - translator.put( PrisonBlock.AIR.getBlockName(), "" ); - } +// 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++ ) ); + 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 level = (int) ((i / (double) blocksPerLayer) + 1); + int y = getMineTargetPrisonBlocks().get(i).getLocation().getBlockY(); + blockCount++; + +// int level = (int) ((i / (double) blocksPerLayer) + 1); + - String keyPrime = tBlock.getPrisonBlock() == null ? - PrisonBlock.AIR.getBlockName() : + String keyPrime = tBlock == null || tBlock.getPrisonBlock() == null ? + airName : tBlock.getPrisonBlock().getBlockName(); String key = translator.get(keyPrime); @@ -945,12 +982,31 @@ public List getTargetBlockStatsPerLevel() { 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) ); + + } - // if last block of the layer: - if ( (int) (((i + 1) / (double) blocksPerLayer) + 1) > level ) { + + if ( (i + 1) >= getMineTargetPrisonBlocks().size() || + getMineTargetPrisonBlocks().get(i + 1).getLocation().getBlockY() != y ) { + StringBuilder sb = new StringBuilder(); - sb.append( "Layer " ).append( level ).append( " : " ); + sb.append( "Layer " ).append( layer++ ) + .append( " (" ).append( blockCount ).append(")") + .append( " : " ); TreeSet keys = new TreeSet<>( map.keySet() ); for ( String k : keys ) { @@ -963,13 +1019,61 @@ public List getTargetBlockStatsPerLevel() { // break; // } // } - sb.append( k ).append( ":" ).append( map.get(k) ).append( " " ); - } + + 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(); +// } } @@ -981,7 +1085,15 @@ public List getTargetBlockStatsPerLevel() { for ( Entry eSet : translator.entrySet()) { String blockName = eSet.getKey(); - sb.append( eSet.getValue() ).append( ":" ).append( blockName ).append( " " ); + + 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( " " ); } layers.add( sb.toString() ); @@ -1555,6 +1667,79 @@ else if ( stats.getErrorCount() <= 10 ) { } + + private void scanAllBlocksForUpdates() { + + World world = getBounds().getCenter().getWorld(); + if ( world != null ) { + + long start = System.currentTimeMillis(); + + int i = 0; + for ( MineTargetPrisonBlock targetBlock : getMineTargetPrisonBlocks() ) { + + if ( targetBlock != null ) { + + i++; + +; targetBlock.setCheckAir( false ); + targetBlock.setCheckSame( false ); + + try { +// Location targetBlock = new Location(world, x, y, z); + + boolean containsCustomBlocks = + getPrisonBlockTypes().contains( PrisonBlockType.CustomItems ) || + getPrisonBlockTypes().contains( PrisonBlockType.ItemsAdder ); + + Block tBlock = targetBlock.getLocation().getBlockAt( containsCustomBlocks ); + PrisonBlock pBlock = tBlock == null ? null : tBlock.getPrisonBlock(); + + PrisonBlockStatusData tpBlock = targetBlock.getPrisonBlock(); + + if ( tBlock == null || pBlock == null || tpBlock == null ) { + targetBlock.setCheckAir( true ); + } + else { + + + String targetBlockName = tpBlock.getBlockName(); + + + if ( pBlock.getBlockName().equalsIgnoreCase( targetBlockName) ) { + targetBlock.setCheckSame( true ); + } + else if ( pBlock.isAir() ) { + targetBlock.setCheckAir( true ); + } + else if ( pBlock.getBlockName().equalsIgnoreCase( targetBlockName) ) { + targetBlock.setCheckSame( true ); + } + else { + targetBlock.setCheckSame( false ); + + } + + } + + + + } + catch ( Exception e ) { + + Output.get().logInfo( "MineReset.scanAllBlocksForUpdates: error:" + + " count=%d %s", (i - 1), e.getMessage()); + + } + } + + + long stop = System.currentTimeMillis(); + long elapsed = stop - start; + } + } + } + /** *

This function should ONLY be used if an enchantment plugin is being used that cannot * provide a working explosion event to monitor, and the plugin is breaking more blocks than what From 4670be2dd3b014d52ca893ade08ad5c5786fa5e1 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 8 Mar 2024 13:28:28 -0500 Subject: [PATCH 60/92] 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". --- docs/changelog_v3.3.x.md | 7 +- .../internal/block/MineTargetPrisonBlock.java | 13 + .../internal/block/PrisonBlockStatusData.java | 70 ++++ .../mines/data/MineLevelBlockListData.java | 17 +- .../mcprison/prison/mines/data/MineReset.java | 359 ++++++++++++------ ...StartupRefreshBlockBreakCountSyncTask.java | 4 +- 6 files changed, 339 insertions(+), 131 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index e14a69507..176f14a37 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -18,7 +18,12 @@ These change logs represent the work that has been going on within prison. -**3.3.0-alpha.16c 2024-03-07** +**3.3.0-alpha.16c 2024-03-08** + + +* **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. 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 ac1c522f6..f812ed5fd 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 @@ -46,6 +46,19 @@ public MineTargetPrisonBlock( this.isCorner = isCorner; } + public MineTargetPrisonBlock( + PrisonBlockStatusData prisonBlock, + Location targetLocation ) { + this( prisonBlock, targetLocation.getWorld(), + targetLocation.getBlockX(), + targetLocation.getBlockY(), + targetLocation.getBlockZ(), + targetLocation.isEdge(), + targetLocation.isCorner() + ); + + } + @Override public String toString() { return "MineTargetPrisonBlock: key= " + getBlockKey().toString() + 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 ce4074868..6f3fa4649 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 @@ -45,6 +45,12 @@ public abstract class PrisonBlockStatusData { private transient boolean includeInLayerCalculations; + private transient String altAlias; + private transient String altColorCode; + private transient int altCountVirtual; + private transient int altCountPhysical; + + public PrisonBlockStatusData( PrisonBlockType blockType, String blockName, String displayName, double chance, long blockCountTotal ) { @@ -619,4 +625,68 @@ private int getRandomBlockPositionInRange( return position; } + public void setAltValues( int i ) { + + String codes = "abcdefghijklmnopqrstuvwxyz"; + String colors = "12345789abcde"; + + int codePos = i % codes.length(); + int codeFactor = i / codes.length(); + + String code = codePos == codes.length() ? + codes.substring( codePos ) : + codes.substring( codePos, codePos + 1 ); + + String alias = code + + (codeFactor == 0 ? + "" : + codeFactor); + setAltAlias( alias ); + + int colorPos = i % colors.length(); + String color = colorPos == colors.length() ? + colors.substring( colorPos ) : + colors.substring( colorPos, colorPos + 1 ); + setAltColorCode( "&" + color ); + + setAltCountVirtual( 0 ); + setAltCountPhysical( 0 ); + + } + + public void resetAltValues() { + + setAltCountVirtual( 0 ); + setAltCountPhysical( 0 ); + + } + + public String getAltAlias() { + return altAlias; + } + public void setAltAlias(String altAlias) { + this.altAlias = altAlias; + } + + public String getAltColorCode() { + return altColorCode; + } + public void setAltColorCode(String altColorCode) { + this.altColorCode = altColorCode; + } + + public int getAltCountVirtual() { + return altCountVirtual; + } + public void setAltCountVirtual(int altCountVirtual) { + this.altCountVirtual = altCountVirtual; + } + + public int getAltCountPhysical() { + return altCountPhysical; + } + public void setAltCountPhysical(int altCountPhysical) { + this.altCountPhysical = altCountPhysical; + } + } 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 7bb028471..bbfe9f094 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 @@ -38,6 +38,9 @@ public MineLevelBlockListData( int currentMineLevel, Mine mine, Random random ) private void initialize() { + totalChance = 0d; + selectedChance = 0d; + airChance = 0d; // PrisonBlocks contains the percent chance of spawning: @@ -174,12 +177,14 @@ public PrisonBlock randomlySelectPrisonBlock() selected = block; break; - } else { + } + else { chance -= block.getChance(); } } - // If block reaches it's max amount, remove it from the block list. + // If block reaches it's max amount, remove it from the block list so it will not + // be selected again. If max is reached, then this block is the max number allowed. // Note that the block has not been incremented yet, so add one to the placement count if ( selected != null && selected.getConstraintMax() > 0 && @@ -187,9 +192,13 @@ public PrisonBlock randomlySelectPrisonBlock() selected.setIncludeInLayerCalculations( false ); -// selectedBlocks.remove(selected); + selectedBlocks.remove(selected); -// selectedChance -= selected.getChance(); + selectedChance -= selected.getChance(); + } + + if ( chance == 0d && selected == null ) { + selected = PrisonBlock.AIR.clone(); } return selected; 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 162b955e5..2e54dec4f 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 @@ -3,10 +3,8 @@ import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; -import java.util.Map.Entry; import java.util.Optional; import java.util.Random; -import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; @@ -586,7 +584,8 @@ public void generateBlockListAsync() { // This is used to select the correct block list for the given mine level: - MineLevelBlockListData mineLevelBlockList = new MineLevelBlockListData( currentLevel, (Mine) this, random ); + MineLevelBlockListData mineLevelBlockList = + new MineLevelBlockListData( currentLevel, (Mine) this, random ); for (int x = xMin; x <= xMax; x++) { @@ -604,9 +603,9 @@ public void generateBlockListAsync() { boolean isCorner = xEdge && yEdge && zEdge; - Location targetBlock = new Location(world, x, y, z); - targetBlock.setEdge( isEdge ); - targetBlock.setCorner( isCorner ); + Location targetLocation = new Location(world, x, y, z); + targetLocation.setEdge( isEdge ); + targetLocation.setCorner( isCorner ); // MineTargetBlock mtb = null; @@ -624,7 +623,8 @@ public void generateBlockListAsync() { // Increment the mine's block count. This block is one of the control blocks: incrementResetBlockCount( prisonBlock ); - addMineTargetPrisonBlock( prisonBlock, targetBlock ); + // 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.equals( PrisonBlock.AIR ) ) { @@ -649,7 +649,7 @@ public void generateBlockListAsync() { if ( Output.get().isDebug() && Output.get().isSelectiveTarget( DebugTarget.blockConstraints ) ) { DecimalFormat dFmt = Prison.get().getDecimalFormatDouble(); - DecimalFormat iFmt = Prison.get().getDecimalFormatInt(); + //DecimalFormat iFmt = Prison.get().getDecimalFormatInt(); for ( PrisonBlockStatusData b : getPrisonBlocks() ) { @@ -909,54 +909,77 @@ public List getTargetBlockStatsPerLevel() { //int totalLayers = getBounds().getTotalLayers(); // BlockName = BlockLetter - TreeMap translator = new TreeMap<>(); - TreeMap map = new TreeMap<>(); - TreeMap mapMine = new TreeMap<>(); +// TreeMap translator = new TreeMap<>(); +// TreeMap map = new TreeMap<>(); +// TreeMap mapMine = new TreeMap<>(); - // Always add the air block: - translator.put( PrisonBlock.AIR.getBlockName(), "" ); + // 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 ); + } - String colors = "12345789abcde"; + int j = 0; + TreeSet keys = new TreeSet<>( getBlockStats().keySet() ); + for (String key : keys) { + PrisonBlockStatusData blk = getBlockStats().get( key ); + + blk.setAltValues( j++ ); + } - // 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 ); +// 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; @@ -966,37 +989,72 @@ else if ( blk == 'z' ) { MineTargetPrisonBlock tBlock = getMineTargetPrisonBlocks().get(i); int y = getMineTargetPrisonBlocks().get(i).getLocation().getBlockY(); blockCount++; - -// int level = (int) ((i / (double) blocksPerLayer) + 1); - - 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) ); + { + 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 ); + + if ( statsBlock == null ) { + statsBlock = getBlockStats().get( air ); + } + + + 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 ( !mapMine.containsKey(key) ) { - mapMine.put( key, 0 ); - } -// if ( !mapMine.containsKey(keyAir) ) { -// mapMine.put( keyAir, 0 ); +// 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) ); +// // } - - if ( tBlock.isCheckSame() ) { - mapMine.put( key, 1 + mapMine.get(key) ); - } - else if ( tBlock.isCheckAir() ) { - mapMine.put( keyAir, 1 + mapMine.get(keyAir) ); - - } if ( (i + 1) >= getMineTargetPrisonBlocks().size() || @@ -1008,8 +1066,26 @@ else if ( tBlock.isCheckAir() ) { .append( " (" ).append( blockCount ).append(")") .append( " : " ); - TreeSet keys = new TreeSet<>( map.keySet() ); +// 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) ) { // @@ -1020,34 +1096,35 @@ else if ( tBlock.isCheckAir() ) { // } // } - 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( " " ); +// 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 ); +// map.clear(); +// mapMine.clear(); +// +// map.put( keyAir, 0 ); +// mapMine.put( keyAir, 0 ); } // // if last block of the layer: @@ -1083,23 +1160,42 @@ else if ( tBlock.isCheckAir() ) { sb.append( "Legend: " ); - for ( Entry eSet : translator.entrySet()) { - String blockName = eSet.getKey(); - - String value = eSet.getValue(); + for ( String k : keys ) { - int c = value.charAt(0) % colors.length(); - String color = "&" + String.valueOf(colors.charAt(c)); + PrisonBlockStatusData statsBlock = getBlockStats( k ); + + sb.append( statsBlock.getAltColorCode() ) + .append( statsBlock.getAltAlias() ) + .append( Output.get().getColorCodeInfo() ) + .append( "=" ) + .append( statsBlock.getBlockName() ) + .append( " " ); + - sb - .append( color ).append( eSet.getValue() ).append( Output.get().getColorCodeDebug() ) - .append( ":" ).append( blockName ).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( " " ); +// } + layers.add( sb.toString() ); } + if ( !hasAir ) { + removePrisonBlock( air ); + getBlockStats().remove( air.getBlockName() ); + } + return layers; } @@ -1532,11 +1628,11 @@ public List refreshAirCountSyncTaskBuildLocations() { boolean isCorner = xEdge && yEdge && zEdge; - Location targetBlock = new Location(world, x, y, z); - targetBlock.setEdge( isEdge ); - targetBlock.setCorner( isCorner ); + Location targetLocation = new Location(world, x, y, z); + targetLocation.setEdge( isEdge ); + targetLocation.setCorner( isCorner ); - locations.add( targetBlock ); + locations.add( targetLocation ); @@ -1609,7 +1705,7 @@ public List refreshAirCountSyncTaskBuildLocations() { } - public void refreshAirCountSyncTaskSetLocation( Location targetBlock, + public void refreshAirCountSyncTaskSetLocation( Location targetLocation, OnStartupRefreshBlockBreakCountSyncTask stats ) { try { @@ -1619,20 +1715,23 @@ public void refreshAirCountSyncTaskSetLocation( Location targetBlock, getPrisonBlockTypes().contains( PrisonBlockType.CustomItems ) || getPrisonBlockTypes().contains( PrisonBlockType.ItemsAdder ); - Block tBlock = targetBlock.getBlockAt( containsCustomBlocks ); + Block tBlock = targetLocation.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 ) { + // TODO AIR block fix - allow AIR to be part of the regular block list? + pBlock = PrisonBlock.AIR.clone(); } - if ( pBlock == null || pBlock.isAir() ) { + + // Increment the mine's block count. This block is one of the control blocks: + addMineTargetPrisonBlock( incrementResetBlockCount( pBlock ), targetLocation ); + + + if ( pBlock.isAir() ) { stats.incrementAirCount(); } } @@ -1646,7 +1745,7 @@ public void refreshAirCountSyncTaskSetLocation( Location targetBlock, // 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 ", - targetBlock.getBlockX(), targetBlock.getBlockY(), targetBlock.getBlockZ() ); + targetLocation.getBlockX(), targetLocation.getBlockY(), targetLocation.getBlockZ() ); if ( stats.getErrorCount() == 0 ) { String message = String.format( @@ -1733,9 +1832,23 @@ else if ( pBlock.getBlockName().equalsIgnoreCase( targetBlockName) ) { } } + } + + if ( Output.get().isDebug() ) { long stop = System.currentTimeMillis(); long elapsed = stop - start; + + double ms = elapsed / 1_000_000_000d; + String msStr = Prison.getDecimalFormatStaticDouble().format(ms); + + Output.get().logInfo( + String.format( + "MineReset.scanAllBlocksForUpdates runtime%s=", + msStr + ) + ); + } } } @@ -2227,11 +2340,9 @@ public void setCurrentJob( MineJob currentJob ) - private void addMineTargetPrisonBlock( PrisonBlockStatusData block, Location targetBlock ) { + private void addMineTargetPrisonBlock( PrisonBlockStatusData block, Location targetLocation ) { - MineTargetPrisonBlock mtpb = new MineTargetPrisonBlock( block, getWorld().get(), - targetBlock.getBlockX(), targetBlock.getBlockY(), targetBlock.getBlockZ(), - targetBlock.isEdge(), targetBlock.isCorner() ); + MineTargetPrisonBlock mtpb = new MineTargetPrisonBlock( block, targetLocation ); synchronized ( getMineStateMutex() ) { 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 7c866ab23..d2a7f2964 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,9 +69,9 @@ public void run() { int start = position; for (int i = start; i < locations.size(); i++ ) { - Location targetBlock = locations.get( i ); + Location targetLocation = locations.get( i ); - mine.refreshAirCountSyncTaskSetLocation( targetBlock, this ); + mine.refreshAirCountSyncTaskSetLocation( targetLocation, this ); position++; if ( (i - start) % 500 == 0 ) { From c0378ee3fc2891aeb266ec4510912b2553bafdb4 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 9 Mar 2024 16:33:29 -0500 Subject: [PATCH 61/92] 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. --- docs/changelog_v3.3.x.md | 7 +- .../mines/data/MineLevelBlockListData.java | 261 ++++++++++++++---- .../mcprison/prison/mines/data/MineReset.java | 7 +- 3 files changed, 216 insertions(+), 59 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 176f14a37..c72daa93d 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -18,7 +18,12 @@ These change logs represent the work that has been going on within prison. -**3.3.0-alpha.16c 2024-03-08** +**3.3.0-alpha.16c 2024-03-09** + + +* **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.** 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 bbfe9f094..6ffe17b7b 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 @@ -5,28 +5,38 @@ import java.util.Random; import tech.mcprison.prison.internal.block.PrisonBlock; +import tech.mcprison.prison.output.Output; public class MineLevelBlockListData { private int currentMineLevel; + private int maxMineLevel; + private Mine mine; private Random random; private List selectedBlocks; + private PrisonBlock fillerBlock; + private double totalChance = 0d; private double selectedChance = 0d; private double airChance = 0d; + + private boolean errorMessageSent = false; + - public MineLevelBlockListData( int currentMineLevel, Mine mine, Random random ) { + public MineLevelBlockListData( int currentMineLevel, int maxMineLevel, Mine mine, Random random ) { super(); this.currentMineLevel = currentMineLevel; + this.maxMineLevel = maxMineLevel; + this.mine = mine; this.random = random; @@ -42,6 +52,8 @@ private void initialize() { selectedChance = 0d; airChance = 0d; + fillerBlock = null; + // PrisonBlocks contains the percent chance of spawning: for ( PrisonBlock pBlock : mine.getPrisonBlocks() ) @@ -49,58 +61,68 @@ private void initialize() { // First calculate the total percent chance: totalChance += pBlock.getChance(); + int cExcludeTop = pBlock.getConstraintExcludeTopLayers(); + int cExcludeBottom = pBlock.getConstraintExcludeBottomLayers(); + + int cMin = pBlock.getConstraintMin(); + int cMax = pBlock.getConstraintMax(); + + boolean hasConstraints = cExcludeTop != 0 || cExcludeBottom != 0 || + cMin != 0 || cMax != 0; + + boolean includeOnThisLevel = + cExcludeTop == 0 && cExcludeBottom == 0 || + + (cExcludeTop == 0 || cExcludeTop != 0 && currentMineLevel > cExcludeTop) && + (cExcludeBottom == 0 || cExcludeBottom != 0 && currentMineLevel < cExcludeBottom ); + + + // If the block has no constraints, or if the block is within the - // mine constraints, add it to our list. + // mine constraints of top and bottom, then add it to our list. + // If block has exceed max constraint, let it pass through this + // code so it can get the update on the rangeBlockCountHigh. // Check to ensure that the max placement has not been exceeded and if // it has, exclude from this level. Note that past levels may have // placed more than max. - if ( - ( pBlock.getConstraintExcludeTopLayers() == 0 && - pBlock.getConstraintExcludeBottomLayers() == 0 || - - pBlock.getConstraintExcludeTopLayers() <= currentMineLevel && - (pBlock.getConstraintExcludeBottomLayers() == 0 || - pBlock.getConstraintExcludeBottomLayers() > currentMineLevel) ) - - ) { + if ( includeOnThisLevel ) { - // Sum the selected blocks: - selectedChance += pBlock.getChance(); - // Add the selected blocks to our list: - selectedBlocks.add( pBlock ); + // If block has reached it's max, then do not add it's chance or add + // add it as a selected block: + if ( cMax == 0 || + cMax != 0 && pBlock.getBlockPlacedCount() < cMax) { + + // Sum the selected blocks: + selectedChance += pBlock.getChance(); + + // Add the selected blocks to our list: + selectedBlocks.add( pBlock ); + + // Need to find a filler block that has no constraints used: + if ( !hasConstraints && + (fillerBlock == null || + fillerBlock != null && pBlock.getChance() > fillerBlock.getChance() ) ) { + fillerBlock = pBlock; + } + + } - // If exclude top layers is enabled, then only try to set the - // rangeBlockCountLowLimit once since we need the lowest possible - // value. The initial value for getRangeBlockCountLowLimit is -1. - if ( pBlock.getRangeBlockCountLowLimit() == -1 && - (pBlock.getConstraintExcludeTopLayers() <= 0 || - currentMineLevel > pBlock.getConstraintExcludeTopLayers()) - ) { + // Only set the rangeBlockCountLowLimit on the first pass through here. + // The initial value for getRangeBlockCountLowLimit is -1. + if ( pBlock.getRangeBlockCountLowLimit() == -1 ) { int targetBlockPosition = mine.getMineTargetPrisonBlocks().size(); pBlock.setRangeBlockCountLowLimit( targetBlockPosition ); } - // If exclude bottom layer is enabled, then we need to track every number - // until the currentLevel exceeds the getConstraintExcludeBottomLayers value. + // Always set getConstraintExcludeBottomLayers value: // If exclude top layers, then do not record for the bottom layers until // the top layers is cleared. - if ( (pBlock.getConstraintExcludeTopLayers() > 0 && - currentMineLevel > pBlock.getConstraintExcludeTopLayers() || - pBlock.getConstraintExcludeTopLayers() == 0) && - - (pBlock.getConstraintExcludeBottomLayers() == 0 || - pBlock.getConstraintExcludeBottomLayers() > 0 && - currentMineLevel < pBlock.getConstraintExcludeBottomLayers() ) - ) { - - int targetBlockPosition = mine.getMineTargetPrisonBlocks().size(); - pBlock.setRangeBlockCountHighLimit( targetBlockPosition ); - - } + int targetBlockPosition = mine.getMineTargetPrisonBlocks().size(); + pBlock.setRangeBlockCountHighLimit( targetBlockPosition ); } @@ -124,32 +146,64 @@ private void initialize() { /** - *

For each block, run this to ensure all selected blocks that have a specified - * exclusion from the lower levels of the mine, that the rangeBlockCountHighLimit is - * properly set. + *

For each block, need to update the rangeBlockCountHighLimit, even if the + * block has reached it's max constraint. This is not tracking what was the + * last block that was placed, but it's tracking what is the max range of + * the targetBlocks collection (`mine.getMineTargetPrisonBlocks()`) in which + * this block can be placed while honoring the constraints exclude from + * top and exclude from bottom. *

*/ public void checkSelectedBlockExcludeFromBottomLayers() { for ( PrisonBlock pBlock : selectedBlocks ) { - // 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 ( (pBlock.getConstraintExcludeTopLayers() > 0 && - currentMineLevel > pBlock.getConstraintExcludeTopLayers() || - pBlock.getConstraintExcludeTopLayers() == 0) && + int cExcludeTop = pBlock.getConstraintExcludeTopLayers(); + int cExcludeBottom = pBlock.getConstraintExcludeBottomLayers(); + +// int cMin = pBlock.getConstraintMin(); +// int cMax = pBlock.getConstraintMax(); + +// boolean hasConstraints = cExcludeTop != 0 || cExcludeBottom != 0 || +// cMin != 0 || cMax != 0; + + boolean includeOnThisLevel = + cExcludeTop == 0 && cExcludeBottom == 0 || + + (cExcludeTop == 0 || cExcludeTop != 0 && currentMineLevel > cExcludeTop) && + (cExcludeBottom == 0 || cExcludeBottom != 0 && currentMineLevel < cExcludeBottom ); - (pBlock.getConstraintExcludeBottomLayers() == 0 || - pBlock.getConstraintExcludeBottomLayers() > 0 && - pBlock.getConstraintExcludeBottomLayers() < currentMineLevel) - ) { + + + // If the block has no constraints, or if the block is within the + // mine constraints of top and bottom, then add it to our list. + // If block has exceed max constraint, let it pass through this + // code so it can get the update on the rangeBlockCountHigh. + // Check to ensure that the max placement has not been exceeded and if + // it has, exclude from this level. Note that past levels may have + // placed more than max. + if ( includeOnThisLevel ) { int targetBlockPosition = mine.getMineTargetPrisonBlocks().size(); pBlock.setRangeBlockCountHighLimit( 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 ( (pBlock.getConstraintExcludeTopLayers() > 0 && +// currentMineLevel > pBlock.getConstraintExcludeTopLayers() || +// pBlock.getConstraintExcludeTopLayers() == 0) && +// +// (pBlock.getConstraintExcludeBottomLayers() == 0 || +// pBlock.getConstraintExcludeBottomLayers() > 0 && +// pBlock.getConstraintExcludeBottomLayers() < currentMineLevel) +// ) { +// +// +// } } } @@ -165,11 +219,14 @@ 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 // prevent more of them from being added to the mine. - if ( block.isIncludeInLayerCalculations() && chance <= block.getChance() ) { + if ( chance <= block.getChance() ) { // 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, @@ -190,19 +247,111 @@ public PrisonBlock randomlySelectPrisonBlock() selected.getConstraintMax() > 0 && (selected.getBlockPlacedCount() + 1) >= selected.getConstraintMax() ) { - selected.setIncludeInLayerCalculations( false ); +// selected.setIncludeInLayerCalculations( false ); selectedBlocks.remove(selected); selectedChance -= selected.getChance(); } + // if selected == null, then the block feel through the cracks because + // if the mine did not have a full 100% chance of all blocks combined, + // then an AIR block was added to the selectedBlocks collection when + // starting to process this level. So if selected is null, then something + // went wrong... assign it the filler block. + // If all blocks have constraints, the the filler block will be null so + // then assign it an AIR block. if ( chance == 0d && selected == null ) { - selected = PrisonBlock.AIR.clone(); + if ( fillerBlock != null ) { + selected = fillerBlock; + } + else { + selected = PrisonBlock.AIR.clone(); + + if ( !errorMessageSent ) { + + String msg = String.format( + "Error: generateBlockListAsync() selectBlock: " + + "Mine: %s Layer: %d : All blocks " + + "have constraints so could not backfill a void with a block " + + "so using AIR. Add a non-constrained block to the mine to " + + "prevent air blocks from spawning in this mine when a valid " + + "block cannot be choosen. This is not a bug, but it's an " + + "issue with base-2 being coverted to base-10 and the " + + "resulting random " + + "generated number not falling on any valid blocks. ", + getMine().getName(), getCurrentMineLevel() + ); + Output.get().logError( msg ); + errorMessageSent = true; + } + } } return selected; } - + + public int getCurrentMineLevel() { + return currentMineLevel; + } + public void setCurrentMineLevel(int currentMineLevel) { + this.currentMineLevel = currentMineLevel; + } + + public int getMaxMineLevel() { + return maxMineLevel; + } + public void setMaxMineLevel(int maxMineLevel) { + this.maxMineLevel = maxMineLevel; + } + + public Mine getMine() { + return mine; + } + public void setMine(Mine mine) { + this.mine = mine; + } + + public Random getRandom() { + return random; + } + public void setRandom(Random random) { + this.random = random; + } + + public List getSelectedBlocks() { + return selectedBlocks; + } + public void setSelectedBlocks(List selectedBlocks) { + this.selectedBlocks = selectedBlocks; + } + + public PrisonBlock getFillerBlock() { + return fillerBlock; + } + public void setFillerBlock(PrisonBlock fillerBlock) { + this.fillerBlock = fillerBlock; + } + + public double getTotalChance() { + return totalChance; + } + public void setTotalChance(double totalChance) { + this.totalChance = totalChance; + } + + public double getSelectedChance() { + return selectedChance; + } + public void setSelectedChance(double selectedChance) { + this.selectedChance = selectedChance; + } + + public double getAirChance() { + return airChance; + } + public void setAirChance(double airChance) { + this.airChance = airChance; + } } 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 2e54dec4f..e7dda5f87 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 @@ -564,7 +564,6 @@ public void generateBlockListAsync() { World world = worldOptional.get(); int airCount = 0; - int currentLevel = 0; int yMin = getBounds().getyBlockMin(); @@ -575,6 +574,10 @@ public void generateBlockListAsync() { int zMin = getBounds().getzBlockMin(); int zMax = getBounds().getzBlockMax(); + + + int currentLevel = 0; + int maxLevels = yMax - yMin + 1; // The reset takes place first with the top-most layer since most mines may have @@ -585,7 +588,7 @@ public void generateBlockListAsync() { // This is used to select the correct block list for the given mine level: MineLevelBlockListData mineLevelBlockList = - new MineLevelBlockListData( currentLevel, (Mine) this, random ); + new MineLevelBlockListData( currentLevel, maxLevels, (Mine) this, random ); for (int x = xMin; x <= xMax; x++) { From 578ea861512f1a5cf563474f8a17025b4302a4b9 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 9 Mar 2024 16:34:07 -0500 Subject: [PATCH 62/92] Test: minor changes to check something. --- .../util/ExampleJavaDoubleVsBigDecimal.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) 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 807cd35db..b3cd94e07 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 @@ -27,6 +27,24 @@ public static void main( String[] args ) { for (String line : out) { System.out.println( line ); } + + System.out.println(); + System.out.println(); + System.out.println(); + + double a = 1.0; + double b = 0.014; + double c = a - b; + double d = c * 100d; + double e = d / 100d; + double f = ((a * 100d) - (b * 100d)) / 100.0d; + + System.out.println( + String.format( "a = %f b = %f c = %f d = %f e = %f f = %f" , + a, b, c, d, e, f ) ); + + System.out.println( c ); + System.out.println( f ); } From c8ea54416c4c3462f6549eeb3ccd3f97e049ef30 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 9 Mar 2024 16:36:09 -0500 Subject: [PATCH 63/92] Mines: eliminate a field no longer used: includeInLayerCalculations. This was obsoleted with better use of logic. --- docs/changelog_v3.3.x.md | 4 ++++ .../internal/block/PrisonBlockStatusData.java | 16 ++++++++-------- .../mcprison/prison/mines/data/MineData.java | 4 ++-- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index c72daa93d..359cba772 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -21,6 +21,10 @@ These change logs represent the work that has been going on within prison. **3.3.0-alpha.16c 2024-03-09** +* **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. 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 6f3fa4649..0dab4b8d0 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,7 +42,7 @@ public abstract class PrisonBlockStatusData { private boolean gravity = false; - private transient boolean includeInLayerCalculations; +// private transient boolean includeInLayerCalculations; private transient String altAlias; @@ -90,7 +90,7 @@ public PrisonBlockStatusData( this.gravity = checkGravityAffects( blockName ); - this.includeInLayerCalculations = true; +// this.includeInLayerCalculations = true; } @@ -556,12 +556,12 @@ public void setGravity( boolean gravity ) { - public boolean isIncludeInLayerCalculations() { - return includeInLayerCalculations; - } - public void setIncludeInLayerCalculations(boolean includeInLayerCalculations) { - this.includeInLayerCalculations = includeInLayerCalculations; - } +// public boolean isIncludeInLayerCalculations() { +// return includeInLayerCalculations; +// } +// public void setIncludeInLayerCalculations(boolean includeInLayerCalculations) { +// this.includeInLayerCalculations = includeInLayerCalculations; +// } /** 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 ab62c20f4..e8f3f9f2f 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 @@ -791,7 +791,7 @@ public void resetResetBlockCounts() { block.setRangeBlockCountHigh( -1 ); block.setRangeBlockCountLowLimit( -1 ); block.setRangeBlockCountHighLimit( -1 ); - block.setIncludeInLayerCalculations( true ); +// block.setIncludeInLayerCalculations( true ); } for ( PrisonBlockStatusData block : getPrisonBlocks() ) { @@ -802,7 +802,7 @@ public void resetResetBlockCounts() { block.setRangeBlockCountHigh( -1 ); block.setRangeBlockCountLowLimit( -1 ); block.setRangeBlockCountHighLimit( -1 ); - block.setIncludeInLayerCalculations( true ); +// block.setIncludeInLayerCalculations( true ); } // for ( PrisonBlockStatusData blockStats : getBlockStats().values() ) { From c81d1dbcd69eb27ce025d85a33b72d019cf2fe48 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 10 Mar 2024 05:08:08 -0400 Subject: [PATCH 64/92] 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. --- docs/changelog_v3.3.x.md | 7 +- .../prison/ranks/data/RankPlayer.java | 163 ++++++++---- .../prison/ranks/data/RankPlayerMessages.java | 248 ++++++++++++++++++ .../main/resources/lang/core/de_DE.properties | 30 ++- .../main/resources/lang/core/en_GB.properties | 30 ++- .../main/resources/lang/core/en_US.properties | 31 ++- .../main/resources/lang/core/es_ES.properties | 30 ++- .../main/resources/lang/core/fi_FI.properties | 30 ++- .../main/resources/lang/core/fr_FR.properties | 30 ++- .../main/resources/lang/core/hu_HU.properties | 30 ++- .../main/resources/lang/core/it_IT.properties | 30 ++- .../main/resources/lang/core/nl_BE.properties | 43 ++- .../main/resources/lang/core/nl_NL.properties | 30 ++- .../main/resources/lang/core/pt_PT.properties | 32 ++- .../main/resources/lang/core/ro_RO.properties | 31 ++- .../main/resources/lang/core/zh-CN.properties | 40 ++- .../main/resources/lang/core/zh_TW.properties | 31 ++- .../prison/ranks/commands/RanksCommands.java | 6 + .../prison/ranks/data/TopNPlayers.java | 10 + .../tasks/TopNPlayerUpdateAsyncTask.java | 7 + 20 files changed, 824 insertions(+), 65 deletions(-) create mode 100644 prison-core/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerMessages.java diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 359cba772..1050500c2 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -18,7 +18,12 @@ These change logs represent the work that has been going on within prison. -**3.3.0-alpha.16c 2024-03-09** +**3.3.0-alpha.16c 2024-03-10** + + +* **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.** 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 cbf7a1272..cbfbed73b 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 @@ -50,6 +50,7 @@ * @author Faizaan A. Datoo */ public class RankPlayer + extends RankPlayerMessages implements Player { public static final long DELAY_THREE_SECONDS = 20 * 3; // 3 seconds in ticks @@ -1690,16 +1691,19 @@ private void calculateRankScore( String currency, double cost, double playerBala // } public static String printRankScoreLine1Header() { - String header = String.format( - "Rank %-16s %-9s %-6s %-9s %-9s %-9s", - "Player", - "Prestiges", - "Rank", - "Balance", - "Rank-Score", - "Penalty" - - ); + + String header = coreTopNLine1HeaderMsg(); + +// String header = String.format( +// "Rank %-16s %-9s %-6s %-9s %-9s %-9s", +// "Player", +// "Prestiges", +// "Rank", +// "Balance", +// "Rank-Score", +// "Penalty" +// +// ); return header; } @@ -1707,28 +1711,55 @@ public String printRankScoreLine1( int rankPostion ) { DecimalFormat dFmt = Prison.get().getDecimalFormat("#,##0.00"); - PlayerRank prestRank = getPlayerRankPrestiges(); + PlayerRank prestigeRank = getPlayerRankPrestiges(); PlayerRank defRank = getPlayerRankDefault(); - String prestRankTag = prestRank == null ? "---" : prestRank.getRank().getTag(); + String prestigeRankName = prestigeRank == null ? "" : prestigeRank.getRank().getName(); + String defaultRankName = defRank == null ? "" : defRank.getRank().getName(); + + String prestRankTag = prestigeRank == null ? "---" : prestigeRank.getRank().getTag(); String defRankTag = defRank == null ? "---" : defRank.getRank().getTag(); String prestRankTagNc = Text.stripColor(prestRankTag); String defRankTagNc = Text.stripColor(defRankTag); - String balanceStr = PlaceholdersUtil.formattedKmbtSISize( getRankScoreBalance(), dFmt, " " ); + String balanceFmtStr = dFmt.format( getRankScoreBalance() ); + String balanceKmbtStr = PlaceholdersUtil.formattedKmbtSISize( getRankScoreBalance(), dFmt, " " ); + String balanceMetricStr = PlaceholdersUtil.formattedMetricSISize( getRankScoreBalance(), dFmt, " " ); + + String rankPositionStr = Integer.toString(rankPostion); + String rankScoreStr = rankPostion > 0 ? Integer.toString(rankPostion) : ""; String sPenaltyStr = PlaceholdersUtil.formattedKmbtSISize( getRankScorePenalty(), dFmt, " " ); - String message = String.format( - " %-3s %-18s %-7s %-7s %9s %9s %9s", - (rankPostion > 0 ? Integer.toString(rankPostion) : ""), - getName(), - prestRankTagNc, - defRankTagNc, - balanceStr, - dFmt.format( getRankScore() ), - sPenaltyStr + String playerName = getName(); + + String message = coreTopNLine1DetailMsg( + + playerName, + rankPositionStr, + rankScoreStr, + sPenaltyStr, + prestigeRankName, + defaultRankName, + prestRankTag, + defRankTag, + prestRankTagNc, + defRankTagNc, + balanceFmtStr, + balanceKmbtStr, + 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") @@ -1738,46 +1769,82 @@ public String printRankScoreLine1( int rankPostion ) { } public static String printRankScoreLine2Header() { - String header = String.format( - "Rank %s %s %-15s %9s", - "Ranks", - "Rank-Score", - "Player", - "Balance" - - ); + + String header = coreTopNLine2HeaderMsg(); +// String header = String.format( +// "Rank %s %s %-15s %9s", +// "Ranks", +// "Rank-Score", +// "Player", +// "Balance" +// +// ); return header; } public String printRankScoreLine2( int rankPostion ) { - + DecimalFormat dFmt = Prison.get().getDecimalFormat("#,##0.00"); - PlayerRank prestRank = getPlayerRankPrestiges(); + PlayerRank prestigeRank = getPlayerRankPrestiges(); PlayerRank defRank = getPlayerRankDefault(); - String prestRankTag = prestRank == null ? "---" : prestRank.getRank().getTag(); + String prestigeRankName = prestigeRank == null ? "" : prestigeRank.getRank().getName(); + String defaultRankName = defRank == null ? "" : defRank.getRank().getName(); + + String prestRankTag = prestigeRank == null ? "---" : prestigeRank.getRank().getTag(); String defRankTag = defRank == null ? "---" : defRank.getRank().getTag(); String prestRankTagNc = Text.stripColor(prestRankTag); String defRankTagNc = Text.stripColor(defRankTag); - String balanceStr = PlaceholdersUtil.formattedKmbtSISize( getRankScoreBalance(), dFmt, " " ); -// String sPenaltyStr = PlaceholdersUtil.formattedKmbtSISize( getRankScorePenalty(), dFmt, " " ); - - String ranks = prestRankTagNc + defRankTagNc; - String message = String.format( - " %-3s %-9s %6s %-17s %9s", - (rankPostion > 0 ? Integer.toString(rankPostion) : ""), - ranks, - dFmt.format( getRankScore() ), - getName(), - balanceStr - ); + String balanceFmtStr = dFmt.format( getRankScoreBalance() ); + String balanceKmbtStr = PlaceholdersUtil.formattedKmbtSISize( getRankScoreBalance(), dFmt, " " ); + String balanceMetricStr = PlaceholdersUtil.formattedMetricSISize( getRankScoreBalance(), dFmt, " " ); - message = message - .replace(prestRankTagNc, prestRankTag + "&r") - .replace(defRankTagNc, defRankTag + "&r"); + String rankPositionStr = Integer.toString(rankPostion); + String rankScoreStr = rankPostion > 0 ? Integer.toString(rankPostion) : ""; + String sPenaltyStr = PlaceholdersUtil.formattedKmbtSISize( getRankScorePenalty(), dFmt, " " ); + + 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, + rankPositionStr, + rankScoreStr, sPenaltyStr, + prestigeRankName, defaultRankName, + prestRankTag, defRankTag, + 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; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerMessages.java b/prison-core/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerMessages.java new file mode 100644 index 000000000..eef69d38c --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerMessages.java @@ -0,0 +1,248 @@ +package tech.mcprison.prison.ranks.data; + +import tech.mcprison.prison.Prison; + +public class RankPlayerMessages { + + + protected String coreOutputErrorIncorrectNumberOfParametersMsg ( + String levelName, String errorMessage, + String originalMessage, String arguments ) { + return Prison.get().getLocaleManager() + .getLocalizable( "core_output__error_incorrect_number_of_parameters" ) + .withReplacements( levelName, errorMessage, + originalMessage, arguments ) + .localize(); + } + + + protected static String coreTopNLine1HeaderMsg() { + String header = Prison.get().getLocaleManager() + .getLocalizable( "core_ranks_topn__player_line_1_header_format" ) + .localize(); + header = header.replace( "[", "%" ).replace( "]", "s" ); + + String[] values = coreTopNLine1HeaderValuesMsg(); + + String results = String.format( + header, + (Object[]) values + ); + return results; + } + + private static String[] coreTopNLine1HeaderValuesMsg () { + String[] results = null; + String values = Prison.get().getLocaleManager() + .getLocalizable( "core_ranks_topn__player_line_1_header_values" ) + .localize(); + results = values.split(", "); + + return results; + } + + + + protected static String coreTopNLine2HeaderMsg() { + String header = Prison.get().getLocaleManager() + .getLocalizable( "core_ranks_topn__player_line_2_header_format" ) + .localize(); + header = header.replace( "[", "%" ).replace( "]", "s" ); + + String[] values = coreTopNLine2HeaderValuesMsg(); + + String results = String.format( + header, + (Object[]) values + ); + return results; + } + + private static String[] coreTopNLine2HeaderValuesMsg () { + String[] results = null; + String values = Prison.get().getLocaleManager() + .getLocalizable( "core_ranks_topn__player_line_2_header_values" ) + .localize(); + results = values.split(", "); + + return results; + } + + + protected static String coreTopNLine1DetailMsg( + String playerName, + String rankPositionStr, + String rankScoreStr, String sPenaltyStr, + String prestigeRankName, String defaultRankName, + String prestRankTag, String defRankTag, + String prestRankTagNc, String defRankTagNc, + String balanceFmtStr, String balanceKmbtStr, String balanceMetricStr) { + + String detail = Prison.get().getLocaleManager() + .getLocalizable( "core_ranks_topn__player_line_1_detail_format" ) + .localize(); + detail = detail.replace( "[", "%" ).replace( "]", "s" ); + + String[] values = coreTopNLine1DetailValuesMsg( + playerName, + rankPositionStr, + rankScoreStr, + sPenaltyStr, + prestigeRankName, + defaultRankName, + prestRankTag, + defRankTag, + prestRankTagNc, + defRankTagNc, + balanceFmtStr, + balanceKmbtStr, + balanceMetricStr + ); + + String results = String.format( + detail, + (Object[]) values + ); + return results; + } + + private static String[] coreTopNLine1DetailValuesMsg( + String playerName, + String rankPositionStr, + String rankScoreStr, String sPenaltyStr, + String prestigeRankName, String defaultRankName, + String prestRankTag, String defRankTag, + String prestRankTagNc, String defRankTagNc, + String balanceFmtStr, String balanceKmbtStr, String balanceMetricStr + ) { + + String[] results = null; + + String values = Prison.get().getLocaleManager() + .getLocalizable( "core_ranks_topn__player_line_1_detail_values" ) + .localize(); + + String[] tmp = values.split(","); + results = new String[tmp.length]; + + for ( int i = 0; i < tmp.length; i++ ) { + String value = tmp[i]; + + results[i] = value + .replace( "{playerName}", playerName ) + .replace( "{rankPosition}", rankPositionStr ) + .replace( "{rankScore}", rankScoreStr ) + .replace( "{rankScorePenalty}", sPenaltyStr ) + + .replace( "{prestigeRank}", prestigeRankName ) + .replace( "{defaultRank}", defaultRankName ) + .replace( "{prestigeDefaultRank}", prestigeRankName + defaultRankName ) + + .replace( "{prestigeRankTag}", prestRankTag + "&r" ) + .replace( "{defaultRankTag}", defRankTag + "&r" ) + .replace( "{prestigeDefaultRankTag}", prestRankTag + defRankTag + "&r" ) + + .replace( "{prestigeRankTagNoColor}", prestRankTagNc ) + .replace( "{defaultRankTagNoColor}", defRankTagNc ) + .replace( "{prestigeDefaultRankTagNoColor}", prestRankTagNc + defRankTagNc ) + + .replace( "{balanceFmt}", balanceFmtStr ) + .replace( "{balanceKmbt}", balanceKmbtStr ) + .replace( "{balanceMetric}", balanceMetricStr ) + .trim(); + + } + + return results; + } + + protected static String coreTopNLine2DetailMsg( + String playerName, + String rankPositionStr, + String rankScoreStr, String sPenaltyStr, + String prestigeRankName, String defaultRankName, + String prestRankTag, String defRankTag, + String prestRankTagNc, String defRankTagNc, + String balanceFmtStr, String balanceKmbtStr, String balanceMetricStr) { + + String detail = Prison.get().getLocaleManager() + .getLocalizable( "core_ranks_topn__player_line_2_detail_format" ) + .localize(); + detail = detail.replace( "[", "%" ).replace( "]", "s" ); + + String[] values = coreTopNLine2DetailValuesMsg( + playerName, + rankPositionStr, + rankScoreStr, + sPenaltyStr, + prestigeRankName, + defaultRankName, + prestRankTag, + defRankTag, + prestRankTagNc, + defRankTagNc, + balanceFmtStr, + balanceKmbtStr, + balanceMetricStr + ); + + String results = String.format( + detail, + (Object[]) values + ); + return results; + } + + private static String[] coreTopNLine2DetailValuesMsg( + String playerName, + String rankPositionStr, + String rankScoreStr, String sPenaltyStr, + String prestigeRankName, String defaultRankName, + String prestRankTag, String defRankTag, + String prestRankTagNc, String defRankTagNc, + String balanceFmtStr, String balanceKmbtStr, String balanceMetricStr + ) { + + String[] results = null; + + String values = Prison.get().getLocaleManager() + .getLocalizable( "core_ranks_topn__player_line_2_detail_values" ) + .localize(); + + String[] tmp = values.split(","); + results = new String[tmp.length]; + + for ( int i = 0; i < tmp.length; i++ ) { + String value = tmp[i]; + + + results[i] = value + .replace( "{playerName}", playerName ) + .replace( "{rankPosition}", rankPositionStr ) + .replace( "{rankScore}", rankScoreStr ) + .replace( "{rankScorePenalty}", sPenaltyStr ) + + .replace( "{prestigeRank}", prestigeRankName ) + .replace( "{defaultRank}", defaultRankName ) + .replace( "{prestigeDefaultRank}", prestigeRankName + defaultRankName ) + + .replace( "{prestigeRankTag}", prestRankTag + "&r" ) + .replace( "{defaultRankTag}", defRankTag + "&r" ) + .replace( "{prestigeDefaultRankTag}", prestRankTag + defRankTag + "&r" ) + + .replace( "{prestigeRankTagNoColor}", prestRankTagNc ) + .replace( "{defaultRankTagNoColor}", defRankTagNc ) + .replace( "{prestigeDefaultRankTagNoColor}", prestRankTagNc + defRankTagNc ) + + .replace( "{balanceFmt}", balanceFmtStr ) + .replace( "{balanceKmbt}", balanceKmbtStr ) + .replace( "{balanceMetric}", balanceMetricStr ) + .trim() + ; + + } + + return results; + } + +} 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 e426fcec9..6697897e9 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=8 +messages__version=9 messages__auto_refresh=true @@ -192,3 +192,31 @@ core_gui__value=&3Value: %1 core_gui__permission=&3Permission: &7%1 core_gui__prestige_name=&3Prestige name: %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. +# Header values will be used as is. Detail values identifies the placeholder to use. +# 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_2_header_format=[4] [-10] [7] [-18] [9] +core_ranks_topn__player_line_2_header_values=Rank, Ranks, r-Score, Player, Balance + +# For detail_values you can use any of the following placeholders, but they must pair up +# with the detail_format's []. +# {playerName}, {rankPosition}, {rankScore}, {rankScorePenalty}, +# {prestigeRank}, {defaultRank}, {prestigeDefaultRank}, +# {prestigeRankTag}, {defaultRankTag}, {prestigeDefaultRankTag}, +# {prestigeRankTagNoColor}, {defaultRankTagNoColor}, {prestigeDefaultRankTagNoColor}, +# {balanceFmt}, {balanceKmbt}, {balanceMetric} +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} + + 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 12a920078..c464867c9 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=8 +messages__version=9 messages__auto_refresh=true @@ -192,3 +192,31 @@ core_gui__value=&3Value: %1 core_gui__permission=&3Permission: &7%1 core_gui__prestige_name=&3Prestige name: %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. +# Header values will be used as is. Detail values identifies the placeholder to use. +# 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_2_header_format=[4] [-10] [7] [-18] [9] +core_ranks_topn__player_line_2_header_values=Rank, Ranks, r-Score, Player, Balance + +# For detail_values you can use any of the following placeholders, but they must pair up +# with the detail_format's []. +# {playerName}, {rankPosition}, {rankScore}, {rankScorePenalty}, +# {prestigeRank}, {defaultRank}, {prestigeDefaultRank}, +# {prestigeRankTag}, {defaultRankTag}, {prestigeDefaultRankTag}, +# {prestigeRankTagNoColor}, {defaultRankTagNoColor}, {prestigeDefaultRankTagNoColor}, +# {balanceFmt}, {balanceKmbt}, {balanceMetric} +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} + + 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 c5499c0d2..6a0805f94 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=9 +messages__version=10 messages__auto_refresh=true @@ -192,3 +192,32 @@ core_gui__value=&3Value: %1 core_gui__permission=&3Permission: &7%1 core_gui__prestige_name=&3Prestige name: %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. +# Header values will be used as is. Detail values identifies the placeholder to use. +# 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] [-10] +core_ranks_topn__player_line_1_header_values=Rank, Player, PreDefRanks, Balance, r-Score, Penalty +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 + +# For detail_values you can use any of the following placeholders, but they must pair up +# with the detail_format's []. +# {playerName}, {rankPosition}, {rankScore}, {rankScorePenalty}, +# {prestigeRank}, {defaultRank}, {prestigeDefaultRank}, +# {prestigeRankTag}, {defaultRankTag}, {prestigeDefaultRankTag}, +# {prestigeRankTagNoColor}, {defaultRankTagNoColor}, {prestigeDefaultRankTagNoColor}, +# {balanceFmt}, {balanceKmbt}, {balanceMetric} +core_ranks_topn__player_line_1_detail_format= [-4] [-18] [-12] [10] [7] [9] +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} + + + 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 b6e6fbcde..68f1693de 100644 --- a/prison-core/src/main/resources/lang/core/es_ES.properties +++ b/prison-core/src/main/resources/lang/core/es_ES.properties @@ -76,7 +76,7 @@ # like to share, please contact a staff member on our Discord server. #Thanks for your contributions! # -messages__version=8 +messages__version=9 messages__auto_refresh=true @@ -192,3 +192,31 @@ core_gui__value=&3Value: %1 core_gui__permission=&3Permission: &7%1 core_gui__prestige_name=&3Prestige name: %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. +# Header values will be used as is. Detail values identifies the placeholder to use. +# 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_2_header_format=[4] [-10] [7] [-18] [9] +core_ranks_topn__player_line_2_header_values=Rank, Ranks, r-Score, Player, Balance + +# For detail_values you can use any of the following placeholders, but they must pair up +# with the detail_format's []. +# {playerName}, {rankPosition}, {rankScore}, {rankScorePenalty}, +# {prestigeRank}, {defaultRank}, {prestigeDefaultRank}, +# {prestigeRankTag}, {defaultRankTag}, {prestigeDefaultRankTag}, +# {prestigeRankTagNoColor}, {defaultRankTagNoColor}, {prestigeDefaultRankTagNoColor}, +# {balanceFmt}, {balanceKmbt}, {balanceMetric} +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} + + 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 831d6af77..724ddc12d 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=9 +messages__version=10 messages__auto_refresh=true @@ -192,3 +192,31 @@ core_gui__value=&3Value: %1 core_gui__permission=&3Permission: &7%1 core_gui__prestige_name=&3Prestige name: %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. +# Header values will be used as is. Detail values identifies the placeholder to use. +# 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_2_header_format=[4] [-10] [7] [-18] [9] +core_ranks_topn__player_line_2_header_values=Rank, Ranks, r-Score, Player, Balance + +# For detail_values you can use any of the following placeholders, but they must pair up +# with the detail_format's []. +# {playerName}, {rankPosition}, {rankScore}, {rankScorePenalty}, +# {prestigeRank}, {defaultRank}, {prestigeDefaultRank}, +# {prestigeRankTag}, {defaultRankTag}, {prestigeDefaultRankTag}, +# {prestigeRankTagNoColor}, {defaultRankTagNoColor}, {prestigeDefaultRankTagNoColor}, +# {balanceFmt}, {balanceKmbt}, {balanceMetric} +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} + + 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 9997d0444..cfa59876b 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=9 +messages__version=10 messages__auto_refresh=true @@ -192,3 +192,31 @@ core_gui__value=&3Valeur: %1 core_gui__permission=&3Permission: &7%1 core_gui__prestige_name=&3Nom de prestige: %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. +# Header values will be used as is. Detail values identifies the placeholder to use. +# 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_2_header_format=[4] [-10] [7] [-18] [9] +core_ranks_topn__player_line_2_header_values=Rank, Ranks, r-Score, Player, Balance + +# For detail_values you can use any of the following placeholders, but they must pair up +# with the detail_format's []. +# {playerName}, {rankPosition}, {rankScore}, {rankScorePenalty}, +# {prestigeRank}, {defaultRank}, {prestigeDefaultRank}, +# {prestigeRankTag}, {defaultRankTag}, {prestigeDefaultRankTag}, +# {prestigeRankTagNoColor}, {defaultRankTagNoColor}, {prestigeDefaultRankTagNoColor}, +# {balanceFmt}, {balanceKmbt}, {balanceMetric} +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} + + 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 fee17ae76..2d5d92351 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=8 +messages__version=9 messages__auto_refresh=true @@ -192,3 +192,31 @@ core_gui__value=&3Value: %1 core_gui__permission=&3Permission: &7%1 core_gui__prestige_name=&3Prestige name: %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. +# Header values will be used as is. Detail values identifies the placeholder to use. +# 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_2_header_format=[4] [-10] [7] [-18] [9] +core_ranks_topn__player_line_2_header_values=Rank, Ranks, r-Score, Player, Balance + +# For detail_values you can use any of the following placeholders, but they must pair up +# with the detail_format's []. +# {playerName}, {rankPosition}, {rankScore}, {rankScorePenalty}, +# {prestigeRank}, {defaultRank}, {prestigeDefaultRank}, +# {prestigeRankTag}, {defaultRankTag}, {prestigeDefaultRankTag}, +# {prestigeRankTagNoColor}, {defaultRankTagNoColor}, {prestigeDefaultRankTagNoColor}, +# {balanceFmt}, {balanceKmbt}, {balanceMetric} +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} + + 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 7868eee2f..3ad654dc4 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=8 +messages__version=9 messages__auto_refresh=true @@ -192,3 +192,31 @@ core_gui__value=&3Value: %1 core_gui__permission=&3Permission: &7%1 core_gui__prestige_name=&3Prestige name: %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. +# Header values will be used as is. Detail values identifies the placeholder to use. +# 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_2_header_format=[4] [-10] [7] [-18] [9] +core_ranks_topn__player_line_2_header_values=Rank, Ranks, r-Score, Player, Balance + +# For detail_values you can use any of the following placeholders, but they must pair up +# with the detail_format's []. +# {playerName}, {rankPosition}, {rankScore}, {rankScorePenalty}, +# {prestigeRank}, {defaultRank}, {prestigeDefaultRank}, +# {prestigeRankTag}, {defaultRankTag}, {prestigeDefaultRankTag}, +# {prestigeRankTagNoColor}, {defaultRankTagNoColor}, {prestigeDefaultRankTagNoColor}, +# {balanceFmt}, {balanceKmbt}, {balanceMetric} +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} + + 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 bec93ed55..8a5e13c54 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=8 +messages__version=9 messages__auto_refresh=true @@ -149,7 +149,15 @@ worldNotFound=De wereld %1 kon niet worden gevonden. 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. @@ -175,8 +183,41 @@ core_gui__page_next=&3Next page. core_gui__page_prior=&3Prior 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 + + + + +# 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. +# Header values will be used as is. Detail values identifies the placeholder to use. +# 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_2_header_format=[4] [-10] [7] [-18] [9] +core_ranks_topn__player_line_2_header_values=Rank, Ranks, r-Score, Player, Balance + +# For detail_values you can use any of the following placeholders, but they must pair up +# with the detail_format's []. +# {playerName}, {rankPosition}, {rankScore}, {rankScorePenalty}, +# {prestigeRank}, {defaultRank}, {prestigeDefaultRank}, +# {prestigeRankTag}, {defaultRankTag}, {prestigeDefaultRankTag}, +# {prestigeRankTagNoColor}, {defaultRankTagNoColor}, {prestigeDefaultRankTagNoColor}, +# {balanceFmt}, {balanceKmbt}, {balanceMetric} +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} + + + 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 270b1fc24..9560116bf 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=8 +messages__version=9 messages__auto_refresh=true @@ -192,3 +192,31 @@ core_gui__value=&3Value: %1 core_gui__permission=&3Permission: &7%1 core_gui__prestige_name=&3Prestige name: %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. +# Header values will be used as is. Detail values identifies the placeholder to use. +# 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_2_header_format=[4] [-10] [7] [-18] [9] +core_ranks_topn__player_line_2_header_values=Rank, Ranks, r-Score, Player, Balance + +# For detail_values you can use any of the following placeholders, but they must pair up +# with the detail_format's []. +# {playerName}, {rankPosition}, {rankScore}, {rankScorePenalty}, +# {prestigeRank}, {defaultRank}, {prestigeDefaultRank}, +# {prestigeRankTag}, {defaultRankTag}, {prestigeDefaultRankTag}, +# {prestigeRankTagNoColor}, {defaultRankTagNoColor}, {prestigeDefaultRankTagNoColor}, +# {balanceFmt}, {balanceKmbt}, {balanceMetric} +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} + + 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 9c87f5f9d..c3776f21d 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=3 +messages__version=5 messages__auto_refresh=true @@ -101,6 +101,7 @@ core_text__just_now=just now core_text__ago=ago core_text__from_now=from now core_text__and=and +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 @@ -182,6 +183,7 @@ core_gui__page_next=&3Pagina seguinte. core_gui__page_prior=&3Pagina anterior. +core_gui__money_earned=&3You earned &a$%1 core_gui__price=&3Preco: %1 core_gui__confirm=&3Confirmar: %1 %2 core_gui__delay=&3Atrado: %1 secs @@ -190,3 +192,31 @@ core_gui__value=&3Valor: %1 core_gui__permission=&3Permissão: &7%1 core_gui__prestige_name=&3Nome do Prestige: %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. +# Header values will be used as is. Detail values identifies the placeholder to use. +# 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_2_header_format=[4] [-10] [7] [-18] [9] +core_ranks_topn__player_line_2_header_values=Rank, Ranks, r-Score, Player, Balance + +# For detail_values you can use any of the following placeholders, but they must pair up +# with the detail_format's []. +# {playerName}, {rankPosition}, {rankScore}, {rankScorePenalty}, +# {prestigeRank}, {defaultRank}, {prestigeDefaultRank}, +# {prestigeRankTag}, {defaultRankTag}, {prestigeDefaultRankTag}, +# {prestigeRankTagNoColor}, {defaultRankTagNoColor}, {prestigeDefaultRankTagNoColor}, +# {balanceFmt}, {balanceKmbt}, {balanceMetric} +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} + + 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 647284ad2..1c7170fa5 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=3 +messages__version=4 messages__auto_refresh=true @@ -192,3 +192,32 @@ core_gui__value=&3Value: %1 core_gui__permission=&3Permission: &7%1 core_gui__prestige_name=&3Prestige name: %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. +# Header values will be used as is. Detail values identifies the placeholder to use. +# 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_2_header_format=[4] [-10] [7] [-18] [9] +core_ranks_topn__player_line_2_header_values=Rank, Ranks, r-Score, Player, Balance + +# For detail_values you can use any of the following placeholders, but they must pair up +# with the detail_format's []. +# {playerName}, {rankPosition}, {rankScore}, {rankScorePenalty}, +# {prestigeRank}, {defaultRank}, {prestigeDefaultRank}, +# {prestigeRankTag}, {defaultRankTag}, {prestigeDefaultRankTag}, +# {prestigeRankTagNoColor}, {defaultRankTagNoColor}, {prestigeDefaultRankTagNoColor}, +# {balanceFmt}, {balanceKmbt}, {balanceMetric} +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} + + + 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 cfeca845d..86f6b9a6a 100644 --- a/prison-core/src/main/resources/lang/core/zh-CN.properties +++ b/prison-core/src/main/resources/lang/core/zh-CN.properties @@ -1,4 +1,3 @@ - # # Prison is a Minecraft plugin for the prison game mode. # Copyright (C) 2021 The Prison Team @@ -77,7 +76,7 @@ # like to share, please contact a staff member on our Discord server. #Thanks for your contributions! # -messages__version=7 +messages__version=8 messages__auto_refresh=true @@ -101,7 +100,8 @@ core_text__prefix=&3 core_text__just_now=现在 core_text__ago=ä»¥å‰ core_text__from_now=åŽ -core_text__and=å’Œ +core_text__and=å +core_text__time_units_prefix_spacer= ’Œ core_text__time_units_singular=å¹´ã€æœˆã€å‘¨ã€æ—¥ã€æ—¶ã€åˆ†ã€ç§’ core_text__time_units_plural=å¹´ã€æœˆã€å‘¨ã€æ—¥ã€æ—¶ã€åˆ†ã€ç§’ core_text__time_units_short=å¹´ã€æœˆã€å‘¨ã€æ—¥ã€æ—¶ã€åˆ†ã€ç§’ @@ -119,6 +119,10 @@ core_tokens__set_amount=&3%1 now has &7%2 &3tokens. core_runCmd__name_required=A valid player name is required. core_runCmd__command_required=A command is 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 + + # The following are the original messages and they will eventually be replaced. includeError=[%1] 具有无效值 @@ -179,6 +183,7 @@ core_gui__page_next=&3下一页 core_gui__page_prior=&3上一页 +core_gui__money_earned=&3You earned &a$%1 core_gui__price=&3价格:%1 core_gui__confirm=&3确认:%1%2 core_gui__delay=&3延迟:%1秒 @@ -187,3 +192,32 @@ core_gui__value=&3值:%1 core_gui__permission=&3æƒé™ï¼š&7%1 core_gui__prestige_name=&3声望å称:%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. +# Header values will be used as is. Detail values identifies the placeholder to use. +# 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_2_header_format=[4] [-10] [7] [-18] [9] +core_ranks_topn__player_line_2_header_values=Rank, Ranks, r-Score, Player, Balance + +# For detail_values you can use any of the following placeholders, but they must pair up +# with the detail_format's []. +# {playerName}, {rankPosition}, {rankScore}, {rankScorePenalty}, +# {prestigeRank}, {defaultRank}, {prestigeDefaultRank}, +# {prestigeRankTag}, {defaultRankTag}, {prestigeDefaultRankTag}, +# {prestigeRankTagNoColor}, {defaultRankTagNoColor}, {prestigeDefaultRankTagNoColor}, +# {balanceFmt}, {balanceKmbt}, {balanceMetric} +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} + + + 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 99880acb3..0d605c9e4 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=8 +messages__version=9 messages__auto_refresh=true @@ -192,3 +192,32 @@ core_gui__value=&3Value: %1 core_gui__permission=&3Permission: &7%1 core_gui__prestige_name=&3Prestige name: %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. +# Header values will be used as is. Detail values identifies the placeholder to use. +# 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_2_header_format=[4] [-10] [7] [-18] [9] +core_ranks_topn__player_line_2_header_values=Rank, Ranks, r-Score, Player, Balance + +# For detail_values you can use any of the following placeholders, but they must pair up +# with the detail_format's []. +# {playerName}, {rankPosition}, {rankScore}, {rankScorePenalty}, +# {prestigeRank}, {defaultRank}, {prestigeDefaultRank}, +# {prestigeRankTag}, {defaultRankTag}, {prestigeDefaultRankTag}, +# {prestigeRankTagNoColor}, {defaultRankTagNoColor}, {prestigeDefaultRankTagNoColor}, +# {balanceFmt}, {balanceKmbt}, {balanceMetric} +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} + + + 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 ee97cad9f..74b08b40d 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 @@ -2268,6 +2268,7 @@ public void rankTopN(CommandSender sender, // boolean sort = contains( "sort", pageNumber, pageSizeNumber, options ); int topNSize = TopNPlayers.getInstance().getTopNSize(); + boolean loading = TopNPlayers.getInstance().isLoading(); int archivedSize = TopNPlayers.getInstance().getArchivedSize(); @@ -2340,6 +2341,11 @@ public void rankTopN(CommandSender sender, RankPlayer.printRankScoreLine1Header(); sender.sendMessage( header ); + if ( loading ) { + sender.sendMessage( "&3(Loading TopN List - Please Wait)" ); + } + + for ( int i = posStart; i < posEnd; i++ ) { RankPlayer rPlayer = 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 de0a28878..4c79e3cf6 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 @@ -64,6 +64,9 @@ public class TopNPlayers private long statsSaveDataNanoSec = 0L; private long statsLoadDataNanoSec = 0L; + private boolean loading = true; + + private TopNPlayers() { super(); @@ -798,5 +801,12 @@ public long getStatsLoadDataNanoSec() { public void setStatsLoadDataNanoSec(long statsLoadDataNanoSec) { this.statsLoadDataNanoSec = statsLoadDataNanoSec; } + + public boolean isLoading() { + return loading; + } + public void setLoading(boolean loading) { + this.loading = loading; + } } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/tasks/TopNPlayerUpdateAsyncTask.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/tasks/TopNPlayerUpdateAsyncTask.java index ffdde60fd..98c2e3705 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/tasks/TopNPlayerUpdateAsyncTask.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/tasks/TopNPlayerUpdateAsyncTask.java @@ -40,13 +40,20 @@ public void run() { // } if ( forceReload ) { + topNPlayers.setLoading( true ); + topNPlayers.forceReloadAllPlayers(); + topNPlayers.setLoading( false ); forceReload = false; } else { + topNPlayers.setLoading( true ); + topNPlayers.refreshAndSort(); + + topNPlayers.setLoading( false ); } } From fa10d0a16c019f03fdb27482c04af7717fdc828f Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 10 Mar 2024 13:37:12 -0400 Subject: [PATCH 65/92] Last adjustment to the topN formatting. --- prison-core/src/main/resources/lang/core/en_US.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 6a0805f94..6d0e97f29 100644 --- a/prison-core/src/main/resources/lang/core/en_US.properties +++ b/prison-core/src/main/resources/lang/core/en_US.properties @@ -202,7 +202,7 @@ core_gui__prestige_name=&3Prestige name: %1 # Header values will be used as is. Detail values identifies the placeholder to use. # 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] [-10] +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_2_header_format=[4] [-10] [7] [-18] [9] core_ranks_topn__player_line_2_header_values=Rank, Ranks, r-Score, Player, Balance @@ -214,7 +214,7 @@ core_ranks_topn__player_line_2_header_values=Rank, Ranks, r-Score, Player, Balan # {prestigeRankTag}, {defaultRankTag}, {prestigeDefaultRankTag}, # {prestigeRankTagNoColor}, {defaultRankTagNoColor}, {prestigeDefaultRankTagNoColor}, # {balanceFmt}, {balanceKmbt}, {balanceMetric} -core_ranks_topn__player_line_1_detail_format= [-4] [-18] [-12] [10] [7] [9] +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 f9a35a3769a3ef961a112f94d1aedaf7e970f319 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 10 Mar 2024 14:00:47 -0400 Subject: [PATCH 66/92] 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. --- docs/changelog_v3.3.x.md | 4 ++ .../prison/ranks/commands/RankUpCommand.java | 71 +++++++++++-------- 2 files changed, 47 insertions(+), 28 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 1050500c2..503983e4f 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -21,6 +21,10 @@ These change logs represent the work that has been going on within prison. **3.3.0-alpha.16c 2024-03-10** +* **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. 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 6ca277370..866c09938 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 @@ -768,34 +768,43 @@ public void promotePlayer(CommandSender sender, UUID playerUuid = player.getUUID(); ladder = confirmLadder( sender, ladder ); + if ( ladder == null ) { + return; + } RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); RankPlayer rankPlayer = getRankPlayer( sender, playerUuid, player.getName() ); PlayerRank playerRank = rankPlayerFactory.getRank( rankPlayer, ladder ); - if ( playerRank != null ) { + if ( rankPlayer != null && playerRank != null ) { Rank pRank = playerRank.getRank(); + if ( pRank == null ) { + sender.sendMessage( "Promote: 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 = rankPlayer == null || pRank == null ? null : pRank.getCurrency(); + String currency = pRank.getCurrency(); + + List cmdTasks = new ArrayList<>(); + + RankupResults results = new RankUtil().promotePlayer(player, rankPlayer, ladder, + player.getName(), sender.getName(), pForceCharge, cmdTasks ); + + // submit cmdTasks... + submitCmdTasks( player, cmdTasks ); + + processResults( sender, player.getName(), results, null, ladder, currency, null ); - if ( ladder != null && rankPlayer != null ) { - - List cmdTasks = new ArrayList<>(); - - RankupResults results = new RankUtil().promotePlayer(player, rankPlayer, ladder, - player.getName(), sender.getName(), pForceCharge, cmdTasks ); - - // submit cmdTasks... - submitCmdTasks( player, cmdTasks ); - - processResults( sender, player.getName(), results, null, ladder, currency, null ); - } } 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."); } } @@ -842,28 +851,34 @@ public void demotePlayer(CommandSender sender, RankPlayer rankPlayer = getRankPlayer( sender, playerUuid, player.getName() ); PlayerRank playerRank = rankPlayerFactory.getRank( rankPlayer, ladder ); - if ( playerRank != null ) { + if ( rankPlayer != 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 = rankPlayer == null || pRank == null ? null : pRank.getCurrency(); + String currency = pRank.getCurrency(); + + List cmdTasks = new ArrayList<>(); + + RankupResults results = new RankUtil().demotePlayer(player, rankPlayer, ladder, + player.getName(), sender.getName(), pForceCharge, cmdTasks ); + + // submit cmdTasks + submitCmdTasks( player, cmdTasks ); + + processResults( sender, player.getName(), results, null, ladder, currency, null ); - if ( ladder != null && rankPlayer != null ) { - - List cmdTasks = new ArrayList<>(); - - RankupResults results = new RankUtil().demotePlayer(player, rankPlayer, ladder, - player.getName(), sender.getName(), pForceCharge, cmdTasks ); - - // submit cmdTasks - submitCmdTasks( player, cmdTasks ); - - processResults( sender, player.getName(), results, null, ladder, currency, null ); - } } 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."); } } From bce00a8beea09c303b02d3b71c5f972310df5ae5 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 11 Mar 2024 02:34:03 -0400 Subject: [PATCH 67/92] Prison support listeners: added support for listening to and providing dumps for PlayerDropItemEvent, PlayerPickupItemEvent, and BlockPlaceEvent. --- docs/changelog_v3.3.x.md | 5 +- .../tech/mcprison/prison/PrisonCommand.java | 3 +- .../prison/internal/platform/Platform.java | 12 ++++ .../mcprison/prison/util/PrisonStatsUtil.java | 19 ++++++ .../prison/spigot/SpigotPlatform.java | 59 +++++++++++++++++-- 5 files changed, 92 insertions(+), 6 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 503983e4f..b587a9b0e 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -18,7 +18,10 @@ These change logs represent the work that has been going on within prison. -**3.3.0-alpha.16c 2024-03-10** +**3.3.0-alpha.16c 2024-03-11** + + +* **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.** 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 ffe1a943c..5f848ac7c 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java +++ b/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java @@ -2019,7 +2019,8 @@ public void supportListenersDump(CommandSender sender, description = "Provides a detailed list of all registered event listeners for" + "the various event types. BlockBreak listeners will include all " + "listeners that are being monitored within auto features. " + - "[all, blockBreak, chat, playerInteract]" + "[all, blockBreak, blockPlace, chat, playerDropItem, " + + "playerPickupItem, playerInteract]" ) String listener ) { 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 fc11e767a..94c3d8f51 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 @@ -386,6 +386,18 @@ public String autoCreateMineLinerAssignment(ModuleElement eMine, public String dumpEventListenersPlayerInteractEvents(); + + + public String dumpEventListenersBlockPlaceEvents(); + + + public String dumpEventListenersPlayerDropItemEvents(); + + + public String dumpEventListenersPlayerPickupItemEvents(); + + + public void testPlayerUtil( UUID uuid ); 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 a597c11ae..1b00164f5 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 @@ -338,6 +338,12 @@ public StringBuilder getSupportSubmitListenersData( String listenerType ) { 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||" ); @@ -356,6 +362,19 @@ public StringBuilder getSupportSubmitListenersData( String listenerType ) { 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; } 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 92dfed8bd..5acb0a6a1 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 @@ -48,9 +48,12 @@ import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.event.EventPriority; +import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.player.AsyncPlayerChatEvent; import org.bukkit.event.player.PlayerChatEvent; +import org.bukkit.event.player.PlayerDropItemEvent; import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerPickupItemEvent; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.RegisteredListener; @@ -2759,17 +2762,19 @@ public String dumpEventListenersBlockBreakEvents() { blockEvents.dumpEventListeners( sb ); + // 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( "&2. . Prison Internal BlockBreakEvents: " + - "tech.mcprison.prison.spigot.SpigotListener\n" ); + "tmps.SpigotListener\n" ); sb.append( "&2. . Auto Features: " + - "tmpsae.AutoManagerBlockBreakEvents$AutoManagerBlockBreakEventListener\n" ); + "tmps.ae.AutoManagerBlockBreakEvents$AutoManagerBlockBreakEventListener\n" ); sb.append( "&2. . Prison's multi-block explosions (bombs): " + "tmpsae.AutoManagerPrisonsExplosiveBlockBreakEvents$AutoManagerExplosiveBlockBreakEventListener\n" ); sb.append( "&2. . Prison Abbrv: '&3tmps.&2' = '&3tech..==..mcprison.prison.spigot.&2' & " + - "'&3tmpsae.&2' = '&3tmps..==..autofeatures.events.&2'\n" ); + "'&3tmps.ae.&2' = '&3tmps..==..autofeatures.events.&2'\n" ); // sb.append( "&2. . Auto Feature Core: Non-AutoManager: " + @@ -2824,7 +2829,7 @@ public String dumpEventListenersBlockBreakEvents() { // 'tmpsae.' = 'tmps.autofeatures.events.' String results = sb.toString() .replace( "tech.mcprison.prison.spigot.", "tmps." ) - .replace( "tmps.autofeatures.events.", "tmpsae." ) + .replace( "tmps.autofeatures.events.", "tmps.ae." ) .replace( "..==..", "." ); return results; @@ -2868,6 +2873,52 @@ public String dumpEventListenersPlayerInteractEvents() { return sb.toString(); } + @Override + public String dumpEventListenersBlockPlaceEvents() { + StringBuilder sb = new StringBuilder(); + + ChatDisplay eventDisplay = dumpEventListenersChatDisplay( + "BlockPlaceEvent", + new SpigotHandlerList( BlockPlaceEvent.getHandlerList()) ); + if ( eventDisplay != null ) { + sb.append( eventDisplay.toStringBuilder() ); + } + + return sb.toString(); + } + + @Override + public String dumpEventListenersPlayerDropItemEvents() { + StringBuilder sb = new StringBuilder(); + + ChatDisplay eventDisplay = dumpEventListenersChatDisplay( + "PlayerDropItemEvent", + new SpigotHandlerList( PlayerDropItemEvent.getHandlerList()) ); + if ( eventDisplay != null ) { + sb.append( eventDisplay.toStringBuilder() ); + } + + return sb.toString(); + } + + @Override + public String dumpEventListenersPlayerPickupItemEvents() { + StringBuilder sb = new StringBuilder(); + + try { + ChatDisplay eventDisplay = dumpEventListenersChatDisplay( + "PlayerPickupItemEvent", + new SpigotHandlerList( PlayerPickupItemEvent.getHandlerList()) ); + if ( eventDisplay != null ) { + sb.append( eventDisplay.toStringBuilder() ); + } + } catch (Exception e) { + sb.append( "The PlayerPickupItemEvent is not valid on this version of spigot." ); + } + + return sb.toString(); + } + /** *

Some information on events... *

From 8ea166473800e4d1144d1a0c7843c1d483261f3d Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 11 Mar 2024 02:34:58 -0400 Subject: [PATCH 68/92] Prison support listeners: added support for listening to and providing dumps for PlayerDropItemEvent, PlayerPickupItemEvent, and BlockPlaceEvent. --- .../tech/mcprison/prison/TestPlatform.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) 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 ad688cbd5..74eb4933e 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/TestPlatform.java +++ b/prison-core/src/test/java/tech/mcprison/prison/TestPlatform.java @@ -572,4 +572,22 @@ public String getRankByFileName(String name) { public Map loadYaml(File file) { return new TreeMap(); } + + @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; + } } From 2d3b8ce902416f7ed3f0a3dfc70596c08167ce48 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 11 Mar 2024 02:37:15 -0400 Subject: [PATCH 69/92] Add support for getting the "hand" from the BlockPlaceEvent. --- docs/changelog_v3.3.x.md | 3 +++ .../mcprison/prison/spigot/compat/Compatibility.java | 3 +++ .../mcprison/prison/spigot/compat/Spigot_1_13.java | 10 ++++++++++ .../tech/mcprison/prison/spigot/compat/Spigot_1_8.java | 6 ++++++ .../tech/mcprison/prison/spigot/compat/Spigot_1_9.java | 10 ++++++++++ 5 files changed, 32 insertions(+) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index b587a9b0e..d35c6c4c2 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -21,6 +21,9 @@ These change logs represent the work that has been going on within prison. **3.3.0-alpha.16c 2024-03-11** +* **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.** 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 2740820fd..ce342617a 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 @@ -21,6 +21,7 @@ import org.bukkit.Location; import org.bukkit.Sound; import org.bukkit.entity.Player; +import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; @@ -39,6 +40,8 @@ public interface Compatibility public EquipmentSlot getHand(PlayerInteractEvent e); + + public EquipmentSlot getHand(BlockPlaceEvent e); public ItemStack getItemInMainHand(PlayerInteractEvent e); 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 86c3642a8..c14d3a370 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 @@ -4,6 +4,7 @@ import org.bukkit.Location; import org.bukkit.Sound; import org.bukkit.entity.Player; +import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; @@ -25,6 +26,15 @@ public EquipmentSlot getHand(PlayerInteractEvent e) { } } + @Override + public EquipmentSlot getHand(BlockPlaceEvent e) { + if (e.getHand() == null) { + return null; + } else { + return EquipmentSlot.valueOf(e.getHand().name()); + } + } + @Override public ItemStack getItemInMainHand(PlayerInteractEvent e) { return getItemInMainHand( e.getPlayer() ); 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 ec7cffb74..67fb01c47 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 @@ -22,6 +22,7 @@ import org.bukkit.Location; import org.bukkit.Sound; import org.bukkit.entity.Player; +import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; @@ -43,6 +44,11 @@ public class Spigot_1_8 public EquipmentSlot getHand(PlayerInteractEvent e) { return EquipmentSlot.HAND; // Spigot 1.8 only has one hand } + + @Override + public EquipmentSlot getHand(BlockPlaceEvent e) { + return EquipmentSlot.HAND; // Spigot 1.8 only has one hand + } @Override public ItemStack getItemInMainHand(PlayerInteractEvent e) { 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 b6fb32c73..7f005893f 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 @@ -22,6 +22,7 @@ import org.bukkit.Location; import org.bukkit.Sound; import org.bukkit.entity.Player; +import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; @@ -48,6 +49,15 @@ public EquipmentSlot getHand(PlayerInteractEvent e) { } } + @Override + public EquipmentSlot getHand(BlockPlaceEvent e) { + if (e.getHand() == null) { + return null; + } else { + return EquipmentSlot.valueOf(e.getHand().name()); + } + } + @Override public ItemStack getItemInMainHand(PlayerInteractEvent e) { return getItemInMainHand( e.getPlayer() ); From 8d21821860bda388a2b49b07189fcb0c2dabf0d4 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 11 Mar 2024 02:39:39 -0400 Subject: [PATCH 70/92] Prison's NBT: Add support for using NBTs with bukkit's Block. --- docs/changelog_v3.3.x.md | 3 +++ .../prison/spigot/nbt/PrisonNBTUtil.java | 24 +++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index d35c6c4c2..4faf92176 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -21,6 +21,9 @@ These change logs represent the work that has been going on within prison. **3.3.0-alpha.16c 2024-03-11** +* **Prison's NBT: Add support for using NBTs with bukkit's Block.** + + * **Add support for getting the "hand" from the BlockPlaceEvent.** 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 415409308..ed4edbff0 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 @@ -2,11 +2,14 @@ import java.util.function.Function; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; import org.bukkit.inventory.ItemStack; import de.tr7zw.changeme.nbtapi.NBT; import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT; import de.tr7zw.changeme.nbtapi.iface.ReadableItemNBT; +import de.tr7zw.changeme.nbtapi.iface.ReadableNBT; import tech.mcprison.prison.output.Output; /** @@ -50,6 +53,18 @@ public static String getNBTString( ItemStack bukkitStack, String key ) { return results; } + + 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 ); + + return results; + } public static void setNBTString( ItemStack bukkitStack, String key, String value ) { @@ -108,12 +123,21 @@ public static void nbtDebugLog( ItemStack bukkitStack, String desc ) { } } + public static String nbtDebugString( ItemStack bukkitStack ) { ReadWriteNBT nbtItem = NBT.itemStackToNBT(bukkitStack); return nbtItem.toString(); } + public static String nbtDebugString() { + + ReadWriteNBT nbtItem = NBT.createNBTObject(); + +// ReadWriteNBT nbtItem = NBT.itemStackToNBT(bukkitStack); + return nbtItem.toString(); + } + // public NBTItem getNBT( ItemStack bukkitStack ) { // NBTItem nbtItemStack = null; // From 785cead26d54ba3accbcf7479c4c3977cc828946 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 11 Mar 2024 02:42:48 -0400 Subject: [PATCH 71/92] Mine bombs: add support for BlockPlacementEvent so if someone is using a Block they can use it as the mine bomb's item. --- docs/changelog_v3.3.x.md | 2 + .../spigot/utils/PrisonBombListener.java | 237 +++++++++++------- 2 files changed, 153 insertions(+), 86 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 4faf92176..92c4d8421 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -20,6 +20,8 @@ These change logs represent the work that has been going on within prison. **3.3.0-alpha.16c 2024-03-11** +* **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.** 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 966b638fc..949c109fa 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 @@ -4,11 +4,14 @@ import java.util.List; import org.bukkit.Material; +import org.bukkit.block.Block; import org.bukkit.entity.Player; +import org.bukkit.event.Event; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.block.Action; +import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.player.PlayerDropItemEvent; import org.bukkit.event.player.PlayerInteractEvent; @@ -51,6 +54,44 @@ public PrisonBombListener( PrisonUtilsMineBombs utilsMineBombs ) { this.blockBreakMines = new OnBlockBreakMines(); } + + @EventHandler( priority = EventPriority.LOW ) + public void onInteract( BlockPlaceEvent event ) { + + String bombName = PrisonNBTUtil.getNBTString( event.getBlockPlaced(), + MineBombs.MINE_BOMBS_NBT_BOMB_KEY ); + + if ( bombName == null || bombName.trim().length() == 0 ) { +// if ( !nbtItem.hasKey( MineBombs.MINE_BOMBS_NBT_BOMB_KEY ) ) { + return; + } + + if ( Output.get().isDebug() ) { + Output.get().logInfo( "PrisonBombListener.onInteract (block) " + + "bombName: &7%s&r &3:: nbt: &r%s", + bombName, + PrisonNBTUtil.nbtDebugString( ) +// PrisonNBTUtil.nbtDebugString( event.getBlockPlaced() ) +// (nbtItem == null ? "&a-no-nbt-" : nbtItem.toString()) + ); + + + Player player = event.getPlayer(); + + Block targetBlock = event.getBlockAgainst(); + + EquipmentSlot hand = SpigotCompatibility.getInstance().getHand(event); + + boolean canceled = processBombTriggerEvent(event, player, bombName, + targetBlock, hand ); + + if ( canceled ) { + event.setCancelled( canceled ); + } + + } + + } @EventHandler( priority = EventPriority.LOW ) public void onInteract( PlayerInteractEvent event ) { @@ -84,7 +125,8 @@ public void onInteract( PlayerInteractEvent event ) { // String bombName = nbtItem.getString( MineBombs.MINE_BOMBS_NBT_BOMB_KEY ); if ( Output.get().isDebug() ) { - Output.get().logInfo( "PrisonBombListener.onInteract bombName: &7%s&r &3:: nbt: &r%s", + Output.get().logInfo( "PrisonBombListener.onInteract (item) " + + "bombName: &7%s&r &3:: nbt: &r%s", bombName, PrisonNBTUtil.nbtDebugString( event.getItem() ) // (nbtItem == null ? "&a-no-nbt-" : nbtItem.toString()) @@ -93,6 +135,27 @@ public void onInteract( PlayerInteractEvent event ) { Player player = event.getPlayer(); + Block targetBlock = event.getClickedBlock(); + + EquipmentSlot hand = SpigotCompatibility.getInstance().getHand(event); + + boolean canceled = processBombTriggerEvent(event, player, bombName, + targetBlock, hand ); + + if ( canceled ) { + event.setCancelled( canceled ); + } + + } + } + + private boolean processBombTriggerEvent( Event event, Player player, + String bombName, Block targetBlock, + EquipmentSlot hand ) { + + boolean canceled = false; + + // // Temp test stuff... remove when NBTs are working: // { // @@ -110,95 +173,97 @@ public void onInteract( PlayerInteractEvent event ) { // 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; - } - - 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 ( event.getClickedBlock() == 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( event.getClickedBlock() ); - } - - - Mine mine = blockBreakMines.findMine(player, 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." ); - } - - event.setCancelled( true ); - return; - } - 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()); - } - - event.setCancelled( true ); - return; - } - - HashSet allowedMines = new HashSet<>( bomb.getAllowedMines() ); - HashSet preventedMines = new HashSet<>( bomb.getPreventedMines() ); - List globalPreventedMines = (List) Prison.get().getPlatform() - .getConfigStringArray("prison-mines.mine-bombs.prevent-usage-in-mines"); - preventedMines.addAll( globalPreventedMines ); - - // Skip prevent-in-mines check if mine is within the allowedMines list: - if ( !allowedMines.contains( mine.getName().toLowerCase() ) ) { - - if ( preventedMines.contains( mine.getName().toLowerCase() ) ) { - - // Mine bombs are not allowed to be used in this mine so cancel: - event.setCancelled( true ); - return; - } - } + + 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 = blockBreakMines.findMine(player, 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." ); + } + + 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: + + if ( Output.get().isDebug() ) { + Output.get().logInfo( "MineBombs: Player %s&r does not have access to Mine %s&r.", + sPlayer.getName(), mine.getName()); + } + + canceled = true; +// event.setCancelled( true ); + return canceled; + } + + HashSet allowedMines = new HashSet<>( bomb.getAllowedMines() ); + HashSet preventedMines = new HashSet<>( bomb.getPreventedMines() ); + List globalPreventedMines = (List) Prison.get().getPlatform() + .getConfigStringArray("prison-mines.mine-bombs.prevent-usage-in-mines"); + preventedMines.addAll( globalPreventedMines ); + + // Skip prevent-in-mines check if mine is within the allowedMines list: + if ( !allowedMines.contains( mine.getName().toLowerCase() ) ) { + + if ( preventedMines.contains( mine.getName().toLowerCase() ) ) { + + // Mine bombs are not allowed to be used in this mine so cancel: + canceled = true; +// event.setCancelled( true ); + return canceled; + } + } - - // getHand() is not available with bukkit 1.8.8 so use the compatibility functions: - EquipmentSlot hand = SpigotCompatibility.getInstance().getHand(event); + + // 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( player, 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. - + if ( getPrisonUtilsMineBombs().setBombInHand( player, 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. + // Output.get().logInfo( "### PrisonBombListener: PlayerInteractEvent 03 Bomb detected - May not have been set. " ); - event.setCancelled( true ); - } - - - - } - } + canceled = true; +// event.setCancelled( true ); + } + + return canceled; + } // @EventHandler( priority = EventPriority.HIGHEST, ignoreCancelled = false ) From 1138afcabcf792a0f22f762422c4833a321db1dc Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 11 Mar 2024 02:57:28 -0400 Subject: [PATCH 72/92] XSeries: Upgrade from v9.8.0 to v9.9.0 --- docs/changelog_v3.3.x.md | 4 ++++ prison-spigot/build.gradle | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 92c4d8421..cb1940d10 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -20,6 +20,10 @@ These change logs represent the work that has been going on within prison. **3.3.0-alpha.16c 2024-03-11** + +* **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.** diff --git a/prison-spigot/build.gradle b/prison-spigot/build.gradle index d568569e1..19c225609 100644 --- a/prison-spigot/build.gradle +++ b/prison-spigot/build.gradle @@ -149,7 +149,8 @@ dependencies { // https://mvnrepository.com/artifact/com.github.cryptomorin/XSeries - implementation 'com.github.cryptomorin:XSeries:9.8.0' + implementation 'com.github.cryptomorin:XSeries:9.9.0' +// implementation 'com.github.cryptomorin:XSeries:9.8.0' //implementation 'com.github.cryptomorin:XSeries:9.4.0' //implementation 'com.github.cryptomorin:XSeries:9.2.0' From 1afda976ae5575c339d5ab9a7bdff129ce7318ca Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 11 Mar 2024 03:01:45 -0400 Subject: [PATCH 73/92] PlaceholderAPI: Upgrade from v2.11.2 to v2.11.5 --- docs/changelog_v3.3.x.md | 3 +++ prison-spigot/build.gradle | 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 cb1940d10..b94d47bf5 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -21,6 +21,9 @@ These change logs represent the work that has been going on within prison. **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** diff --git a/prison-spigot/build.gradle b/prison-spigot/build.gradle index 19c225609..b94f6db3a 100644 --- a/prison-spigot/build.gradle +++ b/prison-spigot/build.gradle @@ -136,7 +136,8 @@ dependencies { - compileOnly 'me.clip:placeholderapi:2.11.2' + compileOnly 'me.clip:placeholderapi:2.11.5' + //compileOnly 'me.clip:placeholderapi:2.11.2' //compileOnly 'me.clip:placeholderapi:2.10.9' // Repo may be hosted: https://hub.spigotmc.org/nexus/content/groups/public/ From 43e2752c31cd3a02f73a1f891c83fd2c6bb4f5d1 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 14 Mar 2024 17:41:50 -0400 Subject: [PATCH 74/92] Initial setup of sellall lore filtering --- docs/changelog_v3.3.x.md | 5 +- .../prison/internal/block/PrisonBlock.java | 8 ++ .../commands/PrisonSpigotSellAllCommands.java | 60 ++++++++++++ .../prison/spigot/sellall/SellAllUtil.java | 91 +++++++++++++++++-- 4 files changed, 157 insertions(+), 7 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index b94d47bf5..9f680084e 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.16c 2024-03-05 +# 3.3.0-alpha.16c 2024-03-14 + + +* **Initial setup of sellall lore filtering** 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 2679d178f..be4af9ed8 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 @@ -45,6 +45,7 @@ public class PrisonBlock private Double salePrice = null; private Double purchasePrice = null; + private boolean loreAllowed = false; static { @@ -526,4 +527,11 @@ public ItemStack getItemStack( int blockQuantity ) { return results; } + public boolean isLoreAllowed() { + return loreAllowed; + } + public void setLoreAllowed(boolean loreAllowed) { + this.loreAllowed = loreAllowed; + } + } 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 543490482..1bb2dce5e 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 @@ -865,6 +865,66 @@ private void sellAllEditCommand(CommandSender sender, } + @Command(identifier = "sellall items allowLore", + description = "Edits an existing SellAll shop item to either allow the sellable items " + + "to have lore or not. If an item is not allowed to have lore, but the itemm " + + "that is intended to be sold has lore, then the item will not be sellable..", + permissions = "prison.admin", onlyPlayers = false) + private void sellAllAllowLoreCommand(CommandSender sender, + @Arg(name = "Item_ID", description = "The Item_ID or block to add to the sellAll Shop.") String itemID, + @Arg(name = "allowLore", description = "Allow lore to be used. " + + "Default: 'false'. [true, allow, false] Invalid values are treated as 'false'.", + def = "false") + String isLoreAllowed ){ + + if ( !isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ + return; + } + SellAllUtil sellAllUtil = SellAllUtil.get(); + + if (itemID == null){ + Output.get().sendWarn(sender, messages.getString(MessagesConfig.StringID.spigot_message_sellall_item_missing_name)); + return; + } + itemID = itemID.toUpperCase(); + + + if (sellAllUtil.sellAllConfig.getConfigurationSection("Items." + itemID) == null){ + Output.get().sendWarn(sender, itemID + " " + messages.getString(MessagesConfig.StringID.spigot_message_sellall_item_not_found)); + return; + } + + boolean allowLore = false; + + if ( isLoreAllowed != null && + ("true".equalsIgnoreCase(isLoreAllowed) || "allow".equalsIgnoreCase(isLoreAllowed)) ) { + allowLore = true; + } + + +// sender.sendMessage("not yet enabled"); +// return; + + try { + XMaterial blockAdd; + try { + blockAdd = XMaterial.valueOf(itemID); + } 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 )) { + + Output.get().sendInfo(sender, "&3ITEM [" + itemID + ", allowLore= " + allowLore + "] " + 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 + "]"); + } + } + + @Command(identifier = "sellall multiplier list", description = "Lists all of the SellAll Rank multipliers", permissions = "prison.admin", onlyPlayers = false) 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 168eb2948..145bc08a3 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 @@ -907,9 +907,23 @@ private SellAllData sellItemStack( SpigotItemStack iStack, double multiplier ) { PrisonBlock pBlockSellAll = sellAllItems.get( pBlockInv.getBlockNameSearch() ); if ( pBlockSellAll != null ) { - double amount = iStack.getAmount() * pBlockSellAll.getSalePrice() * multiplier; - soldItem = new SellAllData( pBlockSellAll, iStack.getAmount(), amount ); + 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 ( Output.get().isDebug() ) { + Output.get().logInfo( msg ); + } + + } + else { + + double amount = iStack.getAmount() * pBlockSellAll.getSalePrice() * multiplier; + soldItem = new SellAllData( pBlockSellAll, iStack.getAmount(), amount ); + } } } @@ -1248,19 +1262,20 @@ public HashMap initSellAllItems(){ for (String key : sellAllConfig.getConfigurationSection("Items").getKeys(false)) { String itemName = key.trim().toUpperCase(); + String itemPrefix = "Items." + itemName; - String itemID = sellAllConfig.getString("Items." + itemName + ".ITEM_ID"); + String itemID = sellAllConfig.getString( itemPrefix + ".ITEM_ID"); PrisonBlock pBlock = Prison.get().getPlatform().getPrisonBlock(itemID); if ( pBlock != null ) { - String itemDisplayName = sellAllConfig.getString("Items." + itemName + ".ITEM_DISPLAY_NAME"); + String itemDisplayName = sellAllConfig.getString( itemPrefix + ".ITEM_DISPLAY_NAME"); if ( itemDisplayName != null ) { pBlock.setDisplayName( itemDisplayName ); } - String saleValueString = sellAllConfig.getString("Items." + itemName + ".ITEM_VALUE"); + String saleValueString = sellAllConfig.getString( itemPrefix + ".ITEM_VALUE"); if ( saleValueString != null ) { try { @@ -1270,7 +1285,7 @@ public HashMap initSellAllItems(){ } } - String purchaseValueString = sellAllConfig.getString("Items." + itemName + ".PURCHASE_PRICE"); + String purchaseValueString = sellAllConfig.getString( itemPrefix + ".PURCHASE_PRICE"); if ( purchaseValueString != null ) { try { @@ -1280,6 +1295,19 @@ public HashMap initSellAllItems(){ } } + 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 ); } @@ -1387,6 +1415,10 @@ public boolean addSellAllBlock(XMaterial xMaterial, String displayName, double v return false; } + + // pBlock is null, but it's being used below. So clone the key: + pBlock = pBlockKey.clone(); + try { String itemName = pBlockKey.getBlockName().toUpperCase(); @@ -1395,6 +1427,7 @@ public boolean addSellAllBlock(XMaterial xMaterial, String displayName, double v 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() ); if ( displayName != null ) { conf.set("Items." + itemName + ".ITEM_DISPLAY_NAME", displayName ); @@ -1732,6 +1765,7 @@ public boolean editPrice(XMaterial xMaterial, String displayName, double value) 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); @@ -1763,6 +1797,51 @@ public boolean editPrice(XMaterial xMaterial, String displayName, double value) return true; } + + + public boolean editAllowLore(XMaterial xMaterial, boolean 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.isLoreAllowed() == value ){ + Output.get().logDebug( "sellall edit: No change in 'allow lore' (%s %s)", + pBlockKey.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 = key.toUpperCase(); +// conf.set("Items." + itemName + ".ITEM_ID", key ); + conf.set("Items." + itemName + ".IS_LORE_ALLOWED", pBlock.isLoreAllowed() ); + + 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 +// sellAllBlocks.put(xMaterial, value); + + return true; + } // /** // * BUG: With Spigot versions less than 1.13 bukkit's Material will not work on all Materials since From 77e58e8f02d7b2f095bdab7675fe143ed47f7141 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 14 Mar 2024 17:46:06 -0400 Subject: [PATCH 75/92] Sellall: a little clean up. --- docs/changelog_v3.3.x.md | 2 +- .../commands/PrisonSpigotSellAllCommands.java | 63 ++++++++++--------- 2 files changed, 34 insertions(+), 31 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 9f680084e..a7d83b5a2 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -18,7 +18,7 @@ These change logs represent the work that has been going on within prison. * **Initial setup of sellall lore filtering** - +A little clean up. **3.3.0-alpha.16c 2024-03-11** 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 1bb2dce5e..4709217de 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 @@ -47,7 +47,7 @@ public class PrisonSpigotSellAllCommands extends PrisonSpigotBaseCommands { /** * Check if SellAll's enabled. * */ - public static boolean isEnabled(){ + public static boolean isEnabled() { return SpigotPrison.getInstance().isSellAllEnabled(); } @@ -59,9 +59,6 @@ public static PrisonSpigotSellAllCommands get() { if (instance == null && isEnabled()) { instance = new PrisonSpigotSellAllCommands(); } - if (instance == null){ - return null; - } return instance; } @@ -92,7 +89,9 @@ private void sellAllCurrency(CommandSender sender, onlyPlayers = false) private void sellAllCommands(CommandSender sender) { - if (!isEnabled()) return; + if ( !isEnabled() ) { + return; + } if (sender.hasPermission("prison.admin")) { sender.dispatchCommand("sellall help"); @@ -115,7 +114,7 @@ private void sellAllDelay(CommandSender sender, description = "True to enable or false to disable.", def = "false") String enable){ - if (!isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ + if ( !isEnabled() ){ return; } SellAllUtil sellAllUtil = SellAllUtil.get(); @@ -153,7 +152,7 @@ private void sellAllDelaySet(CommandSender sender, @Arg(name = "delay", description = "Set delay value in seconds. Defaults to a value of 15 seconds.", def = "15") String delay){ - if ( !isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ + if ( !isEnabled() ) { return; } SellAllUtil sellAllUtil = SellAllUtil.get(); @@ -182,7 +181,7 @@ private void sellAllAutoSell(CommandSender sender, + "[true false perUserToggleable]", def = "true") String enable){ - if ( !isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ + if ( !isEnabled() ){ return; } SellAllUtil sellAllUtil = SellAllUtil.get(); @@ -229,7 +228,7 @@ private void sellAllAutoSellPerUserToggleable(CommandSender sender, description = "'True' to enable or 'false' to disable. [true false]", def = "") String enable){ - if (!isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ + if (!isEnabled() ){ return; } SellAllUtil sellAllUtil = SellAllUtil.get(); @@ -266,7 +265,9 @@ public void sellAllSellCommand(CommandSender sender, description = "Notification behavior for the sellall transaction. Defaults to normal. " + "'silent' suppresses all notifications. [silent]") String notification ){ - if (!isEnabled()) return; + if ( !isEnabled() ) { + return; + } Player p = getSpigotPlayer(sender); @@ -341,7 +342,7 @@ else if (p == null){ onlyPlayers = true) public void sellAllSellHandCommand(CommandSender sender){ - if (!isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ + if ( !isEnabled() ){ return; } SellAllUtil sellAllUtil = SellAllUtil.get(); @@ -383,7 +384,7 @@ public void sellAllSellHandCommand(CommandSender sender){ } public void sellAllSell(Player p){ - if ( !isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ + if ( !isEnabled() ){ return; } SellAllUtil sellAllUtil = SellAllUtil.get(); @@ -425,7 +426,7 @@ public void sellAllValueOfCommand(CommandSender sender, "Only console or prison commands can include this parameter") String playerName ){ - if (!isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ + if ( !isEnabled() ) { return; } SellAllUtil sellAllUtil = SellAllUtil.get(); @@ -500,7 +501,7 @@ else if (p == null){ onlyPlayers = true) public void sellAllValueOfHandCommand(CommandSender sender){ - if (!isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ + if ( !isEnabled() ){ return; } SellAllUtil sellAllUtil = SellAllUtil.get(); @@ -547,7 +548,7 @@ public void sellAllValueOfHandCommand(CommandSender sender){ onlyPlayers = true) public void sellAllSellWithDelayCommand(CommandSender sender){ - if ( !isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ + if ( !isEnabled() ) { return; } SellAllUtil sellAllUtil = SellAllUtil.get(); @@ -594,7 +595,7 @@ public void sellAllSellWithDelayCommand(CommandSender sender){ altPermissions = "prison.sellall.toggle", onlyPlayers = true) private void sellAllAutoEnableUser(CommandSender sender){ - if (!isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ + if ( !isEnabled() ) { return; } StringBuilder debugInfo = new StringBuilder(); @@ -719,7 +720,7 @@ private void sellAllAddCommand(CommandSender sender, description = "The Item_ID or block to add to the sellAll Shop.") String itemID, @Arg(name = "Value", description = "The value of the item.") Double value){ - if (!isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ + if ( !isEnabled() ){ return; } SellAllUtil sellAllUtil = SellAllUtil.get(); @@ -793,7 +794,7 @@ public void sellAllAddCommand(XMaterial blockAdd, Double value){ private void sellAllDeleteCommand(CommandSender sender, @Arg(name = "Item_ID", description = "The Item_ID you want to remove.") String itemID){ - if ( !isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ + if ( !isEnabled() ) { return; } SellAllUtil sellAllUtil = SellAllUtil.get(); @@ -824,7 +825,7 @@ private void sellAllEditCommand(CommandSender sender, @Arg(name = "Item_ID", description = "The Item_ID or block to add to the sellAll Shop.") String itemID, @Arg(name = "Value", description = "The value of the item.") Double value){ - if ( !isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ + if ( !isEnabled() ) { return; } SellAllUtil sellAllUtil = SellAllUtil.get(); @@ -877,7 +878,7 @@ private void sellAllAllowLoreCommand(CommandSender sender, def = "false") String isLoreAllowed ){ - if ( !isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ + if ( !isEnabled() ) { return; } SellAllUtil sellAllUtil = SellAllUtil.get(); @@ -936,7 +937,7 @@ private void sellAllMultiplierCommand(CommandSender sender, + "columns in the output by using 'cols=16', where the default is 10 columns. ") String options ) { - if ( !isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ + if ( !isEnabled() ) { return; } SellAllUtil sellAllUtil = SellAllUtil.get(); @@ -1144,7 +1145,7 @@ private void sellAllAddMultiplierCommand(CommandSender sender, @Arg(name = "rank", description = "The rank name for the multiplier.") String rank, @Arg(name = "multiplier", description = "Multiplier value.") Double multiplier) { - if (!isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ + if (!isEnabled() ) { return; } SellAllUtil sellAllUtil = SellAllUtil.get(); @@ -1168,7 +1169,7 @@ private void sellAllAddMultiplierCommand(CommandSender sender, private void sellAllDeleteMultiplierCommand(CommandSender sender, @Arg(name = "Rank", description = "The rank name of the multiplier.") String rank){ - if ( !isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ + if ( !isEnabled() ) { return; } SellAllUtil sellAllUtil = SellAllUtil.get(); @@ -1206,7 +1207,7 @@ private void sellAllMultiplierDeleteLadderCommand( ) { - if ( !isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ + if ( !isEnabled() ) { return; } SellAllUtil sellAllUtil = SellAllUtil.get(); @@ -1278,7 +1279,7 @@ private void sellAllMultiplierAddLadderCommand( ) { - if ( !isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ + if ( !isEnabled() ) { return; } SellAllUtil sellAllUtil = SellAllUtil.get(); @@ -1346,7 +1347,7 @@ private void sellAllMultiplierAddLadderCommand( private void sellAllToolsTriggerToggle(CommandSender sender, @Arg(name = "Boolean", description = "Enable or disable", def = "true") String enable){ - if (!isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ + if (!isEnabled() ) { return; } SellAllUtil sellAllUtil = SellAllUtil.get(); @@ -1389,7 +1390,7 @@ private void sellAllToolsTriggerToggle(CommandSender sender, private void sellAllTriggerAdd(CommandSender sender, @Arg(name = "Item", description = "Item name") String itemID){ - if (!isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ + if (!isEnabled() ) { return; } SellAllUtil sellAllUtil = SellAllUtil.get(); @@ -1428,7 +1429,7 @@ private void sellAllTriggerAdd(CommandSender sender, private void sellAllTriggerDelete(CommandSender sender, @Arg(name = "Item", description = "Item name") String itemID){ - if (!isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ + if ( !isEnabled() ) { return; } SellAllUtil sellAllUtil = SellAllUtil.get(); @@ -1466,7 +1467,9 @@ private void sellAllTriggerDelete(CommandSender sender, permissions = "prison.admin", onlyPlayers = false) private void sellAllSetDefaultCommand(CommandSender sender){ - if (!isEnabled()) return; + if ( !isEnabled() ) { + return; + } // Setup all the prices in sellall: SpigotPlatform platform = (SpigotPlatform) Prison.get().getPlatform(); @@ -1484,7 +1487,7 @@ private void sellAllSetDefaultCommand(CommandSender sender){ permissions = "prison.admin", onlyPlayers = false) private void sellAllListItems( CommandSender sender ) { - if ( !isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ + if ( !isEnabled() ) { return; } SellAllUtil sellAllUtil = SellAllUtil.get(); From 2ec6277e8e039320b289e1d8e2c49b5d0cee8e0b Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 15 Mar 2024 01:25:28 -0400 Subject: [PATCH 76/92] 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. --- docs/changelog_v3.3.x.md | 6 ++- .../mcprison/prison/internal/ItemStack.java | 42 +++++++++---------- .../prison/spigot/block/SpigotItemStack.java | 34 +++++++++++++++ 3 files changed, 60 insertions(+), 22 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index a7d83b5a2..b5d24c1af 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.16c 2024-03-14 +# 3.3.0-alpha.16c 2024-03-15 + + +* **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** 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 880d0cb85..c49d47b4b 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 @@ -20,9 +20,7 @@ import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; import java.util.List; -import java.util.Map; import org.apache.commons.lang3.StringUtils; @@ -41,14 +39,14 @@ public class ItemStack { private int amount; private PrisonBlock material; private List lore; - private Map enchantments; +// private Map enchantments; protected ItemStack() { super(); this.lore = new ArrayList<>(); - this.enchantments = new HashMap<>(); +// this.enchantments = new HashMap<>(); } public ItemStack(String displayName, int amount, PrisonBlock material, String... lore) { @@ -56,7 +54,7 @@ public ItemStack(String displayName, int amount, PrisonBlock material, String... this.amount = amount; this.material = material; this.lore = new ArrayList<>(Arrays.asList(lore)); - this.enchantments = new HashMap<>(); +// this.enchantments = new HashMap<>(); } public ItemStack(int amount, PrisonBlock material, String... lore) { @@ -114,21 +112,21 @@ public void setLore( List lore ) { this.lore = lore; } - public Map getEnchantments() { - return enchantments; - } - - public void addEnchantment(int enchantment, int level) { - enchantments.put(enchantment, level); - } - - public boolean hasEnchantments() { - return !enchantments.isEmpty(); - } - - public boolean hasEnchantment(int enchantment) { - return enchantments.containsKey(enchantment); - } +// 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) { if (this == o) { @@ -157,6 +155,8 @@ public boolean hasEnchantment(int enchantment) { @Override public String toString() { return "ItemStack{" + "displayName='" + displayName + '\'' + ", amount=" + amount - + ", material=" + material + ", lore=" + lore + ", enchantments=" + enchantments + '}'; + + ", material=" + material + ", lore=" + lore + + "}"; + //", enchantments=" + enchantments + '}'; } } 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 8d1a6bc1a..a35990cd1 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 @@ -265,6 +265,15 @@ public void setNBTString( String key, String value ) { // } } + + + public String getNBTItemStackInfo() { + + String results = PrisonNBTUtil.nbtDebugString(getBukkitStack()) ; + + return results; + } + // public int getNBTInt( String key ) { // int results = -1; // @@ -349,6 +358,18 @@ public void setAmount( int amount ) { } } + /** + *

This function will add the given amount to the item stack's total amount. + *

+ * + * @param i amount to add to this itemStack + */ + public void addToAmount( int i ) { + int amt = getAmount() + i; + setAmount( amt ); + } + + private ItemMeta getMeta() { ItemMeta meta; if (!bukkitStack.hasItemMeta()) { @@ -468,6 +489,19 @@ public static SpigotItemStack deserialize( Map map ) return sItemStack; } + + public Map getEnchantments() { + Map results = null; + + ItemMeta meta = getMeta(); + if ( meta != null && + meta.getEnchants() != null && + meta.getEnchants().size() > 0 ) { + + results = meta.getEnchants(); + } + return results; + } /** *

This function will return information on the item in the item stack, which is for From 75573167eb7809a5d891927b476e0b7e1047850d Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 15 Mar 2024 01:27:18 -0400 Subject: [PATCH 77/92] 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. --- docs/changelog_v3.3.x.md | 3 + .../spigot/utils/PrisonBombListener.java | 131 +++++++++--------- 2 files changed, 71 insertions(+), 63 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index b5d24c1af..14715464e 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.16c 2024-03-15 +* **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. 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 949c109fa..83ac8ca39 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 @@ -14,6 +14,7 @@ import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.player.PlayerDropItemEvent; import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; import tech.mcprison.prison.Prison; import tech.mcprison.prison.bombs.MineBombData; @@ -58,39 +59,31 @@ public PrisonBombListener( PrisonUtilsMineBombs utilsMineBombs ) { @EventHandler( priority = EventPriority.LOW ) public void onInteract( BlockPlaceEvent event ) { - String bombName = PrisonNBTUtil.getNBTString( event.getBlockPlaced(), - MineBombs.MINE_BOMBS_NBT_BOMB_KEY ); - - if ( bombName == null || bombName.trim().length() == 0 ) { -// if ( !nbtItem.hasKey( MineBombs.MINE_BOMBS_NBT_BOMB_KEY ) ) { - return; - } - - if ( Output.get().isDebug() ) { - Output.get().logInfo( "PrisonBombListener.onInteract (block) " - + "bombName: &7%s&r &3:: nbt: &r%s", - bombName, - PrisonNBTUtil.nbtDebugString( ) -// PrisonNBTUtil.nbtDebugString( event.getBlockPlaced() ) -// (nbtItem == null ? "&a-no-nbt-" : nbtItem.toString()) - ); - - - Player player = event.getPlayer(); - - Block targetBlock = event.getBlockAgainst(); + ItemStack iStack = event.getItemInHand(); + + if ( iStack.getType() != Material.AIR ) { + - EquipmentSlot hand = SpigotCompatibility.getInstance().getHand(event); + String bombName = checkMineBombItemStack( iStack ); - boolean canceled = processBombTriggerEvent(event, player, bombName, - targetBlock, hand ); - - if ( canceled ) { - event.setCancelled( canceled ); + if ( bombName != null ) { + + Player player = event.getPlayer(); + + Block targetBlock = event.getBlockAgainst(); + + EquipmentSlot hand = SpigotCompatibility.getInstance().getHand(event); + + boolean canceled = processBombTriggerEvent(event, player, bombName, + targetBlock, hand ); + + if ( canceled ) { + event.setCancelled( canceled ); + } } - - } - + + } + } @EventHandler( priority = EventPriority.LOW ) @@ -109,46 +102,58 @@ public void onInteract( PlayerInteractEvent event ) { // 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(); - // Check to see if this is an mine bomb by checking the NBT key-value pair, - // which will also identify which mine bomb it is too. - // NOTE: Because we're just checking, do not auto update the itemstack. -// NBTItem nbtItem = new NBTItem( event.getItem() ); - - String bombName = PrisonNBTUtil.getNBTString( event.getItem(), MineBombs.MINE_BOMBS_NBT_BOMB_KEY ); - - if ( bombName == null || bombName.trim().length() == 0 ) { -// if ( !nbtItem.hasKey( MineBombs.MINE_BOMBS_NBT_BOMB_KEY ) ) { - return; - } - -// String bombName = nbtItem.getString( MineBombs.MINE_BOMBS_NBT_BOMB_KEY ); - - if ( Output.get().isDebug() ) { - Output.get().logInfo( "PrisonBombListener.onInteract (item) " - + "bombName: &7%s&r &3:: nbt: &r%s", - bombName, - PrisonNBTUtil.nbtDebugString( event.getItem() ) -// (nbtItem == null ? "&a-no-nbt-" : nbtItem.toString()) - ); - } - - Player player = event.getPlayer(); - - Block targetBlock = event.getClickedBlock(); - - EquipmentSlot hand = SpigotCompatibility.getInstance().getHand(event); + String bombName = checkMineBombItemStack( iStack ); - boolean canceled = processBombTriggerEvent(event, player, bombName, - targetBlock, hand ); - - if ( canceled ) { - event.setCancelled( canceled ); + if ( bombName != null ) { + + Player player = event.getPlayer(); + + Block targetBlock = event.getClickedBlock(); + + EquipmentSlot hand = SpigotCompatibility.getInstance().getHand(event); + + boolean canceled = processBombTriggerEvent(event, player, bombName, + targetBlock, hand ); + + if ( canceled ) { + event.setCancelled( canceled ); + } + + } } } + private String checkMineBombItemStack( ItemStack iStack ) { + // Check to see if this is an mine bomb by checking the NBT key-value pair, + // which will also identify which mine bomb it is too. + // 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 ); + + 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%s", + bombName, + PrisonNBTUtil.nbtDebugString( iStack ) +// (nbtItem == null ? "&a-no-nbt-" : nbtItem.toString()) + ); + } + } + + + return bombName; + } + private boolean processBombTriggerEvent( Event event, Player player, String bombName, Block targetBlock, EquipmentSlot hand ) { From ff1c930049a3f1872eccc9689efdac991f37a8ef Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 15 Mar 2024 01:31:50 -0400 Subject: [PATCH 78/92] 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. --- docs/changelog_v3.3.x.md | 4 +++ .../prison/internal/CommandSender.java | 36 +++++++++++++++---- .../prison/ranks/data/RankPlayer.java | 35 +++++++++--------- .../java/tech/mcprison/prison/TestPlayer.java | 13 +++++++ .../spigot/game/SpigotCommandSender.java | 28 ++++++++++++++- .../spigot/game/SpigotOfflinePlayer.java | 20 +++++++++++ 6 files changed, 111 insertions(+), 25 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 14715464e..db9570838 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.16c 2024-03-15 +* **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.** 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 19ee168ab..ea26f938f 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 @@ -39,18 +39,18 @@ public interface CommandSender /** * Returns the name of the command sender. */ - String getName(); + public String getName(); /** * Force a commandSender to send a command */ - void dispatchCommand(String command); + public void dispatchCommand(String command); /** * Returns true if the command sender can show colors to the viewer. * This is not always the case, especially when using command blocks and online consoles. */ - boolean doesSupportColors(); + public boolean doesSupportColors(); /** * Sends a message to the command sender. @@ -59,7 +59,7 @@ public interface CommandSender * * @param message The message to send. May include color codes, amp-prefixed. */ - void sendMessage(String message); + public void sendMessage(String message); /** * Sends multiple messages to the command sender. @@ -68,14 +68,23 @@ public interface CommandSender * @param messages The array containing each message. * @see #sendMessage(String) */ - void sendMessage(String[] messages); + public void sendMessage(String[] messages); + /** + * Sends multiple messages to the command sender. + * Each message will be shown on its own line. + * + * @param messages The List containing each message. + * @see #sendMessage(String) + */ + public void sendMessage(List messages); + /** * Send a raw JSON message to the sender. * * @param json The JSON message. Must be in proper format. */ - void sendRaw(String json); + public void sendRaw(String json); // public boolean isOp(); @@ -92,6 +101,19 @@ public interface CommandSender public boolean isPlayer(); - List getSellAllMultiplierListings(); + public List getSellAllMultiplierListings(); + + + /** + *

Returns an instance of a Platform player object, which is is + * different than just a RankPlayer since it was built with the wrapper of + * SpigotPlayer (when running on spigot). So this object is actually backed + * by the the actual player object too. + *

+ * + * @return Player + */ + public Player getPlatformPlayer(); + } 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 cbfbed73b..fae7183d0 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 @@ -907,6 +907,11 @@ public void sendMessage( String[] messages ) { Output.get().logError( "RankPlayer.sendMessage: Cannot send messages to offline players." ); } + @Override + public void sendMessage( List messages ) { + Output.get().logError( "RankPlayer.sendMessage: Cannot send messages to offline players." ); + } + @Override public void sendRaw( String json ) { Output.get().logError( "RankPlayer.sendRaw: Cannot send messages to offline players." ); @@ -969,7 +974,7 @@ public Optional getLocale() { @Override public boolean isOp() { - Player player = getPlayer(); + Player player = getPlatformPlayer(); return (player != null ? player.isOp() : false ); } @@ -982,14 +987,14 @@ public boolean isOp() { */ @Override public boolean isPlayer() { - Player player = getPlayer(); + Player player = getPlatformPlayer(); return (player != null ? player.isPlayer() : false ); } @Override public void updateInventory() { - Player player = getPlayer(); + Player player = getPlatformPlayer(); if ( player != null ) { player.updateInventory(); @@ -1000,7 +1005,7 @@ public void updateInventory() { public Inventory getInventory() { Inventory results = null; - Player player = getPlayer(); + Player player = getPlatformPlayer(); if ( player != null ) { results = player.getInventory(); @@ -1014,15 +1019,9 @@ public Inventory getInventory() { // // } - /** - *

Player is not cached in this class, so if using it in a function - * make a local variable to save it instead of calling this function multiple - * times since it is a high impact lookup. - *

- * - * @return - */ - private Player getPlayer() { + + @Override + public Player getPlatformPlayer() { Player player = null; Optional oPlayer = Prison.get().getPlatform().getPlayer( uid ); @@ -1030,12 +1029,14 @@ private Player getPlayer() { if ( oPlayer.isPresent() ) { player = oPlayer.get(); } + return player; } + @Override public void recalculatePermissions() { - Player player = getPlayer(); + Player player = getPlatformPlayer(); if ( player != null ) { player.recalculatePermissions(); } @@ -1043,13 +1044,13 @@ public void recalculatePermissions() { @Override public List getPermissions() { - Player player = getPlayer(); + Player player = getPlatformPlayer(); return (player == null ? new ArrayList<>() : player.getPermissions() ); } @Override public List getPermissions( String prefix ) { - Player player = getPlayer(); + Player player = getPlatformPlayer(); return (player == null ? new ArrayList<>() : player.getPermissions( prefix ) ); } @@ -1072,7 +1073,7 @@ public List getPermissions( String prefix ) { public double getSellAllMultiplier() { double results = 1.0; - Player player = getPlayer(); + Player player = getPlatformPlayer(); if ( player != null ) { results = player.getSellAllMultiplier(); } 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 113270066..d04fd5ead 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/TestPlayer.java +++ b/prison-core/src/test/java/tech/mcprison/prison/TestPlayer.java @@ -256,5 +256,18 @@ public void incrementMinecraftStatsDropCount( Player player, String blockName, i public List getSellAllMultiplierListings() { return new ArrayList<>(); } + + + @Override + public void sendMessage(List messages) { + // TODO Auto-generated method stub + + } + + @Override + public Player getPlatformPlayer() { + // TODO Auto-generated method stub + return null; + } } 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 ea04397af..096c311cb 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 @@ -40,7 +40,8 @@ /** * @author Faizaan A. Datoo */ -public class SpigotCommandSender implements CommandSender { +public class SpigotCommandSender + implements CommandSender { private org.bukkit.command.CommandSender bukkitSender; @@ -106,6 +107,18 @@ public void sendMessage(String[] messages) { } } } + + @Override + public void sendMessage(List messages) { + for (String message : messages) { + + String[] msgs = Text.translateAmpColorCodes(message).split( "\\{br\\}" ); + for ( String msg : msgs ) { + + sendMessage(msg); + } + } + } @Override public void sendRaw(String json) { @@ -239,4 +252,17 @@ public org.bukkit.command.CommandSender getWrapper() { return bukkitSender; } + @Override + public Player getPlatformPlayer() { + 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/SpigotOfflinePlayer.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java index c840c0649..77bbd4638 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 @@ -10,6 +10,7 @@ import org.bukkit.entity.Player; import org.bukkit.permissions.PermissionAttachmentInfo; +import tech.mcprison.prison.Prison; import tech.mcprison.prison.cache.PlayerCache; import tech.mcprison.prison.cache.PlayerCachePlayerData; import tech.mcprison.prison.file.JsonFileIO; @@ -388,4 +389,23 @@ public void incrementMinecraftStatsDropCount( tech.mcprison.prison.internal.Play } + @Override + public void sendMessage(List messages) { + // TODO Auto-generated method stub + + } + + @Override + public tech.mcprison.prison.internal.Player getPlatformPlayer() { + tech.mcprison.prison.internal.Player player = null; + + Optional oPlayer = Prison.get().getPlatform().getPlayer( getName() ); + + if ( oPlayer.isPresent() ) { + player = oPlayer.get(); + } + + return player; + } + } From 994d47430ccce47e6965c64f3bd42131c0d6db31 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 15 Mar 2024 01:33:36 -0400 Subject: [PATCH 79/92] 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. --- docs/changelog_v3.3.x.md | 5 +++++ .../java/tech/mcprison/prison/spigot/game/SpigotPlayer.java | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index db9570838..0caa9ef8a 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.16c 2024-03-15 +* **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. 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 57083996d..4d618857c 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 @@ -669,7 +669,9 @@ public void setActionBar( String actionBar ) { } public RankPlayer getRankPlayer() { - if ( rankPlayer == null ) { + if ( rankPlayer == null && + PrisonRanks.getInstance().isEnabled() ) { + rankPlayer = PrisonRanks.getInstance().getPlayerManager().getPlayer( this ); } return rankPlayer; From d5e5a78aec8e68da0858f79e70f5313ce80fc148 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 15 Mar 2024 01:36:50 -0400 Subject: [PATCH 80/92] 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. --- docs/changelog_v3.3.x.md | 7 + .../commands/PrisonSpigotSellAllCommands.java | 146 ++++++++++++++++++ 2 files changed, 153 insertions(+) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 0caa9ef8a..9afb6a071 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -16,6 +16,13 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.16c 2024-03-15 + +* **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. 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 4709217de..1ae5e8dbb 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,11 +1,14 @@ package tech.mcprison.prison.spigot.commands; +import java.lang.reflect.Method; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.TreeMap; +import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; @@ -30,6 +33,7 @@ import tech.mcprison.prison.spigot.compat.Compatibility; import tech.mcprison.prison.spigot.configs.MessagesConfig; import tech.mcprison.prison.spigot.game.SpigotPlayer; +import tech.mcprison.prison.spigot.game.SpigotPlayerUtil; import tech.mcprison.prison.spigot.sellall.SellAllBlockData; import tech.mcprison.prison.spigot.sellall.SellAllUtil; import tech.mcprison.prison.spigot.utils.tasks.PlayerAutoRankupTask; @@ -926,6 +930,148 @@ 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.", + permissions = "prison.admin", onlyPlayers = false) + private void sellAllItemInspectCommand(CommandSender sender) { + + if ( !isEnabled() ) { + return; + } + SellAllUtil sellAllUtil = SellAllUtil.get(); + + + SpigotPlayer sPlayer = (SpigotPlayer) sender.getPlatformPlayer(); + + if ( sPlayer == null ) { + String msg = String.format( + "Only online players can see 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 report. You're not holding anything other than air." + ); + sender.sendMessage(msg); + } + else { + + + ChatDisplay chatDisplay = new ChatDisplay("&bSellall Items inspect: " ); + + List msg = new ArrayList<>(); + + String name = iStack.getName(); + String nameFull = iStack.getDisplayName() == null ? "" : iStack.getDisplayName(); + + PrisonBlock pBlock = iStack.getMaterial(); + + int amount = iStack.getAmount(); + + List lore = iStack.getLore(); + Map enchants = iStack.getEnchantments(); + + String nbtInfo = iStack.getNBTItemStackInfo(); + + + chatDisplay.addText( "Item: %-14s (%s)", name, nameFull ); + chatDisplay.addText( "Qty: %5s PrisonItem: %s", + Integer.toString(amount), pBlock.getBlockNameFormal() ); + + if ( lore.size() == 0 ) { + + chatDisplay.addText( "No Lore." ); + } + else { + chatDisplay.addText( "Lore:" ); + + for (String l : lore) { + chatDisplay.addText( " %s", l ); + } + } + + if ( enchants == null || enchants.size() == 0 ) { + + chatDisplay.addText( "No Enchantments." ); + } + else { + chatDisplay.addText( "Enchantments:" ); + + Set keys = enchants.keySet(); + for (Enchantment ench : keys ) { + + Integer value = enchants.get( ench ); + + String namespace = ""; + String targetName = ""; + + try { + + // NOTE: This is for spigot 1.13.x and higher: + if ( ench.getClass().getMethod( "getKey" ) != null ) { + namespace = ench.getKey() == null ? + "---" : + ench.getKey().toString(); + } + else if ( ench.getClass().getMethod( "getName" ) != null ) { + // Versions of spigot prior to 1.13.x: + namespace = ench.getName(); + + } + + + if ( ench.getClass().getMethod( "getItemTarget" ) != null && + ench.getItemTarget() != null ) { + targetName = ench.getItemTarget().name(); + } + + } catch (Exception e) { + } + + if ( namespace == null || namespace.trim().length() == 0 ) { + namespace = ench.toString(); + } + + chatDisplay.addText( " %-10s %s %s (%s - %s)", + //ench.toString(), + namespace, + targetName, + + value.toString(), + Integer.toString( ench.getStartLevel()), + Integer.toString( ench.getMaxLevel()) + ); + } + + + } + + if ( nbtInfo == null || nbtInfo.trim().length() == 0 ) { + + chatDisplay.addText( " No NBT." ); + } + else { + + chatDisplay.addText( " %s", nbtInfo ); + } +// chatDisplay.addText( " ", ); + + chatDisplay.send( sender );; + } + + } + } + @Command(identifier = "sellall multiplier list", description = "Lists all of the SellAll Rank multipliers", permissions = "prison.admin", onlyPlayers = false) From 631d97e77f83c01b68819bffa7220be0ce5ed820 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 15 Mar 2024 04:01:10 -0400 Subject: [PATCH 81/92] 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. --- docs/changelog_v3.3.x.md | 5 ++++ .../prison/commands/BaseCommands.java | 8 +++--- .../prison/internal/CommandSender.java | 5 ++++ .../tech/mcprison/prison/internal/Player.java | 23 ++++++++------- .../prison/ranks/data/RankPlayer.java | 5 ++++ .../java/tech/mcprison/prison/TestPlayer.java | 8 ++++-- .../prison/mines/commands/MinesCommands.java | 28 +++++++++---------- .../prison/ranks/commands/RanksCommands.java | 2 +- .../prison/spigot/SpigotPlatform.java | 10 ++++--- .../spigot/game/SpigotCommandSender.java | 13 +++++++++ .../prison/spigot/game/SpigotPlayer.java | 1 + 11 files changed, 73 insertions(+), 35 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 9afb6a071..eb1f701d6 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.16c 2024-03-15 +* **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. 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 3260f727b..48de15a3e 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,10 +23,10 @@ public void setCmdGroup( String cmdGroup ) { } - public Player getPlayer( CommandSender sender ) { - Optional player = Prison.get().getPlatform().getPlayer( sender.getName() ); - return player.isPresent() ? player.get() : null; - } +// 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 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 ea26f938f..50b5a53c7 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 @@ -20,6 +20,8 @@ import java.util.List; +import tech.mcprison.prison.ranks.data.RankPlayer; + /** * Represents any entity that may send commands and receive output. * @@ -115,5 +117,8 @@ public interface CommandSender */ public Player getPlatformPlayer(); + + public RankPlayer getRankPlayer(); + } 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 c9b44fced..a0c7e61ae 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 @@ -78,12 +78,12 @@ public interface Player /** * Adds an {@link ItemStack} to the player's inventory. */ - void give(ItemStack itemStack); + public void give(ItemStack itemStack); /** * Returns the player's current {@link Location}. */ - Location getLocation(); + public Location getLocation(); /** @@ -105,31 +105,31 @@ public interface Player * * @param location The new {@link Location}. */ - void teleport(Location location); + public void teleport(Location location); /** * @return Returns true if the player is online, false otherwise. */ - boolean isOnline(); + public boolean isOnline(); /** * Sets the player's visible scoreboard. * * @param scoreboard The {@link Scoreboard} to show the player. */ - void setScoreboard(Scoreboard scoreboard); + public void setScoreboard(Scoreboard scoreboard); /** * Returns the player's current {@link Gamemode} */ - Gamemode getGamemode(); + public Gamemode getGamemode(); /** * Changes the player's {@link Gamemode} to the specified value * * @param gamemode the new gamemode */ - void setGamemode(Gamemode gamemode); + public void setGamemode(Gamemode gamemode); /** * Returns this player's locale. @@ -137,10 +137,11 @@ public interface Player * @return An {@link Optional} containing the locale of this player, or empty if it couldn't be * retrieved. */ - Optional getLocale(); + public Optional getLocale(); - @Override default boolean doesSupportColors() { + @Override + public default boolean doesSupportColors() { return true; } @@ -149,7 +150,7 @@ public interface Player * inventory. May not be necessary on all platforms but should be used where ever the player inventory * is modified */ - void updateInventory(); + public void updateInventory(); // /** @@ -176,5 +177,7 @@ public interface Player public void incrementMinecraftStatsMineBlock( Player player, String blockName, int quantity ); public void incrementMinecraftStatsDropCount( Player player, String blockName, int quantity); + +// 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 fae7183d0..21ce04ffc 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 @@ -1034,6 +1034,11 @@ public Player getPlatformPlayer() { } + @Override + public RankPlayer getRankPlayer() { + return this; + } + @Override public void recalculatePermissions() { Player player = getPlatformPlayer(); 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 d04fd5ead..6cf0b48c4 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/TestPlayer.java +++ b/prison-core/src/test/java/tech/mcprison/prison/TestPlayer.java @@ -32,6 +32,7 @@ import tech.mcprison.prison.internal.block.Block; import tech.mcprison.prison.internal.inventory.Inventory; import tech.mcprison.prison.internal.scoreboard.Scoreboard; +import tech.mcprison.prison.ranks.data.RankPlayer; import tech.mcprison.prison.util.Gamemode; import tech.mcprison.prison.util.Location; @@ -260,13 +261,16 @@ public List getSellAllMultiplierListings() { @Override public void sendMessage(List messages) { - // TODO Auto-generated method stub } @Override public Player getPlatformPlayer() { - // TODO Auto-generated method stub + return null; + } + + @Override + public RankPlayer getRankPlayer() { return null; } 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 1f9614a61..8e7ced08c 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 @@ -307,7 +307,7 @@ public void createCommand(CommandSender sender, } mineName = mineName.trim(); - Player player = getPlayer( sender ); + Player player = sender.getPlatformPlayer(); if ( !virtual && (player == null || !player.isOnline())) { sendMessage( sender, "&3You must be a player in the game to run this command. " + @@ -601,7 +601,7 @@ 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 = getPlayer( sender ); + Player player = sender.getPlatformPlayer(); if (player == null || !player.isOnline()) { sender.sendMessage( "&3You must be a player in the game to run this command." ); @@ -1037,7 +1037,7 @@ else if ( !mineAccessByRank && tpAccessByRank ) { if ( !m.isVirtual() ) { String worldName = m.getWorld().isPresent() ? m.getWorld().get().getName() : "&cmissing"; - Player player = sender == null ? null : getPlayer( sender ); + Player player = sender == null ? null : sender.getPlatformPlayer(); chatDisplay.addText("&3World: &7%-10s &3Center: &7%s &3%s &7%s", worldName, m.getBounds().getCenter().toBlockCoordinates(), @@ -1512,7 +1512,7 @@ public void listCommand(CommandSender sender, @Arg(name = "page", def = "1", description = "Page of search results (optional) [1-n, ALL]") String page ) { - Player player = getPlayer( sender ); + Player player = sender.getPlatformPlayer(); MineSortOrder sortOrder = MineSortOrder.fromString( sort ); @@ -1953,7 +1953,7 @@ public void skipResetCommand(CommandSender sender, Output.get().sendInfo( sender, message ); // Server Log message: - Player player = getPlayer( sender ); + Player player = sender.getPlatformPlayer(); Output.get().logInfo( "%s :: Changed by: %s", message, (player == null ? "console" : player.getDisplayName()) ); } @@ -2032,7 +2032,7 @@ else if ( "*default*".equalsIgnoreCase( time ) ) { mine.getTag(), resetTime ); // Server Log message: - Player player = getPlayer( sender ); + 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 ); } @@ -2078,7 +2078,7 @@ else if ( "*default*".equalsIgnoreCase( time ) ) { Output.get().sendInfo( sender, "&7mines set resettime: &b%s &7resetTime set to &b%d", m.getTag(), resetTime ); // Server Log message: - Player player = getPlayer( sender ); + 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 ); } @@ -2187,7 +2187,7 @@ private void minesSetResetDelay(CommandSender sender, double resetTime, PrisonMi } // Server Log message: - Player player = getPlayer( sender ); + Player player = sender.getPlatformPlayer(); Output.get().logInfo( "&7Mine &b%s Zero Block Reset Delay: &b%s &7set it to &b%s &7sec", (player == null ? "console" : player.getDisplayName()), m, dFmt.format( resetTime ) ); @@ -2286,7 +2286,7 @@ private void changeMinePercentThreshold(CommandSender sender, String percent, Pr Output.get().sendInfo( sender, message ); // Server Log message: - Player player = getPlayer( sender ); + Player player = sender.getPlatformPlayer(); Output.get().logInfo( "%s :: Changed by: %s", message, (player == null ? "console" : player.getDisplayName()) ); } @@ -2714,7 +2714,7 @@ public void redefineCommand(CommandSender sender, PrisonMines pMines = PrisonMines.getInstance(); Mine m = pMines.getMine(mineName); - Player player = getPlayer( sender ); + Player player = sender.getPlatformPlayer(); // if ( !m.isEnabled() ) { // sender.sendMessage( "&cMine is disabled&7. Use &a/mines info &7for possible cause." ); @@ -3413,7 +3413,7 @@ public void mineTp(CommandSender sender, } - Player player = getPlayer( sender ); + Player player = sender.getPlatformPlayer(); Player playerAlt = getOnlinePlayer( playerName ); @@ -3517,7 +3517,7 @@ else if ( playerAlt != null && !player.getName().equalsIgnoreCase( playerAlt.get public void mineTpTop(CommandSender sender ) { - Player player = getPlayer( sender ); + Player player = sender.getPlatformPlayer(); //oboolean isOp = sender.isOp(); @@ -3610,7 +3610,7 @@ public void mineStats(CommandSender sender) { description = "Identifies what mines you are in, or are the closest to." ) public void mineWhereAmI(CommandSender sender) { - Player player = getPlayer( sender ); + Player player = sender.getPlatformPlayer(); if (player == null || !player.isOnline()) { sender.sendMessage( "&3You must be a player in the game to run this command." ); @@ -3723,7 +3723,7 @@ private Player getOnlinePlayer( String playerName ) { onlyPlayers = false ) public void wandCommand(CommandSender sender) { - Player player = getPlayer( sender ); + Player player = sender.getPlatformPlayer(); if (player == null || !player.isOnline()) { sender.sendMessage( "&3You must be a player in the game to run this command." ); 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 74b08b40d..61d6affb3 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 @@ -768,7 +768,7 @@ public void listRanks(CommandSender sender, // } RankPlayer rPlayer = - PrisonRanks.getInstance().getPlayerManager().getPlayer( getPlayer(sender) ); + PrisonRanks.getInstance().getPlayerManager().getPlayer( sender.getPlatformPlayer() ); ChatDisplay display = 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 5acb0a6a1..2d0be5df4 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 @@ -204,7 +204,9 @@ public SpigotPlatform(SpigotPrison plugin) { } public Storage initStorage() { - String confStorage = plugin.getConfig().getString("storage", "file"); + + @SuppressWarnings("unused") + String confStorage = plugin.getConfig().getString("storage", "file"); Storage storage = new FileStorage(plugin.getDataDirectory()); // if (!confStorage.equalsIgnoreCase("file")) { @@ -1469,9 +1471,9 @@ public ModuleElement getPlayerDefaultMine( tech.mcprison.prison.internal.Command PrisonRanks.getInstance() != null && PrisonRanks.getInstance().isEnabled() ) { - PlayerManager pm = PrisonRanks.getInstance().getPlayerManager(); - Player player = pm.getPlayer( sender ); - RankPlayer rankPlayer = pm.getPlayer( player ); +// PlayerManager pm = PrisonRanks.getInstance().getPlayerManager(); +// Player player = sender.getPlatformPlayer(); + RankPlayer rankPlayer = sender.getRankPlayer(); RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); 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 096c311cb..9d5d4c9f4 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 @@ -33,6 +33,8 @@ import tech.mcprison.prison.integration.PermissionIntegration; import tech.mcprison.prison.internal.CommandSender; import tech.mcprison.prison.internal.Player; +import tech.mcprison.prison.ranks.PrisonRanks; +import tech.mcprison.prison.ranks.data.RankPlayer; import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.sellall.SellAllUtil; import tech.mcprison.prison.util.Text; @@ -264,5 +266,16 @@ public Player getPlatformPlayer() { return player; } + + @Override + public RankPlayer getRankPlayer() { + RankPlayer rankPlayer = null; + + if ( PrisonRanks.getInstance().isEnabled() ) { + + rankPlayer = PrisonRanks.getInstance().getPlayerManager().getPlayer( (Player) 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 4d618857c..7b2e70f85 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 @@ -668,6 +668,7 @@ public void setActionBar( String actionBar ) { } } + @Override public RankPlayer getRankPlayer() { if ( rankPlayer == null && PrisonRanks.getInstance().isEnabled() ) { From 25bf92c7b903e75c3639d61d78406495b898ea83 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 15 Mar 2024 04:13:05 -0400 Subject: [PATCH 82/92] Prison API: Added a few new functions to work with ItemStacks. --- docs/changelog_v3.3.x.md | 4 + .../prison/spigot/api/PrisonSpigotAPI.java | 156 +++++++++++++++++- 2 files changed, 159 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index eb1f701d6..1a83c27a7 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.16c 2024-03-15 +* **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. 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 3cb826a75..58d8d426a 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,14 +51,80 @@ *

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() { + +// SpigotPrison.getInstance().isSellAllEnabled(); +// +// SpigotPlayer sPlayer = new SpigotPlayer( Player player ); +// +// sPlayer.getSellAllMulitiplier() +// sPlayer.getSellAllMultiplierListings() +// sPlayer.checkAutoSellPermsAutoFeatures() +// sPlayer.checkAutoSellTogglePerms( sbDebug ) +// sPlayer.isAutoSellEnabled( sbDebug ) +// + + // PrisonSpigotAPI.sellPlayerItems(Player player ); + } + +// private void handleAffectedBlocks(Player p, IWrappedRegion region, List blocksAffected) { +// double totalDeposit = 0.0; +// int fortuneLevel = EnchantUtils.getItemFortuneLevel(p.getItemInHand()); +// boolean autoSellPlayerEnabled = this.plugin.isAutoSellModuleEnabled() && plugin.getCore().getAutoSell().getManager().hasAutoSellEnabled(p); +// +// TreeMap itemValues = new TreeMap<>(); +// PrisonSpigotAPI pApi = new PrisonSpigotAPI(); +// +// getItemStackValueTransactions(p, null); +// +// for (Block block : blocksAffected) { +// +// int amplifier = fortuneLevel; +// if (FortuneEnchant.isBlockBlacklisted(block)) { +// amplifier = 1; +// } +// +// String blockNamme = block.getType().name(); +// double value = 0dg; +// +// if ( itemValues.containsKey(blockNamme) ) { +// value = itemValues.get(blockNamme); +// } +// else { +// ItemStack iStk = new ItemStack( block.getType() ); +// if ( iStk != null ) { +// +// value = getItemStackValue(p, iStk); +// if ( value > 0 ) {{ +// itemValues.put(blockNamme, value); +// } +// } +// } +// +// if (autoSellPlayerEnabled && value > 0) { +// totalDeposit += value * amplifier; +// } else { +// ItemStack itemToGive = CompMaterial.fromBlock(block).toItem(amplifier); +// p.getInventory().addItem(itemToGive); +// } +// +// if (this.removeBlocks ) { +// this.plugin.getCore().getNmsProvider().setBlockInNativeDataPalette(block.getWorld(), block.getX(), block.getY(), block.getZ(), 0, (byte) 0, true); +// } +// +// } +// this.giveEconomyRewardsToPlayer(p, totalDeposit); +// } /** *

This returns all mines that are within prison. @@ -480,6 +546,94 @@ public SellAllUtil getPrisonSellAll(){ return sellAll; } + + + /** + *

This will convert a List to Prison's + * List so it can be used with the various SellAll + * functions. + *

+ * + * @param blocks + * @return + */ + public List getPrisonItemmStacks( List blocks ) { + List results = new ArrayList<>(); + TreeMap map = new TreeMap<>(); + + if ( blocks != null ) { + for ( Block b : blocks ) { + if ( b != null ) { + SpigotBlock sBlock = SpigotBlock.getSpigotBlock( b ); + + if ( sBlock != null ) { + + String bName = sBlock.getBlockName(); + + if ( !map.containsKey( bName ) ) { + String[] lore = null; + SpigotItemStack sis = new SpigotItemStack( 1, sBlock, lore ); + + map.put(bName, sis ); + } + else { + map.get(bName).addToAmount( 1 ); + } + } + + } + } + + } + + if ( map.size() > 0 ) { + for ( SpigotItemStack sItemStack : map.values() ) { + results.add( sItemStack ); + } + } + + return results; + } + + public List getItemStacks( List blocks ) { + List results = new ArrayList<>(); + TreeMap map = new TreeMap<>(); + + if ( blocks != null ) { + for ( Block b : blocks ) { + if ( b != null ) { + + String bName = b.getType().name(); + + if ( bName != null ) { + + if ( !map.containsKey( bName ) ) { + + ItemStack iStk = new ItemStack( b.getType() ); + map.put(bName, iStk ); + } + else { + ItemStack iStk = map.get(bName); + + iStk.setAmount( iStk.getAmount() ); + + map.put(bName, iStk); + } + } + + } + } + + } + + if ( map.size() > 0 ) { + for ( ItemStack sItemStack : map.values() ) { + results.add( sItemStack ); + } + } + + return results; + } /** *

Get the money to give to the Player depending on the SellAll multiplier. From 7aee372370f5e59136ec9deb3739373f4dade2be Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 16 Mar 2024 23:49:51 -0400 Subject: [PATCH 83/92] 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. --- docs/changelog_v3.3.x.md | 5 ++++ .../spigot/economies/EssEconomyWrapper.java | 17 +++++++++++-- .../spigot/economies/SaneEconomyWrapper.java | 21 ++++++++++++++-- .../spigot/economies/VaultEconomyWrapper.java | 24 +++++++++++++++++++ 4 files changed, 63 insertions(+), 4 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 1a83c27a7..968534699 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.16c 2024-03-15 + +* **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.** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/EssEconomyWrapper.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/EssEconomyWrapper.java index b1cf349d8..f3392f4f4 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/EssEconomyWrapper.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/EssEconomyWrapper.java @@ -39,7 +39,13 @@ class EssEconomyWrapper { double getBalance(Player player) { try { - return Economy.getMoneyExact(player.getName()).doubleValue(); + if ( Economy.playerExists( player.getName() ) ) { + return Economy.getMoneyExact(player.getName()).doubleValue(); + } + + player.sendMessage( "You don't exist in the economy plugin." ); + return 0; + } catch (UserDoesNotExistException e) { player.sendMessage("You don't exist in the economy plugin."); return 0.0; @@ -48,7 +54,14 @@ class EssEconomyWrapper { void setBalance(Player player, double amount) { try { - Economy.setMoney(player.getName(), new BigDecimal(amount)); + if ( Economy.playerExists( player.getName() ) ) { + Economy.setMoney(player.getName(), new BigDecimal(amount)); + } + else { + + player.sendMessage( "You don't exist in the economy plugin." ); + } + } catch (UserDoesNotExistException | NoLoanPermittedException e) { player.sendMessage("You don't exist in the economy plugin."); } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/SaneEconomyWrapper.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/SaneEconomyWrapper.java index cee34711a..c4dd89504 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/SaneEconomyWrapper.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/SaneEconomyWrapper.java @@ -27,7 +27,15 @@ public double getBalance(Player player) { double result = 0; try { - result = economyManager.getBalance(toEconomablePlayer(player)); + EconomablePlayer p = toEconomablePlayer(player); + + if ( !economyManager.accountExists( p ) ) { + player.sendMessage( "Economy Error: You don't have an account."); + } + else { + + result = economyManager.getBalance( p ); + } } catch ( Exception e ) { Output.get().logError( "Failed to get SaneEconomy balance. " + @@ -39,7 +47,16 @@ public double getBalance(Player player) { public void setBalance(Player player, double amount) { try { - economyManager.setBalance(toEconomablePlayer(player), amount); + EconomablePlayer p = toEconomablePlayer(player); + + if ( !economyManager.accountExists( p ) ) { + player.sendMessage( "Economy Error: You don't have an account."); + } + else { + + economyManager.setBalance(toEconomablePlayer(player), amount); + } + } catch ( Exception e ) { Output.get().logError( "Failed to set SaneEconomy balance. " + 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 b34c0f9a8..aa3960a8c 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 @@ -110,7 +110,13 @@ private OfflinePlayer getOfflinePlayer(Player player) { @SuppressWarnings( "deprecation" ) public double getBalance(Player player) { double results = 0; + + if ( economy != null && !economy.hasAccount( getOfflinePlayer( player ) ) ) { + player.sendMessage( "Economy Error: You don't have an account."); + } + else if (economy != null) { + if ( isPreV1_4() ) { results = economy.getBalance(player.getName()); } @@ -152,6 +158,11 @@ public double getBalance(Player player) { @SuppressWarnings( "deprecation" ) public boolean setBalance(Player player, double amount) { boolean results = false; + + if ( economy != null && !economy.hasAccount( getOfflinePlayer( player ) ) ) { + player.sendMessage( "Economy Error: You don't have an account."); + } + else if (economy != null) { if ( isPreV1_4() ) { @@ -191,6 +202,10 @@ public boolean addBalance(Player player, double amount) { if ( amount < 0 ) { results = removeBalance( player, amount ); } + + else if ( economy != null && !economy.hasAccount( getOfflinePlayer( player ) ) ) { + player.sendMessage( "Economy Error: You don't have an account."); + } else if (economy != null) { if ( isPreV1_4() ) { economy.depositPlayer( player.getName(), amount ); @@ -239,6 +254,10 @@ public boolean removeBalance(Player player, double amount) { amount *= -1; } + if ( economy != null && !economy.hasAccount( getOfflinePlayer( player ) ) ) { + player.sendMessage( "Economy Error: You don't have an account."); + } + else if (economy != null) { if ( isPreV1_4() ) { economy.withdrawPlayer( player.getName(), amount ); @@ -284,6 +303,11 @@ public boolean removeBalance(Player player, double amount) { @SuppressWarnings( "deprecation" ) public boolean canAfford(Player player, double amount) { boolean results = false; + + if ( economy != null && !economy.hasAccount( getOfflinePlayer( player ) ) ) { + player.sendMessage( "Economy Error: You don't have an account."); + } + else if (economy != null) { if ( isPreV1_4() ) { results = economy.has(player.getName(), amount); From be2512c7786c4019ecde9bf480073549e8e6f356 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 28 Mar 2024 02:01:33 -0400 Subject: [PATCH 84/92] 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. --- docs/changelog_v3.3.x.md | 6 +++++- .../mcprison/prison/localization/Localizable.java | 12 +++++++++++- .../java/tech/mcprison/prison/output/Output.java | 11 +++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 968534699..f5fda75e1 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.16c 2024-03-15 +# 3.3.0-alpha.16c 2024-03-29 + + + +* **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.** 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 dbc54a53a..0b4dbd519 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 @@ -370,7 +370,17 @@ public void sendTo(CommandSender sender, LogLevel level) { String message = localizeFor(sender); if ( message != null && !message.isEmpty() ) { - Output.get().sendMessage(sender, message, level); + 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 + + "]"); + } } } 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 ed904cf6d..f89c3a5c6 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 @@ -383,6 +383,17 @@ public void logError(String message, Throwable... throwable) { } } + /** + *

This will log a message to the console without any conversion of color codes or + * anything else. Expect issues with color formatting. + *

+ * + * @param message + */ + public void logRaw( String message ) { + Prison.get().getPlatform().logPlain(message); + } + public void logDebug(String message, Object... args) { logDebug( message, null, args ); } From 23deddeee76da85c3e0e1eeea3d547d33ea1b5d7 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 28 Mar 2024 02:06:20 -0400 Subject: [PATCH 85/92] 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. --- .../java/tech/mcprison/prison/PrisonCommand.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) 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 5f848ac7c..863195490 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java +++ b/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java @@ -1535,7 +1535,21 @@ public void supportSubmitVersion(CommandSender sender PrisonPasteChat pasteChat = new PrisonPasteChat( getSupportName(), getSupportURLs() ); - String helpURL = pasteChat.post( text.toString() ); + 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 ); From 391b37c8dc76e3b77d40f0b3e9eb77938e798483 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 7 Apr 2024 20:47:11 -0400 Subject: [PATCH 86/92] 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. --- .../prison/localization/Localizable.java | 129 +++++++++++++++++- .../resources/lang/ranks/en_US.properties | 11 ++ .../resources/lang/ranks/fr_FR.properties | 13 ++ .../resources/lang/ranks/pt_PT.properties | 13 ++ .../resources/lang/ranks/zh-CN.properties | 13 ++ .../resources/lang/ranks/zh_TW.properties | 13 ++ 6 files changed, 187 insertions(+), 5 deletions(-) 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 0b4dbd519..b36331d8e 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 @@ -42,6 +42,9 @@ import tech.mcprison.prison.internal.World; import tech.mcprison.prison.output.LogLevel; import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.ranks.data.PlayerRank; +import tech.mcprison.prison.ranks.data.Rank; +import tech.mcprison.prison.ranks.data.RankPlayer; /** * Represents an object which has the potential to be localized in one of @@ -347,9 +350,14 @@ public String localize() { * @since 1.0 */ public String localizeFor(CommandSender sender) { - return sender instanceof Player ? - localizeIn(getParent().getLocale((Player) sender)) : - localize(); + String results = + sender instanceof Player ? + localizeIn(getParent().getLocale((Player) sender)) : + localize(); + + results = applySecondaryPlaceholders( sender, results ); + + return results; } /** @@ -396,11 +404,19 @@ public void sendTo(CommandSender sender, LogLevel level) { * * @param sender The {@link CommandSender} to send this {@link Localizable} to */ - public void sendTo(CommandSender sender) { + public void sendTo(CommandSender sender ) { + CommandSender playerStats = null; + sendTo( sender, playerStats ); + } + public void sendTo(CommandSender sender, CommandSender playerStats ) { String message = localize(); if ( message != null && !message.isEmpty() ) { + message = applySecondaryPlaceholders( + (playerStats != null ? playerStats : sender ), + message ); + sendTo(sender, LogLevel.PLAIN); } } @@ -412,12 +428,16 @@ public void sendTo(CommandSender sender) { * @since 1.0 */ public void broadcast() { + CommandSender playerStats = null; + broadcast( playerStats ); + } + public void broadcast( CommandSender playerStats ) { String message = localize(); if ( message != null && !message.isEmpty() ) { for (Player player : Prison.get().getPlatform().getOnlinePlayers()) { - sendTo(player); + sendTo(player, playerStats); } Output.get().logInfo( message ); } @@ -459,4 +479,103 @@ private String fromNullableString(String nullable) { // PLAIN, INFO, WARN, ERROR // } + + /** + *

This function will provide support for secondary placeholders for all player related placeholders. + * These secondary placeholders are in addition to the preexisting positional placeholders + * that are hard coded for the specific parameters. + *

+ * + *

These secondary placeholders can be inserted anywhere in the message. + *

+ * + *
    + *
  • {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} {rank_default} {rank_tag_default} {rank_next_default} {rank_next_tag_default}
  • + *
  • {rank_prestiges} {rank_tag_prestiges} {rank_next_prestiges} {rank_next_tag_prestiges}
  • + *
+ * + * @param rankPlayer + * @param results + * @return + */ + public String applySecondaryPlaceholders( CommandSender sender, String results ) { + + if ( results != null && !results.isEmpty() && + sender != null && sender instanceof Player ) { + RankPlayer rankPlayer = sender.getRankPlayer(); + + if ( rankPlayer != null ) { + + + results = applySecondaryPlaceholdersCheck( "{player}", rankPlayer.getName(), results ); + + if ( rankPlayer.getPlayerRankDefault() != null ) { + PlayerRank rankP = rankPlayer.getPlayerRankDefault(); + Rank rank = rankP == null ? null : rankP.getRank(); + Rank rankNext = rank == null ? null : rank.getRankNext(); + + results = applySecondaryPlaceholdersCheck( "{rank_default}", + rank == null ? "" : rank.getName(), results ); + results = applySecondaryPlaceholdersCheck( "{rank_tag_default}", + rank == null ? "" : rank.getTag(), results ); + + results = applySecondaryPlaceholdersCheck( "{rank_next_default}", + rankNext == null ? "" : rankNext.getName(), results ); + results = applySecondaryPlaceholdersCheck( "{rank_next_tag_default}", + rankNext == null ? "" : rankNext.getTag(), results ); + } + + if ( rankPlayer.getPlayerRankPrestiges() != null ) { + + PlayerRank rankP = rankPlayer.getPlayerRankPrestiges(); + Rank rank = rankP == null ? null : rankP.getRank(); + Rank rankNext = rank == null ? null : rank.getRankNext(); + + results = applySecondaryPlaceholdersCheck( "{rank_prestiges}", + rank == null ? "" : rank.getName(), results ); + results = applySecondaryPlaceholdersCheck( "{rank_tag_prestiges}", + rank == null ? "" : rank.getTag(), results ); + + results = applySecondaryPlaceholdersCheck( "{rank_next_prestiges}", + rankNext == null ? "" : rankNext.getName(), results ); + results = applySecondaryPlaceholdersCheck( "{rank_next_tag_prestiges}", + rankNext == null ? "" : rankNext.getTag(), results ); + } + + } + } + + + return results; + } + + /** + *

Ths function will perform individual replacements of the given placeholders, but + * if the placeholder does not exist, then it will not change anything with the results + * and it will be just passed through. + *

+ * + * @param placeholder + * @param value + * @param results + * @return + */ + private String applySecondaryPlaceholdersCheck( String placeholder, String value, String results) { + + if ( results.contains( placeholder ) && value != null ) { + results = results.replace( placeholder, value ); + } + + return results; + } } 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 8d0fc484d..9807416d3 100644 --- a/prison-core/src/main/resources/lang/ranks/en_US.properties +++ b/prison-core/src/main/resources/lang/ranks/en_US.properties @@ -61,6 +61,17 @@ # 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 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 6f5e7f54e..d5284ec1b 100644 --- a/prison-core/src/main/resources/lang/ranks/fr_FR.properties +++ b/prison-core/src/main/resources/lang/ranks/fr_FR.properties @@ -58,6 +58,19 @@ # 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=28 messages__auto_refresh=true diff --git a/prison-core/src/main/resources/lang/ranks/pt_PT.properties b/prison-core/src/main/resources/lang/ranks/pt_PT.properties index c6f5ada05..13c0a863c 100644 --- a/prison-core/src/main/resources/lang/ranks/pt_PT.properties +++ b/prison-core/src/main/resources/lang/ranks/pt_PT.properties @@ -58,6 +58,19 @@ # 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=6 messages__auto_refresh=true diff --git a/prison-core/src/main/resources/lang/ranks/zh-CN.properties b/prison-core/src/main/resources/lang/ranks/zh-CN.properties index 9111dfdcb..9a53f49c5 100644 --- a/prison-core/src/main/resources/lang/ranks/zh-CN.properties +++ b/prison-core/src/main/resources/lang/ranks/zh-CN.properties @@ -58,6 +58,19 @@ # 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=25 messages__auto_refresh=true diff --git a/prison-core/src/main/resources/lang/ranks/zh_TW.properties b/prison-core/src/main/resources/lang/ranks/zh_TW.properties index 88443d906..45cce31bc 100644 --- a/prison-core/src/main/resources/lang/ranks/zh_TW.properties +++ b/prison-core/src/main/resources/lang/ranks/zh_TW.properties @@ -58,6 +58,19 @@ # 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=9 messages__auto_refresh=true From 66a3068e0f472f6b21fb4d8037cf192d468d784a Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 7 Apr 2024 23:45:53 -0400 Subject: [PATCH 87/92] 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). --- docs/changelog_v3.3.x.md | 12 +- .../prison/localization/Localizable.java | 24 +- .../PlaceholderStringCoverter.java | 14 ++ .../prison/ranks/data/RankPlayer.java | 109 +++++++- .../prison/ranks/commands/RankUpCommand.java | 154 ++++++++---- .../ranks/commands/RankUpCommandMessages.java | 232 +++++++++++------- .../prison/ranks/commands/RanksCommands.java | 6 +- 7 files changed, 396 insertions(+), 155 deletions(-) create mode 100644 prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderStringCoverter.java diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index f5fda75e1..c0b76589d 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.16c 2024-03-29 +# 3.3.0-alpha.16c 2024-04-07 + + +* **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. 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 b36331d8e..9b32423e0 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 @@ -42,6 +42,7 @@ import tech.mcprison.prison.internal.World; import tech.mcprison.prison.output.LogLevel; import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.placeholders.PlaceholderStringCoverter; import tech.mcprison.prison.ranks.data.PlayerRank; import tech.mcprison.prison.ranks.data.Rank; import tech.mcprison.prison.ranks.data.RankPlayer; @@ -405,17 +406,20 @@ public void sendTo(CommandSender sender, LogLevel level) { * @param sender The {@link CommandSender} to send this {@link Localizable} to */ public void sendTo(CommandSender sender ) { - CommandSender playerStats = null; - sendTo( sender, playerStats ); + PlaceholderStringCoverter placeholderConverter = null; + sendTo( sender, placeholderConverter ); } - public void sendTo(CommandSender sender, CommandSender playerStats ) { + public void sendTo(CommandSender sender, PlaceholderStringCoverter placeholderConverter ) { String message = localize(); if ( message != null && !message.isEmpty() ) { - message = applySecondaryPlaceholders( - (playerStats != null ? playerStats : sender ), - message ); + if ( placeholderConverter != null ) { + message = placeholderConverter.convertStringPlaceholders(message); + } +// message = applySecondaryPlaceholders( +// (playerStats != null ? playerStats : sender ), +// message ); sendTo(sender, LogLevel.PLAIN); } @@ -428,16 +432,16 @@ public void sendTo(CommandSender sender, CommandSender playerStats ) { * @since 1.0 */ public void broadcast() { - CommandSender playerStats = null; - broadcast( playerStats ); + PlaceholderStringCoverter placeholderConverter = null; + broadcast( placeholderConverter ); } - public void broadcast( CommandSender playerStats ) { + public void broadcast( PlaceholderStringCoverter placeholderConverter ) { String message = localize(); if ( message != null && !message.isEmpty() ) { for (Player player : Prison.get().getPlatform().getOnlinePlayers()) { - sendTo(player, playerStats); + sendTo(player, placeholderConverter); } Output.get().logInfo( message ); } diff --git a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderStringCoverter.java b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderStringCoverter.java new file mode 100644 index 000000000..e445873c7 --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderStringCoverter.java @@ -0,0 +1,14 @@ +package tech.mcprison.prison.placeholders; + +public interface PlaceholderStringCoverter { + + /** + *

This returns a String list of all available placeholders that can be used. + *

+ * @return + */ + public String getStringPlaceholders(); + + public String convertStringPlaceholders( String source ); + +} 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 21ce04ffc..189df8e1c 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 @@ -39,6 +39,7 @@ import tech.mcprison.prison.internal.inventory.Inventory; import tech.mcprison.prison.internal.scoreboard.Scoreboard; import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.placeholders.PlaceholderStringCoverter; import tech.mcprison.prison.placeholders.PlaceholdersUtil; import tech.mcprison.prison.util.Gamemode; import tech.mcprison.prison.util.Location; @@ -51,7 +52,7 @@ */ public class RankPlayer extends RankPlayerMessages - implements Player { + implements Player, PlaceholderStringCoverter { public static final long DELAY_THREE_SECONDS = 20 * 3; // 3 seconds in ticks @@ -1907,6 +1908,112 @@ public List getSellAllMultiplierListings() { return player == null ? new ArrayList<>() : player.getSellAllMultiplierListings(); } + + @Override + public String getStringPlaceholders() { + String results = + "{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}"; + + return results; + } + + /** + *

This function will provide support for secondary placeholders for all player related placeholders. + * These secondary placeholders are in addition to the preexisting positional placeholders + * that are hard coded for the specific parameters. + *

+ * + *

These secondary placeholders can be inserted anywhere in the message. + *

+ * + *
    + *
  • {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} {rank_default} {rank_tag_default} {rank_next_default} {rank_next_tag_default}
  • + *
  • {rank_prestiges} {rank_tag_prestiges} {rank_next_prestiges} {rank_next_tag_prestiges}
  • + *
+ * + * @param rankPlayer + * @param results + * @return + */ + @Override + public String convertStringPlaceholders(String results) { + + RankPlayer rankPlayer = this; + + if ( rankPlayer != null ) { + + results = applySecondaryPlaceholdersCheck( "{player}", rankPlayer.getName(), results ); + + if ( rankPlayer.getPlayerRankDefault() != null ) { + PlayerRank rankP = rankPlayer.getPlayerRankDefault(); + Rank rank = rankP == null ? null : rankP.getRank(); + Rank rankNext = rank == null ? null : rank.getRankNext(); + + results = applySecondaryPlaceholdersCheck( "{rank_default}", + rank == null ? "" : rank.getName(), results ); + results = applySecondaryPlaceholdersCheck( "{rank_tag_default}", + rank == null ? "" : rank.getTag(), results ); + + results = applySecondaryPlaceholdersCheck( "{rank_next_default}", + rankNext == null ? "" : rankNext.getName(), results ); + results = applySecondaryPlaceholdersCheck( "{rank_next_tag_default}", + rankNext == null ? "" : rankNext.getTag(), results ); + } + + if ( rankPlayer.getPlayerRankPrestiges() != null ) { + + PlayerRank rankP = rankPlayer.getPlayerRankPrestiges(); + Rank rank = rankP == null ? null : rankP.getRank(); + Rank rankNext = rank == null ? null : rank.getRankNext(); + + results = applySecondaryPlaceholdersCheck( "{rank_prestiges}", + rank == null ? "" : rank.getName(), results ); + results = applySecondaryPlaceholdersCheck( "{rank_tag_prestiges}", + rank == null ? "" : rank.getTag(), results ); + + results = applySecondaryPlaceholdersCheck( "{rank_next_prestiges}", + rankNext == null ? "" : rankNext.getName(), results ); + results = applySecondaryPlaceholdersCheck( "{rank_next_tag_prestiges}", + rankNext == null ? "" : rankNext.getTag(), results ); + } + + } + + return results; + } + + + /** + *

Ths function will perform individual replacements of the given placeholders, but + * if the placeholder does not exist, then it will not change anything with the results + * and it will be just passed through. + *

+ * + * @param placeholder + * @param value + * @param results + * @return + */ + private String applySecondaryPlaceholdersCheck( String placeholder, String value, String results) { + + if ( results.contains( placeholder ) && value != null ) { + results = results.replace( placeholder, value ); + } + + return results; + } + // public long getRankScoreCooldown() { // return rankScoreCooldown; // } 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 866c09938..2a53095dd 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,17 +119,17 @@ public void rankUpMax(CommandSender sender, } + Player player = getPlayer( sender, null ); // submit cmdTasks if ( cmdTasks.size() > 0 ) { - Player player = getPlayer( sender, null ); submitCmdTasks( player, cmdTasks ); } if ( sbRanks.length() > 0 ) { - ranksRankupMaxSuccessMsg( sender, sbRanks ); + ranksRankupMaxSuccessMsg( sender, sbRanks, player.getRankPlayer() ); } // If the ran rankupmax for prestiges, and the last prestige was successful, then @@ -139,10 +139,11 @@ public void rankUpMax(CommandSender sender, } } else { + 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 ); + rankupMaxNoPermissionMsg( sender, "ranks.rankupmax." + ladder, player.getRankPlayer() ); } } @@ -162,17 +163,65 @@ public void rankUp(CommandSender sender, @Arg(name = "ladder", description = "The ladder to rank up on. Defaults to 'default'.", def = "default") String ladder, @Arg(name = "playerName", description = "Provides the player's name for the rankup, but" + "this can only be provided by a non-player such as console or ran from a script.", def = "") String playerName +// , +// @Arg(name = "confirm", def = "", +// description = "If confirmations are enabled, then the rankup command " + +// "must be repeated with the addition of 'confirm'. If the rankup command is ran by a " +// + "non-player, such as console or from script, then the confirmation will be skipped, or " +// + "the word 'confirm' can be appended to the initial command. If 'confirm' is supplied, even " +// + "if the setting 'prison-ranks.confirmation-enabled: true' is enabled, then confirmations will " +// + "be skipped (acts like a bypass)." ) +// String confirm ) { - if ( sender.isPlayer() ) { + boolean isPlayer = sender.isPlayer(); + + if ( isPlayer ) { playerName = ""; } - if ( !sender.isPlayer() && playerName.length() == 0 ) { + if ( !isPlayer && playerName.length() == 0 ) { Output.get().logInfo( rankupCannotRunFromConsoleMsg() ); 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; +// } + String perms = "ranks.rankup."; String permsLadder = perms + ladder; @@ -211,10 +260,11 @@ public void rankUp(CommandSender sender, submitCmdTasks( player, cmdTasks ); } else { + Player player = getPlayer( sender, playerName ); Output.get().logDebug( DebugTarget.rankup, "Rankup: Failed: cmd '/rankup %s' Does not have the permission %s", ladder, permsLadder ); - rankupMaxNoPermissionMsg( sender, permsLadder ); + rankupMaxNoPermissionMsg( sender, permsLadder, player.getRankPlayer() ); } } @@ -296,16 +346,16 @@ public void prestigeCmd(CommandSender sender, if ( nRank == null ) { // You're at the last possible rank. - rankupNotAbleToPrestigeMsg( sender ); - rankupAtLastRankMsg( sender ); + rankupNotAbleToPrestigeMsg( sender, rPlayer ); + rankupAtLastRankMsg( sender, rPlayer ); return; } if ( !nRank.getLadder().getName().equals( LadderManager.LADDER_PRESTIGES ) ) { // your next rank is not a Prestiges rank - rankupNotAbleToPrestigeMsg( sender ); - rankupNotAtLastRankMsg( sender ); + rankupNotAbleToPrestigeMsg( sender, rPlayer ); + rankupNotAtLastRankMsg( sender, rPlayer ); return; } @@ -315,8 +365,8 @@ public void prestigeCmd(CommandSender sender, if ( rPlayer.getBalance( currency ) < nextRank.getRankCost() ) { // You do not have enough to prestige yet - ranksRankupCannotAffordMsg( sender, nextRank ); - ranksRankupPlayerBalanceMsg( sender, rPlayer.getBalance( currency ), currency ); + ranksRankupCannotAffordMsg( sender, nextRank, rPlayer ); + ranksRankupPlayerBalanceMsg( sender, rPlayer.getBalance( currency ), currency, rPlayer); return; } @@ -432,8 +482,9 @@ private boolean rankUpPrivate(CommandSender sender, String playerName, String la //UUID playerUuid = player.getUUID(); + RankPlayer rankPlayer = getRankPlayer( sender, player.getUUID(), player.getName() ); - ladder = confirmLadder( sender, ladder ); + ladder = confirmLadder( sender, ladder, rankPlayer ); if ( ladder == null ) { // ladder cannot be null, return false; @@ -454,7 +505,6 @@ private boolean rankUpPrivate(CommandSender sender, String playerName, String la - RankPlayer rankPlayer = getRankPlayer( sender, player.getUUID(), player.getName() ); PlayerRank rankCurrent = rankPlayer.getPlayerRank(ladder); @@ -462,7 +512,7 @@ private boolean rankUpPrivate(CommandSender sender, String playerName, String la // 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); + rankupAtLastRankMsg(sender, rankPlayer ); return false; } @@ -558,7 +608,7 @@ private boolean rankUpPrivate(CommandSender sender, String playerName, String la // On the default ladder, the player must be at the last rank: // The last rank will never have a rankNext (it will be null): if ( playersRankOnDefaultLadder.getRankNext() != null ) { - rankupNotAtLastRankMsg( sender ); + rankupNotAtLastRankMsg( sender, rankPlayer ); return false; } @@ -618,7 +668,7 @@ private boolean rankUpPrivate(CommandSender sender, String playerName, String la } else if ( canPrestige ) { - rankupNotAbleToPrestigeMsg( sender ); + rankupNotAbleToPrestigeMsg( sender, rankPlayer ); } } @@ -695,13 +745,13 @@ private void prestigePlayer(CommandSender sender, RankPlayer rankPlayer, if ( !pRankSecond.equals( lm.getLadder(LadderManager.LADDER_DEFAULT).getLowestRank().get()) ) { - rankupNotAbleToResetRankMsg( sender ); + rankupNotAbleToResetRankMsg( sender, rankPlayer ); success = false; } } else { - rankupNotAbleToResetRankMsg( sender ); + rankupNotAbleToResetRankMsg( sender, rankPlayer ); success = false; } // } @@ -711,7 +761,7 @@ private void prestigePlayer(CommandSender sender, RankPlayer rankPlayer, // set the player's balance to zero: rankPlayer.setBalance( 0 ); - prestigePlayerBalanceSetToZeroMsg( sender ); + prestigePlayerBalanceSetToZeroMsg( sender, rankPlayer ); } @@ -727,11 +777,11 @@ private void prestigePlayer(CommandSender sender, RankPlayer rankPlayer, if ( success ) { // Send a message to the player because he did prestige! - prestigePlayerSucessfulMsg( sender, title ); + prestigePlayerSucessfulMsg( sender, title, rankPlayer ); } else { - prestigePlayerFailureMsg( sender, title ); + prestigePlayerFailureMsg( sender, title, rankPlayer ); } } @@ -752,29 +802,30 @@ public void promotePlayer(CommandSender sender, ) { Player player = getPlayer( sender, playerName ); + UUID playerUuid = player.getUUID(); if (player == null) { ranksPromotePlayerMustBeOnlineMsg( sender ); return; } + 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 ); + ranksPromotePlayerInvalidChargeValueMsg( sender, rankPlayer ); return; } - UUID playerUuid = player.getUUID(); - ladder = confirmLadder( sender, ladder ); + ladder = confirmLadder( sender, ladder, rankPlayer ); if ( ladder == null ) { return; } - RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); - RankPlayer rankPlayer = getRankPlayer( sender, playerUuid, player.getName() ); PlayerRank playerRank = rankPlayerFactory.getRank( rankPlayer, ladder ); if ( rankPlayer != null && playerRank != null ) { @@ -832,15 +883,16 @@ public void demotePlayer(CommandSender 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 ); + ranksDemotePlayerInvalidRefundValueMsg( sender, rankPlayer ); return; } - UUID playerUuid = player.getUUID(); - - ladder = confirmLadder( sender, ladder ); + ladder = confirmLadder( sender, ladder, rankPlayer ); if ( ladder == null ) { // Already displayed error message about ladder not existing: return; @@ -848,7 +900,6 @@ public void demotePlayer(CommandSender sender, RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); - RankPlayer rankPlayer = getRankPlayer( sender, playerUuid, player.getName() ); PlayerRank playerRank = rankPlayerFactory.getRank( rankPlayer, ladder ); if ( rankPlayer != null && playerRank != null ) { @@ -1022,9 +1073,9 @@ private void setPlayerRank( Player player, String rank, String ladderName, Comma Output.get().logDebug( DebugTarget.rankup, "Rankup: setPlayerRank: "); - ladderName = confirmLadder( sender, ladderName ); + RankPlayer rankPlayer = getRankPlayer( sender, playerUuid, player.getName() ); - RankPlayer rankPlayer = getRankPlayer( sender, playerUuid, player.getName() ); + ladderName = confirmLadder( sender, ladderName, rankPlayer ); if ( ladderName != null && rankPlayer != null ) { @@ -1049,13 +1100,14 @@ private void setPlayerRank( Player player, String rank, String ladderName, Comma - public String confirmLadder( CommandSender sender, String ladderName ) { + private String confirmLadder( CommandSender sender, String ladderName, RankPlayer rPlayer ) { String results = null; RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder(ladderName); // The ladder doesn't exist if ( ladder == null ) { - ranksConfirmLadderMsg( sender, ladderName ); + + ranksConfirmLadderMsg( sender, ladderName, rPlayer ); } else { results = ladder.getName(); @@ -1107,62 +1159,64 @@ public void processResults( CommandSender sender, String playerName, break; case RANKUP_FAILURE: - ranksRankupFailureMsg( sender ); + ranksRankupFailureMsg( sender, results.getRankPlayer() ); break; case RANKUP_FAILURE_COULD_NOT_LOAD_PLAYER: - ranksRankupFailureCouldNotLoadPlayerMsg( sender ); + ranksRankupFailureCouldNotLoadPlayerMsg( sender, results.getRankPlayer() ); break; case RANKUP_FAILURE_COULD_NOT_LOAD_LADDER: - ranksRankupFailureCouldNotLoadLadderMsg( sender ); + ranksRankupFailureCouldNotLoadLadderMsg( sender, results.getRankPlayer() ); break; case RANKUP_FAILURE_UNABLE_TO_ASSIGN_RANK: - ranksRankupFailureUnableToAssignRankMsg( sender ); + ranksRankupFailureUnableToAssignRankMsg( sender, results.getRankPlayer() ); break; case RANKUP_FAILURE_COULD_NOT_SAVE_PLAYER_FILE: - ranksRankupFailureCouldNotSavePlayerFileMsg( sender ); + ranksRankupFailureCouldNotSavePlayerFileMsg( sender, results.getRankPlayer() ); break; case RANKUP_NO_RANKS: - ranksRankupFailureNoRanksMsg( sender ); + ranksRankupFailureNoRanksMsg( sender, results.getRankPlayer() ); break; case RANKUP_FAILURE_RANK_DOES_NOT_EXIST: - ranksRankupFailureRankDoesNotExistMsg( sender, rank ); + ranksRankupFailureRankDoesNotExistMsg( sender, rank, results.getRankPlayer() ); break; case RANKUP_FAILURE_RANK_IS_NOT_IN_LADDER: - ranksRankupFailureRankIsNotInLadderMsg( sender, rank, ladder ); + ranksRankupFailureRankIsNotInLadderMsg( sender, rank, ladder, results.getRankPlayer() ); break; case RANKUP_FAILURE_CURRENCY_IS_NOT_SUPPORTED: - ranksRankupFailureCurrencyIsNotSupportedMsg( sender, results.getTargetRank().getCurrency() ); + ranksRankupFailureCurrencyIsNotSupportedMsg( sender, results.getTargetRank().getCurrency(), + results.getRankPlayer() ); break; case RANKUP_FAILURE_ECONOMY_FAILED: // TODO externalize message - sender.sendMessage( "Failed to adjust player's balance. Could be an issue with vault or " + - "a cache timing issue. Try again." ); + 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; case RANKUP_LADDER_REMOVED: - ranksRankupFailureLadderRemovedMsg( sender, ladder ); + ranksRankupFailureLadderRemovedMsg( sender, ladder, results.getRankPlayer() ); break; case RANKUP_FAILURE_REMOVING_LADDER: - ranksRankupFailureRemovingLadderMsg( sender, ladder ); + ranksRankupFailureRemovingLadderMsg( sender, ladder, results.getRankPlayer() ); break; case IN_PROGRESS: - ranksRankupFailureInProgressMsg( sender ); + ranksRankupFailureInProgressMsg( sender, results.getRankPlayer() ); break; default: 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 c0782abae..6c1a1c9aa 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 @@ -25,11 +25,12 @@ public RankUpCommandMessages( String cmdGroup ) } - protected void rankupMaxNoPermissionMsg( CommandSender sender, String permission ) { + protected void rankupMaxNoPermissionMsg( CommandSender sender, String permission, + RankPlayer rPlayer ) { PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_rankup__no_permission" ) .withReplacements( permission.toLowerCase() ) - .sendTo( sender ); + .sendTo( sender, rPlayer ); } protected String rankupCannotRunFromConsoleMsg() { @@ -85,50 +86,65 @@ protected void rankupErrorPlayerNotOnDefaultLadder( CommandSender sender, .sendTo( sender ); } - protected void rankupNotAtLastRankMsg( CommandSender sender ) { + protected void rankupNotAtLastRankMsg( CommandSender sender, + RankPlayer rPlayer ) { PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_rankup__not_at_last_rank" ) - .sendTo( sender ); + .sendTo( sender, rPlayer ); } - protected void rankupAtLastRankMsg( CommandSender sender ) { + protected void rankupAtLastRankMsg( CommandSender sender, + RankPlayer rPlayer ) { PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_rankup__at_last_rank" ) - .sendTo( sender ); + .sendTo( sender, rPlayer ); } - protected void rankupNotAbleToPrestigeMsg( CommandSender sender ) { + protected void rankupNotAbleToPrestigeMsg( CommandSender sender, + RankPlayer rPlayer ) { PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_rankup__not_able_to_prestige" ) - .sendTo( sender ); + .sendTo( sender, rPlayer ); } - protected void rankupNotAbleToResetRankMsg( CommandSender sender ) { + protected void rankupNotAbleToResetRankMsg( CommandSender sender, + RankPlayer rPlayer ) { PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_rankup__not_able_to_reset_rank" ) - .sendTo( sender ); + .sendTo( sender, rPlayer ); } - protected void prestigePlayerBalanceSetToZeroMsg( CommandSender sender ) { + protected void prestigePlayerBalanceSetToZeroMsg( CommandSender sender, + RankPlayer rPlayer ) { PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_rankup__balance_set_to_zero" ) - .sendTo( sender ); + .sendTo( sender, rPlayer ); } - protected void prestigePlayerSucessfulMsg( CommandSender sender, String tag ) { + protected void prestigePlayerSucessfulMsg( CommandSender sender, String tag, + RankPlayer rPlayer ) { PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_rankup__prestige_successful" ) .withReplacements( tag ) - .sendTo( sender ); + .sendTo( sender, rPlayer ); } - protected void prestigePlayerFailureMsg( 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 ); + } + + protected void prestigePlayerFailureMsg( CommandSender sender, String tag, + RankPlayer rPlayer ) { PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_rankup__prestige_failure" ) .withReplacements( tag ) - .sendTo( sender ); + .sendTo( sender, rPlayer ); } protected String prestigeConfirmationGUIMsg( CommandSender sender, @@ -146,34 +162,46 @@ protected String prestigeConfirmationGUIMsg( CommandSender sender, if ( tag == null ) { tag = targetRank.getRank().getName(); } - sb.append( rMsg.getLocalizable( "ranks_rankup__confirm_prestige_line_1" ) - .withReplacements( tag ) - .localize().replace(" ", "_") ).append( " " ); - - sb.append( rMsg.getLocalizable( "ranks_rankup__confirm_prestige_line_2" ) - .withReplacements( - dFmt.format( targetRank.getRankCost()) ) - .localize().replace(" ", "_") ).append( " " ); - - sb.append( rMsg.getLocalizable( "ranks_rankup__confirm_prestige_line_3" ) - .withReplacements( - dFmt.format( balance), - currency == null || currency.trim().length() == 0 ? - "" : " " + currency ) - .localize().replace(" ", "_") ).append( " " ); + sb.append( + rPlayer.convertStringPlaceholders( + rMsg.getLocalizable( "ranks_rankup__confirm_prestige_line_1" ) + .withReplacements( tag ) + .localize().replace(" ", "_") )).append( " " ); + + sb.append( + rPlayer.convertStringPlaceholders( + rMsg.getLocalizable( "ranks_rankup__confirm_prestige_line_2" ) + .withReplacements( + dFmt.format( targetRank.getRankCost()) ) + .localize().replace(" ", "_") )).append( " " ); + + sb.append( + rPlayer.convertStringPlaceholders( + rMsg.getLocalizable( "ranks_rankup__confirm_prestige_line_3" ) + .withReplacements( + dFmt.format( balance), + currency == null || currency.trim().length() == 0 ? + "" : " " + currency ) + .localize().replace(" ", "_") )).append( " " ); if ( isResetDefaultLadder ) { - sb.append( rMsg.getLocalizable( "ranks_rankup__confirm_prestige_line_4" ) - .localize().replace(" ", "_") ).append( " " ); + sb.append( + rPlayer.convertStringPlaceholders( + rMsg.getLocalizable( "ranks_rankup__confirm_prestige_line_4" ) + .localize().replace(" ", "_") )).append( " " ); } if ( isConfirmationEnabled ) { - sb.append( rMsg.getLocalizable( "ranks_rankup__confirm_prestige_line_5" ) - .localize().replace(" ", "_") ).append( " " ); + sb.append( + rPlayer.convertStringPlaceholders( + rMsg.getLocalizable( "ranks_rankup__confirm_prestige_line_5" ) + .localize().replace(" ", "_") )).append( " " ); } - sb.append( rMsg.getLocalizable( "ranks_rankup__confirm_prestige_line_7" ) - .localize().replace(" ", "_") ); + sb.append( + rPlayer.convertStringPlaceholders( + rMsg.getLocalizable( "ranks_rankup__confirm_prestige_line_7" ) + .localize().replace(" ", "_") )); return sb.toString(); } @@ -196,38 +224,38 @@ protected void prestigeConfirmationMsg( CommandSender sender, } rMsg.getLocalizable( "ranks_rankup__confirm_prestige_line_1" ) .withReplacements( tag ) - .sendTo( sender ); + .sendTo( sender, rPlayer ); rMsg.getLocalizable( "ranks_rankup__confirm_prestige_line_2" ) .withReplacements( dFmt.format( targetRank.getRankCost()) ) - .sendTo( sender ); + .sendTo( sender, rPlayer ); rMsg.getLocalizable( "ranks_rankup__confirm_prestige_line_3" ) .withReplacements( dFmt.format( balance), currency == null || currency.trim().length() == 0 ? "" : " " + currency ) - .sendTo( sender ); + .sendTo( sender, rPlayer ); if ( isResetDefaultLadder ) { rMsg.getLocalizable( "ranks_rankup__confirm_prestige_line_4" ) - .sendTo( sender ); + .sendTo( sender, rPlayer ); } if ( isResetMoney ) { rMsg.getLocalizable( "ranks_rankup__confirm_prestige_line_4" ) - .sendTo( sender ); + .sendTo( sender, rPlayer ); } rMsg.getLocalizable( "ranks_rankup__confirm_prestige_line_5" ) - .sendTo( sender ); + .sendTo( sender, rPlayer ); String playerName = !isPlayer ? rPlayer.getName() + " " : ""; rMsg.getLocalizable( "ranks_rankup__confirm_prestige_line_6" ) .withReplacements( playerName ) - .sendTo( sender ); + .sendTo( sender, rPlayer ); // ranks_rankup__confirm_prestige_line_1=&3Confirm Prestige: %s @@ -240,7 +268,8 @@ protected void prestigeConfirmationMsg( CommandSender sender, } protected void ranksRankupPlayerBalanceMsg( CommandSender sender, - double balance, String currency ) { + double balance, String currency, + RankPlayer rPlayer ) { DecimalFormat dFmt = Prison.get().getDecimalFormat("#,##0.00"); LocaleManager rMsg = PrisonRanks.getInstance().getRanksMessages(); @@ -250,7 +279,7 @@ protected void ranksRankupPlayerBalanceMsg( CommandSender sender, dFmt.format( balance), currency == null || currency.trim().length() == 0 ? "" : " " + currency ) - .sendTo( sender ); + .sendTo( sender, rPlayer ); } protected void ranksPromotePlayerMustBeOnlineMsg( CommandSender sender ) { @@ -259,31 +288,34 @@ protected void ranksPromotePlayerMustBeOnlineMsg( CommandSender sender ) { .sendTo( sender ); } - protected void ranksPromotePlayerInvalidChargeValueMsg( CommandSender sender ) { + protected void ranksPromotePlayerInvalidChargeValueMsg( CommandSender sender, + RankPlayer rPlayer ) { PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_rankup__invalid_charge_value" ) .withReplacements( PromoteForceCharge.no_charge.name(), PromoteForceCharge.charge_player.name() ) - .sendTo( sender ); + .sendTo( sender, rPlayer ); } - protected void ranksDemotePlayerInvalidRefundValueMsg( CommandSender sender ) { + protected void ranksDemotePlayerInvalidRefundValueMsg( CommandSender sender, + RankPlayer rPlayer ) { PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_rankup__invalid_refund_value" ) .withReplacements( PromoteForceCharge.no_charge.name(), PromoteForceCharge.refund_player.name() ) - .sendTo( sender ); + .sendTo( sender, rPlayer ); } - protected void ranksConfirmLadderMsg( CommandSender sender, String ladderName ) { + protected void ranksConfirmLadderMsg( CommandSender sender, String ladderName, + RankPlayer rPlayer ) { PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_rankup__rankup_failure_invalid_ladder" ) .withReplacements( ladderName ) - .sendTo( sender ); + .sendTo( sender, rPlayer ); } @@ -297,7 +329,10 @@ protected void ranksRankupFailureToGetRankPlayerMsg( CommandSender sender ) { protected void ranksRankupSuccessMsg( CommandSender sender, String playerName, RankupResults results, - StringBuilder sbRanks ) { + StringBuilder sbRanks + ) { + + RankPlayer rPlayer = results.getRankPlayer(); // PlayerRank tpRank = results.getPlayerRankTarget(); Rank tRank = results.getTargetRank(); @@ -333,7 +368,9 @@ protected void ranksRankupSuccessMsg( CommandSender sender, String playerName, sender.getName(), localManager.localize() ); - Output.get().logInfo( localManagerLog.localize() ); + Output.get().logInfo( + rPlayer.convertStringPlaceholders( + localManagerLog.localize() )); if ( Prison.get().getPlatform().getConfigBooleanFalse( "broadcast-rankups" ) ) { @@ -348,14 +385,15 @@ protected void ranksRankupSuccessMsg( CommandSender sender, String playerName, (tRank == null ? "" : tRank.getTag() ), (results.getMessage() != null ? results.getMessage() : "") ) - .broadcast(); + .broadcast( rPlayer ); } else { - localManager.sendTo( sender ); + localManager.sendTo( sender, rPlayer ); } } - protected void ranksRankupMaxSuccessMsg( CommandSender sender, StringBuilder ranks ) { + protected void ranksRankupMaxSuccessMsg( CommandSender sender, StringBuilder ranks, + RankPlayer rPlayer ) { Localizable localManagerLog = PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_rankup__log_rank_change" ) @@ -370,12 +408,12 @@ protected void ranksRankupMaxSuccessMsg( CommandSender sender, StringBuilder ran if ( Prison.get().getPlatform().getConfigBooleanFalse( "broadcast-rankups" ) ) { - localManagerLog.broadcast(); + localManagerLog.broadcast( rPlayer ); } else { - localManagerLog.sendTo( sender ); + localManagerLog.sendTo( sender, rPlayer ); } } @@ -384,11 +422,12 @@ protected void ranksRankupCannotAffordMsg( CommandSender sender, PlayerRank tpRank = results.getPlayerRankTarget(); - ranksRankupCannotAffordMsg( sender, tpRank ); + ranksRankupCannotAffordMsg( sender, tpRank, results.getRankPlayer() ); } protected void ranksRankupCannotAffordMsg( CommandSender sender, - PlayerRank tpRank ) { + PlayerRank tpRank, + RankPlayer rPlayer ) { DecimalFormat dFmt = Prison.get().getDecimalFormat("#,##0.00"); @@ -402,7 +441,7 @@ protected void ranksRankupCannotAffordMsg( CommandSender sender, tRank == null || tRank.getCurrency() == null ? "" : " " +tRank.getCurrency() ) - .sendTo( sender ); + .sendTo( sender, rPlayer ); } protected void ranksRankupLowestRankMsg( CommandSender sender, String playerName, @@ -416,7 +455,7 @@ protected void ranksRankupLowestRankMsg( CommandSender sender, String playerName .withReplacements( (playerName == null ? messagYouAre : playerName) ) - .sendTo( sender ); + .sendTo( sender, results.getRankPlayer() ); } protected void ranksRankupHighestRankMsg( CommandSender sender, String playerName, @@ -430,107 +469,120 @@ protected void ranksRankupHighestRankMsg( CommandSender sender, String playerNam .withReplacements( (playerName == null ? messagYouAre : playerName) ) - .sendTo( sender ); + .sendTo( sender, results.getRankPlayer() ); } - protected void ranksRankupFailureMsg( CommandSender sender ) { + protected void ranksRankupFailureMsg( CommandSender sender, + RankPlayer rPlayer ) { PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_rankup__rankup_failure" ) - .sendTo( sender ); + .sendTo( sender, rPlayer ); } - protected void ranksRankupFailureCouldNotLoadPlayerMsg( CommandSender sender ) { + protected void ranksRankupFailureCouldNotLoadPlayerMsg( CommandSender sender, + RankPlayer rPlayer ) { PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_rankup__rankup_failed_to_load_player" ) - .sendTo( sender ); + .sendTo( sender, rPlayer ); } - protected void ranksRankupFailureCouldNotLoadLadderMsg( CommandSender sender ) { + protected void ranksRankupFailureCouldNotLoadLadderMsg( CommandSender sender, + RankPlayer rPlayer ) { PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_rankup__rankup_failed_to_load_ladder" ) - .sendTo( sender ); + .sendTo( sender, rPlayer ); } - protected void ranksRankupFailureUnableToAssignRankMsg( CommandSender sender ) { + protected void ranksRankupFailureUnableToAssignRankMsg( CommandSender sender, + RankPlayer rPlayer ) { PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_rankup__rankup_failed_to_assign_rank" ) - .sendTo( sender ); + .sendTo( sender, rPlayer ); } - protected void ranksRankupFailureUnableToAssignRankWithRefundMsg( CommandSender sender ) { + protected void ranksRankupFailureUnableToAssignRankWithRefundMsg( CommandSender sender, + RankPlayer rPlayer ) { PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_rankup__rankup_failed_to_assign_rank_with_refund" ) - .sendTo( sender ); + .sendTo( sender, rPlayer ); } - protected void ranksRankupFailureCouldNotSavePlayerFileMsg( CommandSender sender ) { + protected void ranksRankupFailureCouldNotSavePlayerFileMsg( CommandSender sender, + RankPlayer rPlayer ) { PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_rankup__rankup_failed_to_save_player_file" ) - .sendTo( sender ); + .sendTo( sender, rPlayer ); } - protected void ranksRankupFailureNoRanksMsg( CommandSender sender ) { + protected void ranksRankupFailureNoRanksMsg( CommandSender sender, + RankPlayer rPlayer ) { PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_rankup__rankup_no_ranks" ) - .sendTo( sender ); + .sendTo( sender, rPlayer ); } - protected void ranksRankupFailureRankDoesNotExistMsg( CommandSender sender, String rank ) { + protected void ranksRankupFailureRankDoesNotExistMsg( CommandSender sender, String rank, + RankPlayer rPlayer ) { PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_rankup__rankup_rank_does_not_exist" ) .withReplacements( rank ) - .sendTo( sender ); + .sendTo( sender, rPlayer ); } protected void ranksRankupFailureRankIsNotInLadderMsg( CommandSender sender, - String rank, String ladder ) { + String rank, String ladder, + RankPlayer rPlayer ) { PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_rankup__rankup_rank_is_not_in_ladder" ) .withReplacements( rank, ladder ) - .sendTo( sender ); + .sendTo( sender, rPlayer ); } protected void ranksRankupFailureCurrencyIsNotSupportedMsg( CommandSender sender, - String currency ) { + String currency, + RankPlayer rPlayer ) { PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_rankup__rankup_currency_is_not_supported" ) .withReplacements( currency ) - .sendTo( sender ); + .sendTo( sender, rPlayer ); } protected void ranksRankupFailureLadderRemovedMsg( CommandSender sender, - String ladder ) { + String ladder, + RankPlayer rPlayer ) { PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_rankup__rankup_ladder_removed" ) .withReplacements( ladder ) - .sendTo( sender ); + .sendTo( sender, rPlayer ); } protected void ranksRankupFailureRemovingLadderMsg( CommandSender sender, - String ladder ) { + String ladder, + RankPlayer rPlayer ) { PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_rankup__rankup_failure_removing_ladder" ) .withReplacements( ladder ) - .sendTo( sender ); + .sendTo( sender, rPlayer ); } - protected void ranksRankupFailureInProgressMsg( CommandSender sender ) { + protected void ranksRankupFailureInProgressMsg( CommandSender sender, + RankPlayer rPlayer ) { PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_rankup__rankup_in_progress_failure" ) - .sendTo( sender ); + .sendTo( sender, rPlayer ); } 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 61d6affb3..7503bccc8 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 @@ -1228,9 +1228,9 @@ private ChatDisplay listRanksOnLadder( RankLadder ladder, boolean hasPerm, RankP return display; } - private String padRankName( Rank rank, int maxRankNameSize, int maxRankTagNoColorSize, boolean hasPerm ) { - return padRankName( rank.getName(), rank.getTag(), maxRankNameSize, maxRankTagNoColorSize, hasPerm ); - } +// 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(); From 5dc094f8033758a550d5a8053a301016542eda9c Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 7 Apr 2024 23:52:13 -0400 Subject: [PATCH 88/92] 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. --- docs/changelog_v3.3.x.md | 3 + .../prison/ranks/managers/PlayerManager.java | 92 +++++++++++++++++++ 2 files changed, 95 insertions(+) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index c0b76589d..854d0aa1d 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.16c 2024-04-07 +* **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. 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 4fdf2a7d9..30f5dc82c 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 @@ -1961,6 +1961,11 @@ public String getTranslatePlayerPlaceHolder( PlaceholderIdentifier identifier ) break; } + +// results = applySecondaryPlaceholders( rankPlayer, results ); + + + if ( attributeText != null && results != null ) { results = attributeText.format( results ); @@ -1974,6 +1979,93 @@ public String getTranslatePlayerPlaceHolder( PlaceholderIdentifier identifier ) } + /** + *

This function will provide support for secondary placeholders for all player related placeholders. + * These secondary placeholders are in addition to the preexisting positional placeholders + * that are hard coded for the specific parameters. + *

+ * + *

These secondary placeholders can be inserted anywhere in the message. + *

+ * + *
    + *
  • {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} {rank_default} {rank_tag_default} {rank_next_default} {rank_next_tag_default}
  • + *
  • {rank_prestiges} {rank_tag_prestiges} {rank_next_prestiges} {rank_next_tag_prestiges}
  • + *
+ * + * @param rankPlayer + * @param results + * @return + */ + private String applySecondaryPlaceholders(RankPlayer rankPlayer, String results) { + + results = applySecondaryPlaceholdersCheck( "{player}", rankPlayer.getName(), results ); + + if ( rankPlayer.getPlayerRankDefault() != null ) { + PlayerRank rankP = rankPlayer.getPlayerRankDefault(); + Rank rank = rankP == null ? null : rankP.getRank(); + Rank rankNext = rank == null ? null : rank.getRankNext(); + + results = applySecondaryPlaceholdersCheck( "{rank_default}", + rank == null ? "" : rank.getName(), results ); + results = applySecondaryPlaceholdersCheck( "{rank_tag_default}", + rank == null ? "" : rank.getTag(), results ); + + results = applySecondaryPlaceholdersCheck( "{rank_next_default}", + rankNext == null ? "" : rankNext.getName(), results ); + results = applySecondaryPlaceholdersCheck( "{rank_next_tag_default}", + rankNext == null ? "" : rankNext.getTag(), results ); + } + + if ( rankPlayer.getPlayerRankPrestiges() != null ) { + + PlayerRank rankP = rankPlayer.getPlayerRankPrestiges(); + Rank rank = rankP == null ? null : rankP.getRank(); + Rank rankNext = rank == null ? null : rank.getRankNext(); + + results = applySecondaryPlaceholdersCheck( "{rank_prestiges}", + rank == null ? "" : rank.getName(), results ); + results = applySecondaryPlaceholdersCheck( "{rank_tag_prestiges}", + rank == null ? "" : rank.getTag(), results ); + + results = applySecondaryPlaceholdersCheck( "{rank_next_prestiges}", + rankNext == null ? "" : rankNext.getName(), results ); + results = applySecondaryPlaceholdersCheck( "{rank_next_tag_prestiges}", + rankNext == null ? "" : rankNext.getTag(), results ); + } + + return results; + } + + /** + *

Ths function will perform individual replacements of the given placeholders, but + * if the placeholder does not exist, then it will not change anything with the results + * and it will be just passed through. + *

+ * + * @param placeholder + * @param value + * @param results + * @return + */ + private String applySecondaryPlaceholdersCheck( String placeholder, String value, String results) { + + if ( results.contains( placeholder ) && value != null ) { + results = results.replace( placeholder, value ); + } + + return results; + } @Override public List getTranslatedPlaceHolderKeys() { From 917ef27980d475c05dad65ce5517f9991a4276ac Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 20 Apr 2024 23:23:39 -0400 Subject: [PATCH 89/92] 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. --- docs/changelog_v3.3.x.md | 5 ++++- .../tech/mcprison/prison/ranks/managers/PlayerManager.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 854d0aa1d..25fba48b3 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.16c 2024-04-07 +# 3.3.0-alpha.16c 2024-04-20 + + +* **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. 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 30f5dc82c..01fc9253e 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 @@ -729,7 +729,7 @@ public String getPlayerNextRankCostPercent( RankPlayer rankPlayer, String ladder if ( attributeNFormat != null ) { - sb.append( attributeNFormat.format( cost ) ); + sb.append( attributeNFormat.format( percent ) ); } else { From 593333627815e53f11aa705dde8aa911ea8f31a4 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 20 Apr 2024 23:32:44 -0400 Subject: [PATCH 90/92] Mines messages: Secondary placeholders. Added support for mines' messages to be able to support secondary placeholders within the language files. 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. --- docs/changelog_v3.3.x.md | 8 + .../tech/mcprison/prison/mines/data/Mine.java | 158 +++++++++++++++++- 2 files changed, 165 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 25fba48b3..c741048c2 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.16c 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. 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 19d422f1f..a98462376 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 @@ -34,6 +34,7 @@ import tech.mcprison.prison.mines.features.MineLinerData; import tech.mcprison.prison.mines.managers.MineManager; import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.placeholders.PlaceholderStringCoverter; import tech.mcprison.prison.selection.Selection; import tech.mcprison.prison.sorting.PrisonSortable; import tech.mcprison.prison.store.Document; @@ -47,7 +48,7 @@ @SuppressWarnings( "deprecation" ) public class Mine extends MineScheduler - implements PrisonSortable, Comparable { + implements PrisonSortable, Comparable, PlaceholderStringCoverter { public enum MineType { @@ -867,5 +868,160 @@ public String getBlockListString() public int compareTo( Mine o ) { return getName().toLowerCase().compareTo( o.getName().toLowerCase() ); } + + + + @Override + public String getStringPlaceholders() { + return "{mine} {mine_tag} {mine_world} {mine_type} {mine_group} " + + "{mine_rank} {mine_air_count} {mine_player_count} " + + "{mine_block_break_count} {mine_block_remaining_count} {mine_block_remaining_percent} " + + "{mine_blocks_mined_total} {mine_reset_time_sec} {mine_reset_time_remaining_sec} " + + "{mine_block_[block]_name} {mine_block_[block]_type} {mine_block_[block]_placed} " + + "{mine_block_[block]_remaining} {mine_block_[block]_total} {mine_block_[block]_chance}"; + } + + + /** + *

This function will provide support for secondary placeholders for all mine related placeholders. + * These secondary placeholders are in addition to the preexisting positional placeholders + * that are hard coded for the specific parameters. + *

+ * + *

These secondary placeholders can be inserted anywhere in the message. + *

+ * + *
    + *
  • {mine}
  • + *
  • {mine_tag}
  • + *
  • {mine_world}
  • + *
  • {mine_type}
  • + *
  • {mine_group}
  • + * + *
  • {mine_rank}
  • + *
  • {mine_air_count}
  • + *
  • {mine_player_count}
  • + * + *
  • {mine_block_break_count}
  • + *
  • {mine_block_remaining_count}
  • + *
  • {mine_block_remaining_percent}
  • + *
  • {mine_blocks_mined_total}
  • + *
  • {mine_reset_time_sec}
  • + *
  • {mine_reset_time_remaining_sec}
  • + * + *
  • {mine_block__name}
  • + *
  • {mine_block__type}
  • + *
  • {mine_block__placed}
  • + *
  • {mine_block__remaining}
  • + *
  • {mine_block__total}
  • + *
  • {mine_block__chance}
  • + + * + *
  • {mine} {mine_tag} {mine_world} {mine_type} {mine_group} + * {mine_rank} {mine_air_count} {mine_player_count} + * {mine_block_break_count} {mine_block_remaining_count} {mine_block_remaining_percent} + * {mine_blocks_mined_total} {mine_reset_time_sec} {mine_reset_time_remaining_sec} + * {mine_block_[block]_name} {mine_block_[block]_type} {mine_block_[block]_placed} + * {mine_block_[block]_remaining} {mine_block_[block]_total} {mine_block_[block]_chance} + *
  • + * + *
+ * + * @param rankPlayer + * @param results + * @return + */ + @Override + public String convertStringPlaceholders(String results) { + + Mine mine = this; + + if ( mine != null ) { + + results = applySecondaryPlaceholdersCheck( "{mine}", mine.getName(), results ); + results = applySecondaryPlaceholdersCheck( "{mine_tag}", mine.getTag(), results ); + results = applySecondaryPlaceholdersCheck( "{mine_world}", mine.getWorldName(), results ); + results = applySecondaryPlaceholdersCheck( "{mine_type}", mine.getMineType().name(), results ); + results = applySecondaryPlaceholdersCheck( "{mine_group}", mine.getMineGroup().getName(), results ); + + results = applySecondaryPlaceholdersCheck( "{mine_rank}", mine.getRankString(), results ); + + results = applySecondaryPlaceholdersCheck( "{mine_air_count}", + Integer.toString( mine.getAirCount()), results ); + results = applySecondaryPlaceholdersCheck( "{mine_player_count}", + Integer.toString( mine.getPlayerCount()), results ); + + results = applySecondaryPlaceholdersCheck( "{mine_block_break_count}", + Integer.toString( mine.getBlockBreakCount()), results ); + results = applySecondaryPlaceholdersCheck( "{mine_block_remaining_count}", + Integer.toString( mine.getRemainingBlockCount()), results ); + results = applySecondaryPlaceholdersCheck( "{mine_block_remaining_percent}", + Double.toString( (mine.getPercentRemainingBlockCount() * 100.0d )), results ); + results = applySecondaryPlaceholdersCheck( "{mine_blocks_mined_total}", + Long.toString( mine.getTotalBlocksMined()), results ); + + results = applySecondaryPlaceholdersCheck( "{mine_reset_time_sec}", + Integer.toString( mine.getResetTime()), results ); + results = applySecondaryPlaceholdersCheck( "{mine_reset_time_remaining_sec}", + Double.toString( mine.getRemainingTimeSec()), results ); + + + Set keys = mine.getBlockStats().keySet(); + for (String key : keys) { + PrisonBlockStatusData blockStat = mine.getBlockStats().get( key ); + + String bName = blockStat.getBlockName().toLowerCase(); + String type = blockStat.getBlockType().name(); + + long placed = blockStat.getBlockPlacedCount(); + long remaining = blockStat.getBlockPlacedCount() - blockStat.getBlockCountUnsaved(); + long total = blockStat.getBlockCountTotal(); + + Double chance = blockStat.getChance() * 100.0d; + + results = applySecondaryPlaceholdersCheck( "{mine_block_" + bName + "_name}", + bName, results ); + results = applySecondaryPlaceholdersCheck( "{mine_block_" + bName + "_type}", + type, results ); + + results = applySecondaryPlaceholdersCheck( "{mine_block_" + bName + "_placed}", + Long.toString( placed ), results ); + results = applySecondaryPlaceholdersCheck( "{mine_block_" + bName + "_remaining}", + Long.toString( remaining ), results ); + results = applySecondaryPlaceholdersCheck( "{mine_block_" + bName + "_total}", + Long.toString( total ), results ); + results = applySecondaryPlaceholdersCheck( "{mine_block_" + bName + "_chance}", + Double.toString( chance ), results ); + + } + + + + } + + return results; + } + + + /** + *

Ths function will perform individual replacements of the given placeholders, but + * if the placeholder does not exist, then it will not change anything with the results + * and it will be just passed through. + *

+ * + * @param placeholder + * @param value + * @param results + * @return + */ + private String applySecondaryPlaceholdersCheck( String placeholder, String value, String results) { + + if ( results.contains( placeholder ) && value != null ) { + results = results.replace( placeholder, value ); + } + + return results; + } + } From 27cfffa8607552c0222514e53f4072a64c61e46d Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 21 Apr 2024 00:01:32 -0400 Subject: [PATCH 91/92] v3.3.0-alpha.17 - Set the version to alpha.17 so it can be posted to the various public servers. --- docs/changelog_v3.3.x.md | 7 ++++++- docs/prison_docs_101_setting_up_mines.md | 8 +++++++- docs/prison_docs_111_mine_commands.md | 9 +++++++++ gradle.properties | 2 +- prison-core/build.gradle | 2 ++ 5 files changed, 25 insertions(+), 3 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index c741048c2..85862084b 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.16c 2024-04-20 +# 3.3.0-alpha.17 2024-04-20 + + + +**v3.3.0-alpha.17** 2024-03-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.** diff --git a/docs/prison_docs_101_setting_up_mines.md b/docs/prison_docs_101_setting_up_mines.md index 0aed9edb2..50c61b391 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: 2023-11-26* +*Documented updated: 2024-03-11*
@@ -22,6 +22,12 @@ Prison has a list of suggested plugins that works well with Prison, and a few th [Setting up Prison - The Basics](prison_docs_012_setting_up_prison_basics.md) +**New Command:** + +`/mines block layerStats help` +This new command will provide a layer by layer inspection of what blocks were assigned to a mine, versus what is actually in the mine currently. This is useful when confirming block constraints are working correctly, or if another block was not spawning as expected, such that there is too much AIR. + + Items to add to this document: * Use of ***/mines backup help** this command will make an individual backup of a mine's config settings on the server's file system. This backup can manually be used to rollback any changes to a mine. Prison has a command **/prison support backup help** that will make a backup of all files within the server directory **plugins/Prison/**, of which it will include all mine backup files, then remove them from file system. Contact support on our discord server for help. diff --git a/docs/prison_docs_111_mine_commands.md b/docs/prison_docs_111_mine_commands.md index 346b73749..a3748cd00 100644 --- a/docs/prison_docs_111_mine_commands.md +++ b/docs/prison_docs_111_mine_commands.md @@ -6,6 +6,7 @@ This document provides information how to setup and use Mine Commands. +*Documented updated: 2024-03-11*
@@ -21,6 +22,14 @@ My personal goals to use this new feature was to dynamically build a large fores - Blue + +**New Command:** + +`/mines block layerStats help` +This new command will provide a layer by layer inspection of what blocks were assigned to a mine, versus what is actually in the mine currently. This is useful when confirming block constraints are working correctly, or if another block was not spawning as expected, such that there is too much AIR. + + +
diff --git a/gradle.properties b/gradle.properties index 3173b2ca5..481a40c90 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.16c +version=3.3.0-alpha.17 diff --git a/prison-core/build.gradle b/prison-core/build.gradle index 8c84bad53..6dd5be946 100644 --- a/prison-core/build.gradle +++ b/prison-core/build.gradle @@ -32,6 +32,8 @@ repositories { dependencies { implementation 'org.apache.commons:commons-lang3:3.12.0' + + // https://github.com/InstantlyMoist/privatebin-java-api //implementation 'com.github.InstantlyMoist:privatebin-java-api:1.0.2' //implementation 'org.json:json:20230227' From e4997733e4c9c175cb5fd7abac562e5cd00432c6 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 21 Apr 2024 16:35:08 -0400 Subject: [PATCH 92/92] Update the changelogs for v3.3.0-alpha.17 support. --- docs/changelog_v3.3.x.md | 14 +- docs/knownissues_v3.3.x.md | 8 + docs/prison_changelogs.md | 1 + docs/prison_chnagelog_v3.3.0-alpha.17.md | 655 +++++++++++++++++++++++ 4 files changed, 675 insertions(+), 3 deletions(-) create mode 100644 docs/prison_chnagelog_v3.3.0-alpha.17.md diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 85862084b..4ef8cd627 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -4,7 +4,7 @@ ## Change logs - **[v3.3.0-alpha - Current](changelog_v3.3.x.md)** - - [v3.2.0 through v3.3.0-alpha.16](prison_changelogs.md) + - [v3.2.0 through v3.3.0-alpha.17](prison_changelogs.md) * [Known Issues - Open](knownissues_v3.2.x.md) * [Known Issues - Resolved](knownissues_v3.2.x_resolved.md) @@ -18,7 +18,15 @@ These change logs represent the work that has been going on within prison. -**v3.3.0-alpha.17** 2024-03-20 + + + + + + +# 3.3.0-alpha.17 2024-04-20 + +**v3.3.0-alpha.17** 2024-04-20 @@ -275,7 +283,7 @@ As a side effect, these two unit test run much faster since it's not trying to s * **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 hoo up displayName to other features, such as sellall and add prison block to mines. +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.** diff --git a/docs/knownissues_v3.3.x.md b/docs/knownissues_v3.3.x.md index 1d6b7bff6..f3fc65e06 100644 --- a/docs/knownissues_v3.3.x.md +++ b/docs/knownissues_v3.3.x.md @@ -13,6 +13,14 @@ Resolved issues have been relocated to: * [Known Issues - Resolved](knownissues_v3.2.x_resolved.md) +# TODO Items for v3.3.0-alpha.16 + + +DONE: Added support for BlockPlaceEvent to allow this - editid - Mine bombs cannot be placed in a mine that is protected by world guard, which is + reporting that the player does not have access. Had to allow players to place blocks in + mines, which is not appropriate. + + # TODO Items for v3.3.0-alpha.15 diff --git a/docs/prison_changelogs.md b/docs/prison_changelogs.md index f0badc17a..5b67fdb73 100644 --- a/docs/prison_changelogs.md +++ b/docs/prison_changelogs.md @@ -22,6 +22,7 @@ These build logs represent the work that has been going on within prison. - Future updates will be under the v3.3.x release + - [v3.3.3-alpha.17 - 2024-04-20](prison_changelog_v3.3.0-alpha.17.md)   - [v3.3.3-alpha.16 - 2023-11-18](prison_changelog_v3.3.0-alpha.16.md)   - [v3.3.3-alpha.15 - 2023-07-07](prison_changelog_v3.3.0-alpha.15.md)   - [v3.3.3-alpha.14 - 2023-01-23](prison_changelog_v3.3.0-alpha.14.md)   diff --git a/docs/prison_chnagelog_v3.3.0-alpha.17.md b/docs/prison_chnagelog_v3.3.0-alpha.17.md new file mode 100644 index 000000000..08b51b908 --- /dev/null +++ b/docs/prison_chnagelog_v3.3.0-alpha.17.md @@ -0,0 +1,655 @@ +[Prison Documents - Table of Contents](prison_docs_000_toc.md) + +## Prison Build Logs for v3.3.x + +## Build logs + - **[v3.3.0-alpha - Current](changelog_v3.3.x.md)** + - [v3.2.0 through v3.3.0-alpha.17](prison_changelogs.md) + + +These build logs represent the work that has been going on within prison. + + +# 3.3.0-alpha.17 2024-04-21 + + + +The following is a highlight of changes for the alpha.17 release since the alpha.16 release. + + +* Mines: Added more support for the use of '*all*' for mine names so more of the mine commands will be able to apply to all mines. + + +* **Upgrade XSeries to v9.7.0 from v9.4.0.** +* **Upgrade XSeries from v9.7.0 to v9.8.0.** +* **XSeries: Upgrade from v9.8.0 to v9.9.0** + +* **Upgrade nbt-api from v2.12.0 to v2.12.2.** + +* **PlaceholderAPI: Upgrade from v2.11.2 to v2.11.5** + + + +* **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 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. + + + +* **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}` + + + +* **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. + + + +* **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. + + + +* **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. + + + + +* **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. + + + +* **updated the help on the `/mines block constraint` to indicate that the layer count is originating from the top, not the bottom.** + + +* **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. + + +* **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: 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. + + + +* **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.** + + + + +* **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. + + + +* **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. + + + + +**3.3.0-alpha.16b 2024-02-24** + + + +* **Mine imports: Fix some minor issues to get this to work even better.** + +* **Mines import: prevent the processing of an importing of a mine if there are problems with the mine's name, or locations.** + + + +* **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. + + + +* **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. + + + +* **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. + + + +* **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. + + +* **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. + + + +* **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". + + + +* **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. + + + +* **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. + + +* **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.** + + + +* **PlaceholderAPI: Upgrade from v2.11.2 to v2.11.5** + + +* **XSeries: Upgrade from v9.8.0 to v9.9.0** + + + +**3.3.0-alpha.16c 2024-03-11** + + + +* **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. + + + + +* **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 API: Added a few new functions to work with ItemStacks.** + + + + +* **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. + + +* **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). + + + +* **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. + + + +* **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. + + + + + + +* * * * * * * * * * * + + + +* **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 hoo 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 + + + +